Wayne Workman
Wayne Workman

Reputation: 541

Exclude subject alternative name from aws_acm_certificate.domain_validation_options in Terraform for loop

I am creating an ACM Certificate for use in a new AWS account with Terraform 1.1.9 and AWS Provider 4.10.0.

The certificate needs to contain a subject alternative name for a domain name in another AWS account. This is because some infrastructure is being moved from one account to another, and I'm setting up a redirect in the old account so that old URLs redirect to the new one.

Because the SAN domain name does not exist in the new AWS account's Route53 area, the automated Terraform way to create Route53 certificate validation records via for loops is not working. Below is that old way which works if all the domains are in the current AWS account.

resource "aws_acm_certificate" "results_cert" {
  domain_name = "${var.results_name}.${data.terraform_remote_state.base.outputs.zone_name}"
  validation_method = "DNS"
}

resource "aws_route53_record" "results_cert" {
  for_each = {
    for dvo in aws_acm_certificate.results_cert.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.terraform_remote_state.base.outputs.zone_id
}

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

The new Terraform with the added SAN is below, and contains what I've attempted to exclude the SAN from the route53 record creation and validation, as I plan to create the validation record manually in the old account.


resource "aws_acm_certificate" "results_cert" {
  domain_name = "${var.project}.${data.terraform_remote_state.base.outputs.zone_name}"
  subject_alternative_names = ["old-domain-name.com"]
  validation_method = "DNS"
}


resource "aws_route53_record" "results_cert" {
  for_each = {
    for dvo in {for k, v in aws_acm_certificate.results_cert.domain_validation_options: k => v if ! contains(values(v), "old-domain-name.com")} : 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.terraform_remote_state.base.outputs.zone_id
}

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

This results in the below error.

│ Error: Invalid object key
│ 
│   on results.tf line 21, in resource "aws_route53_record" "results_cert":
│   21:     for dvo in {for k, v in aws_acm_certificate.results_cert.domain_validation_options: k => v if ! contains(values(v), "old-domain-name.com")} : dvo.domain_name => {
│ 
│ The key expression produced an invalid result: string required.

How can I exclude the SAN "old-domain-name.com" from the Route53 record creation loop?

Upvotes: 1

Views: 1035

Answers (1)

Marcin
Marcin

Reputation: 238131

aws_acm_certificate.results_cert.domain_validation_options is a list of maps, not a map. So it should be:

resource "aws_route53_record" "results_cert" {

  for_each = {
    for validation_option in aws_acm_certificate.results_cert.domain_validation_options: 
           validation_option.domain_name => {
              name   = validation_option.resource_record_name
              record = validation_option.resource_record_value
              type   = validation_option.resource_record_type
           } if validation_option.domain_name != "old-domain-name.com"
    }

  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id = data.terraform_remote_state.base.outputs.zone_id
}

Upvotes: 4

Related Questions