Two-Phase ACM Validation with External DNS
Issuing a certificate when Terraform doesn't own the zone
Abstract
When the DNS zone lives with an external provider, Terraform cannot create the ACM validation records itself, and a naive single apply deadlocks: CloudFront wants a validated certificate that cannot validate until records exist that the apply is waiting to finish before emitting. This paper documents the two-phase apply that breaks the cycle, and why the distribution is gated behind a flag.
The deadlock
A CloudFront distribution with a custom domain needs an issued ACM
certificate in us-east-1. ACM issues a DNS-validated certificate only after a
specific CNAME appears in the domain’s zone.1 When Terraform owns the
zone, it writes that record in the same apply. When the zone is external,
Terraform cannot — and a single apply that both requests the certificate and
builds the distribution cannot complete, because:
The approach: split the apply
The fix is to make certificate issuance a human-in-the-loop boundary and gate the distribution behind a variable. The environment exposes two flags:
us-east-1Phase 1 — request and surface
The first apply creates the bucket, requests the certificate, and outputs the validation records — without attempting to build the distribution.
terraform apply
terraform output acm_dns_validation_records
The operator copies those records into the external DNS provider and waits for
ACM to report the certificate as ISSUED.
create_distribution keeps the whole environment in one state file
and one mental model. The phases are a property of applying, not of the
topology.Phase 2 — build the edge
Once the certificate is issued, the second apply enables the distribution:
terraform apply -var="create_distribution=true"
terraform output cloudfront_domain_name
Finally the apex hostname is pointed at the CloudFront domain. Because apex
records can’t be plain CNAMEs, the provider’s ALIAS/ANAME equivalent is
used.
| Resource | After phase 1 | After phase 2 |
|---|---|---|
| S3 bucket | ✓ | ✓ |
| ACM certificate | requested | issued |
| CloudFront | — | ✓ |
| Public site | — | ✓ |
Why this is acceptable
The two-phase apply trades a one-time manual step for keeping DNS authority where it belongs. The boundary is explicit, the outputs make the required action obvious, and subsequent applies (after the certificate exists) are single-shot again. For a site provisioned once and rarely touched, that is the right trade-off.
CNAME must stay in the zone for the life of the certificate —
ACM re-checks it on renewal. Removing it after issuance will break auto-renewal.References
- (2024). DNS validation for ACM certificates. AWS Certificate Manager User Guide.
Cite this paper
Jon (2026). Two-Phase ACM Validation with External DNS (v1.1). Prosyon Research. https://research.prosyon.ca/papers/external-dns-acm-flow/