in Terraform how do you pull out specific CNAME records from an aws_acm_certificate resource with multiple subdomains

Viewed 260

This is with using an AWS provider for Terraform.

In Terraform I created an SSL certificate with that includes six subdomains. I need to pull out the CNAMEs from that resource so I can add them to the corresponding hosted zone in route 53.

I created an output so I can see that the aws_acm_certificate did do what it was supposed to but I am not sure on how to pull each CNAME record out for each corresponding domain out to use in my CNAME records creation. This -

output "show_ssl_info_for_cnames" {
  value = aws_acm_certificate.ssl_cert.domain_validation_options
}

Produces this -

  + show_ssl_info_for_cnames = [
      + {
          + domain_name           = "*.qa.day-app.com"
          + resource_record_name  = (known after apply)
          + resource_record_type  = (known after apply)
          + resource_record_value = (known after apply)
        },
      + {
          + domain_name           = "*.qa.recog-now.io"
          + resource_record_name  = (known after apply)
          + resource_record_type  = (known after apply)
          + resource_record_value = (known after apply)
        },
      + {
          + domain_name           = "*.qa.sales-app.com"
          + resource_record_name  = (known after apply)
          + resource_record_type  = (known after apply)
          + resource_record_value = (known after apply)
        },
      + {
          + domain_name           = "qa.day-app.com"
          + resource_record_name  = (known after apply)
          + resource_record_type  = (known after apply)
          + resource_record_value = (known after apply)
        },
      + {
          + domain_name           = "qa.recog-now.io"
          + resource_record_name  = (known after apply)
          + resource_record_type  = (known after apply)
          + resource_record_value = (known after apply)
        },
      + {
          + domain_name           = "qa.sales-app.com"
          + resource_record_name  = (known after apply)
          + resource_record_type  = (known after apply)
          + resource_record_value = (known after apply)
        },

Next I am going to use the resource aws_route53_record to add the CNAME record name and value to the corresponding hosted zone. How would I pull out just the record type, value, and name for only one of these - say qa-day-app.com? And then for qa.recog-now.io ?

I tried the following in a count loop but it did not work - I assume I need to match up my domain list with the acm certs but do not know how -

resource "aws_route53_record" "ssl_cert_cname_creation" {
  count   = length(local.domainList)
  provider = aws.{{awsRegion}}
  allow_overwrite = true

  name            = tolist(aws_acm_certificate.ssl_cert.domain_validation_options)[count.index].resource_record_name   # cname value
  records         = [ tolist(aws_acm_certificate.ssl_cert.domain_validation_options)[count.index].resource_record_value ] # cname value
  type            = tolist(aws_acm_certificate.ssl_cert.domain_validation_options)[count.index].resource_record_type

  zone_id = <MY_ZONE_ID>

  ttl      = 60
}

The local.domain list is :

[
      "qa.sales-app.com",
      "qa.recog-now.io",
      "qa.day-app.com",
]
1 Answers

You can use for expressions for this purpose. Consider this example:

locals {
  cnames = [
    {
      domain_name          = "domainA"
      resource_record_type = "typeA"
    },
    {
      domain_name          = "domainB"
      resource_record_type = "typeB"
    }
  ]

  cname_obj = { for c in local.cnames : c.domain_name => c }
}

output "type_for_domain_b" {
  value = local.cname_obj.domainB.resource_record_type
}

output "type_for_domain_b_as_maps" {
  value = local.cname_obj["domainB"]["resource_record_type"]
}

This yields:

āžœ tfp

Changes to Outputs:
  + type_for_domain_b         = "typeB"
  + type_for_domain_b_as_maps = "typeB"

So you can see, you can select by domain name as requested. However, if you are creating per record, you would probably just use these as a for_each meta argument instead.

resource "aws_route53_record" "ssl_cert_cname_creation" {
  for_each = { for c in local.cnames : c.domain_name => c }

  # etc.
}
Related