hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.82k stars 9.16k forks source link

[Bug]: The "for_each" map includes keys derived from resource attributes that cannot be determined until apply #27299

Open lee5i3 opened 2 years ago

lee5i3 commented 2 years ago

Terraform Core Version

1.3.2

AWS Provider Version

4.35.0

Affected Resource(s)

resource "aws_acm_certificate" "main" {
  domain_name       = var.acm_certificate_subdomain_name != null ? "${var.acm_certificate_subdomain_name}.${var.route53_hosted_zone}" : var.route53_hosted_zone
  validation_method = "DNS"

  subject_alternative_names = var.acm_certificate_subject_alternative_names

  tags = merge(local.tags, {})

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_acm_certificate_validation" "main" {
  certificate_arn         = aws_acm_certificate.main.arn
  validation_record_fqdns = [for record in aws_route53_record.main : record.fqdn]

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_route53_record" "main" {
  for_each = {
    for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }

  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id         = data.aws_route53_zone.main.zone_id

  lifecycle {
    create_before_destroy = true
  }
}

Expected Behavior

This should import records successfully

Actual Behavior

Error: Invalid for_each argument │ │ on .terraform/modules/certificate/route53.tf line 2, in resource "aws_route53_record" "main": │ 2: for_each = { │ 3: for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => { │ 4: name = dvo.resource_record_name │ 5: record = dvo.resource_record_value │ 6: type = dvo.resource_record_type │ 7: } │ 8: } │ ├──────────────── │ │ aws_acm_certificate.main.domain_validation_options is a set of object, known only after apply │ │ The "for_each" map includes keys derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will │ identify the instances of this resource. │ │ When working with unknown values in for_each, it's better to define the map keys statically in your configuration and place apply-time results only in the map values. │ │ Alternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge. ╵

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

var.route53_hosted_zone = "mydomain.com" var.acm_certificate_subdomain_name = "*" var.acm_certificate_subject_alternative_names = "mydomain.com"

Steps to Reproduce

terraform import

I am actually importing a cloudfront site which this is used with but even importing either the certificate or the route53 record also causes this

Debug Output

No response

Panic Output

No response

Important Factoids

We were following this documentation https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation

References

I understand this has been reported before with the following

https://github.com/hashicorp/terraform-provider-aws/issues/23260 https://github.com/hashicorp/terraform-provider-aws/issues/17956

Which is a similar issue but this works with v1.2.9 but breaks with v1.3.0 and higher

Would you like to implement a fix?

No response

github-actions[bot] commented 2 years ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

lee5i3 commented 2 years ago

To add to this.. plan has no issues, its only during import

I can import via v1.2.9 and failed to import when switched to v1.3.2

maaarghk commented 1 year ago

https://github.com/hashicorp/terraform/issues/32146

zzorica commented 1 year ago

Same as Terraform example for setting aws_route53_record logic using for_each fails during import. plan is good.

naomichi-y commented 8 months ago

I ran into the same problem with http. terraform-provider-aws/terraform-aws-route53.

module "records" {
  source  = "terraform-aws-modules/route53/aws//modules/records"

  records = [
    {
      name = "***._domainkey%s", element(aws_ses_domain_dkim.this.dkim_tokens, 0)
      ...
    }
  ]
  ...
}

By default, it tries to use the name parameter as the key name, and an error occurs because the value has not been determined. As a solution, I was able to resolve the problem by defining a parameter called key. https://github.com/terraform-aws-modules/terraform-aws-route53/blob/master/modules/records/main.tf#L7