ACM wildcard and apex certs share the same validation CNAME
Requested an ACM certificate with a wildcard SAN:
resource "aws_acm_certificate" "main" {
domain_name = "fizz.today"
subject_alternative_names = ["*.fizz.today"]
validation_method = "DNS"
}
Terraform plan showed two domain_validation_options entries. Wrote a for_each over them to create DNS validation records. Cloudflare rejected the second record as a duplicate.
The cause
ACM’s DNS validation for fizz.today and *.fizz.today produces the same CNAME record. Same name, same value. They’re validated by a single DNS entry.
But domain_validation_options returns two items — one per domain name on the cert. If you naively iterate, you try to create the same DNS record twice:
# BROKEN — creates duplicate records
resource "cloudflare_dns_record" "acm_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options :
dvo.domain_name => dvo
}
# ...
}
Two entries keyed by fizz.today and *.fizz.today, both pointing to the same _acm-validation.fizz.today CNAME.
The fix
Key the for_each on the record name, not the domain name, and filter to just one:
resource "cloudflare_dns_record" "acm_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options :
dvo.resource_record_name => dvo
if dvo.domain_name == var.domain # dedup: wildcard shares apex CNAME
}
zone_id = var.cloudflare_zone_id
name = each.value.resource_record_name
type = "CNAME"
content = each.value.resource_record_value
proxied = false
}
The if dvo.domain_name == var.domain filter drops the wildcard entry. Since both produce the same CNAME, keeping just the apex entry is sufficient.
Why this is easy to miss
It works fine in the AWS console — you create one validation record and both domain names validate. The duplication only bites you in Terraform, where for_each needs unique keys and DNS providers reject duplicate records.
The AWS docs mention that wildcard and apex “may share” a validation record, but they don’t frame it as a Terraform footgun. If you’re writing ACM + DNS validation in Terraform for the first time, you’ll hit this.