terraform-provider-okta icon indicating copy to clipboard operation
terraform-provider-okta copied to clipboard

okta_email_verification does not produce deterministic dns records, makes creating them in the same terraform module a challenge

Open kensykora opened this issue 3 years ago • 3 comments

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Problem

In the scenario where:

  • Terraform creates the okta_email_sender
  • okta_email_sender produces an array of objects, representing DNS records that need to be created via verification_records
  • We are starting an terraform apply from a blank slate

It is not deterministically possible to create the DNS records, because it is not known via any properties or attributes of okta_email_sender how many records need to be created. Terraform does not support creating an unknown amount of resources via a for_each

Terraform Version

Terraform v1.1.5
on linux_amd64
+ provider registry.terraform.io/cloudflare/cloudflare v3.9.1
+ provider registry.terraform.io/hashicorp/time v0.7.2
+ provider registry.terraform.io/okta/okta v3.21.0

Affected Resource(s)

  • okta_email_sender_verification

Terraform Configuration Files

resource "okta_email_sender" "sender" {
  from_name    = var.support_email_from_name
  from_address = var.support_email_address
  subdomain    = var.support_email_domain_name
}

resource "cloudflare_record" "verification_records" {
  for_each = { for k in okta_email_sender.sender.dns_records : k.fqdn => k }

  zone_id = data.cloudflare_zone.homevalet_domain.id

  name  = each.value.fqdn
  value = each.value.value

  # Make sure it's upper case, cloudflare provider requires this
  type = upper(each.value.record_type)
}

resource "time_sleep" "dns_propogation" {
  depends_on = [
    cloudflare_record.verification_records
  ]

  create_duration = "5m"
}

resource "okta_email_sender_verification" "example" {
  depends_on = [
    cloudflare_record.verification_records,
    time_sleep.dns_propogation
  ]

  sender_id = okta_email_sender.sender.id
}

Suggested Improvement

Since it is "Well Known" that 4 records need to be created, (the Okta admin portal definitively says "4" when you try to verify it) expose each of the records that need to be created via their own property, rather than an unknown array length that is only known after the resource has been applied

Actual Behavior

Creation fails because the number of records is not known

Error: Invalid for_each argument

  on ../../infra/main.tf line 49, in resource "cloudflare_record" "verification_records":
  49:   for_each = { for k in okta_email_sender.sender.dns_records : k.fqdn => k }
    ├────────────────
    │ okta_email_sender.sender.dns_records is a list of object, known only after apply

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.

Steps to Reproduce

  1. Run terraform apply with the code sample above

Workaround

  1. Option: First terraform apply with JUST the okta_email_sender so the records go into the state file, THEN a second terraform apply with the DNS records and the verification call
  2. Option: Since we know there will always be 4, just use a count = 4 and access them directly by their index
resource "cloudflare_record" "verification_records" {
  count = 4

  zone_id = data.cloudflare_zone.mydomain_domain.id

  name  = okta_email_sender.sender.dns_records[count.index].fqdn
  value = okta_email_sender.sender.dns_records[count.index].value

  # Make sure it's upper case, cloudflare provider requires this
  type = upper(okta_email_sender.sender.dns_records[count.index].record_type)
}

kensykora avatar Feb 15 '22 17:02 kensykora

I'll be looking into this @kensykora

monde avatar Feb 25 '22 00:02 monde

following up @kensykora, after doing some additional research to get myself more familiar with this topic.

Are you suggesting that on the okta_email_sender resource we should have four attributes, say, dns_record_0, dns_record_1, dns_record_2, and dns_record_3 that are populated with the elements from the dns_records slice?

Adding my notes for background: Original feature: https://github.com/okta/terraform-provider-okta/pull/697 And Issue: https://github.com/okta/terraform-provider-okta/issues/469 Guide: https://developer.okta.com/docs/guides/custom-url-domain/main/#configure-a-custom-email-notification-domain

monde avatar Mar 02 '22 22:03 monde

@monde that might work, or maybe giving them more descriptive names (verification root, verification subdomain, etc.) -- You'd probably need to talk to the API design team to understand the design intent, if they could change in number in the future or not you might want to leave it arbitrary, or if they truly are well known and you can put names to them.

Honestly this is kind of a design issue with Terraform core, and we worked around it so I mostly left this here to raise awareness.

kensykora avatar Mar 02 '22 22:03 kensykora

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Oct 26 '22 00:10 github-actions[bot]