For_each aws_acm_certificate and aws_route53_record

Hello
I’m trying to write for multiple domain using for each. Please, help me with aws_route53_record

resource "aws_acm_certificate" "cert" {
  # for_each    = toset(var.domain_name)
  for_each                  = var.domain_name
  domain_name               = each.key
  subject_alternative_names = each.value.domain_alternative_names
  validation_method         = var.validation_method

  tags = {
    Environment = "test"
  }

  lifecycle {
    create_before_destroy = true
  }

  options {
    certificate_transparency_logging_preference = "ENABLED"
  }
}

data "aws_route53_zone" "domain_zone" {
  # for_each     = var.domain_name
  # name         = each.key
  name         = "jazzfest.link"
  private_zone = false
}

There I have got error message

resource "aws_route53_record" "example" {
  for_each = aws_acm_certificate.cert
   allow_overwrite = true
  name            = each.value.domain_validation_options.resource_record_name
  records         = [each.value.resource_record_value]
  ttl             = 60
  type            = each.value.resource_record_type
  zone_id         = data.aws_route53_zone.domain_zone.zone_id
}
aws_acm_certificate.cert["jazzfest.link"]: Refreshing state... [id=arn:aws:acm:us-east-1:714154805721:certificate/8027f8c4-bd61-4ea3-81a1-d5e65fdbd91c]
╷
│ Error: Unsupported attribute
│ 
│   on 03-main.tf line 83, in resource "aws_route53_record" "example":
│   83:   name            = each.value.resource_record_name
│     ├────────────────
│     │ each.value is object with 15 attributes
│ 
│ This object does not have an attribute named "resource_record_name".

Variables

variable "domain_name" {
  description = "A list of domains that should be SANs in the issued certificate"
  type        = map(any)
  default = {
    "jazzfest.link" = {
      domain_alternative_names = ["neo.jazzfest.link", "trinity.jazzfest.link", "morpheus.jazzfest.link"]
    }
  }
}

Resource output is:

resource "aws_acm_certificate" "cert"
 {
      arn                       = (known after apply)
      domain_name               = "jazzfest.link"
      domain_validation_options = [
          {
              domain_name           = "jazzfest.link"
              resource_record_name  = (known after apply)
              resource_record_type  = (known after apply)
              resource_record_value = (known after apply)
            },
          {
              domain_name           = "morpheus.jazzfest.link"
              resource_record_name  = (known after apply)
              resource_record_type  = (known after apply)
              resource_record_value = (known after apply)
            },
          {
              domain_name           = "neo.jazzfest.link"
              resource_record_name  = (known after apply)
              resource_record_type  = (known after apply)
              resource_record_value = (known after apply)
            },
          {
              domain_name           = "trinity.jazzfest.link"
              resource_record_name  = (known after apply)
              resource_record_type  = (known after apply)
              resource_record_value = (known after apply)
            },
        ]
      id                        = (known after apply)
      status                    = (known after apply)
      subject_alternative_names = [
          "morpheus.jazzfest.link",
          "neo.jazzfest.link",
          "trinity.jazzfest.link",
        ]
      tags                      = {
          "Environment" = "test"
        }
      tags_all                  = {
          "Environment" = "test"
        }
      validation_emails         = (known after apply)
      validation_method         = "DNS"

      options {
          certificate_transparency_logging_preference = "ENABLED"
        }
    }

Thank you in advance for your help

Hi! I’m currently facing the same issue than you. You were able to solve it?

Even though atributes such as resource_record_name and resource_record_type appear in the reference for the resource type, they doesn’t seems to work.

Thanks in advance

Hi,

‘aws_acm_certificate.cert’ returns a map. So you might need to use ‘values’ to fetch all ‘values’ and then use ‘*’ splat operator to fetch the required ‘resource_record_name’.

I was able to fetch ‘resource_record_name’ as below in an output variable.

output "aws_acm_certificate_test" {
  value = values(aws_acm_certificate.cert)[*].domain_validation_options[*].resource_record_name
}

Maybe try out this below code. But again below code returns a list of ‘resource_record_name’. So maybe you need another for_each loop to create one ‘route 53 record’ per ‘resource_record_name’.

values(each.value)[*].domain_validation_options[*].resource_record_name

Thanks.

Can you try this ?

resource "aws_route53_record" "example" {
  for_each = aws_acm_certificate.cert
  allow_overwrite = true
  name            = tolist(each.value.domain_validation_options)[0].resource_record_name
  records         = [tolist(each.value.domain_validation_options)[0].resource_record_value]
  ttl             = 60
  type            = tolist(each.value.domain_validation_options)[0].resource_record_type
  zone_id         = data.aws_route53_zone.domain.zone_id
}
1 Like

Thank you for this. Helped me out.