Terraform and AWS wildcard certificates validation


Context

When defining an AWS ACM certificate in Terraform, it is common to define the validation for that certificate as well (this is a requirement to attach the certificate to a Load Balancer). The current documentation example doesn’t work when the certificate in question contains wildcard domains (e.g. example.com, *.example.com).

Implementation

The following solution leverages the fact that AWS ACM will generate the same validation CNAME for both *.example.com and example.com by filtering the map of values to exclude any non-wildcard SAN.

resource "aws_route53_zone" "example" {
  name = "example.com"
}

resource "aws_acm_certificate" "example" {
  domain_name = "example.com"
  validation_method = "DNS"

  subject_alternative_names = [
    "*.example.com",
  "*.docs.example.com"
  ]

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_route53_record" "example" {
  for_each = {
    for dvo in aws_acm_certificate.example.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
   # Skips the domain if it doesn't contain a wildcard
    if length(regexall("\\*\\..+", dvo.domain_name)) > 0
  }

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

The above solution works in cases where the list of SANs contains wildcard domains (by itself or alongside the parent domain), e.g:

  • example.com
  • *.example.com
  • *.docs.example.com

This implementation won’t work if you have a SANs list as follows

  • example.com
  • help.example.com
  • *.help.example.com

In this case, the only record validation generated would be for *.help.example.com. If you need a more complete solution check the gist in the reference section.

Notes

References

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.