DNS records for email authentication — SPF, DKIM, DMARC, MX, BIMI — are the foundation of your deliverability infrastructure, and incorrect changes to any of them can cause immediate authentication failure or domain spoofing exposure. When DNS is managed exclusively through a web UI, there is no change history, no peer review, no rollback, and no audit trail. A DKIM selector changed in the provider console without a corresponding key update in the secrets manager, or an SPF record that inadvertently drops an authorized sender, will cause delivery failures across your entire subscriber base. RFC1035 records defined as infrastructure-as-code follow the same review process as code changes, providing the same safety guarantees.
Info because unversioned DNS management increases operational risk and recovery time from misconfiguration rather than causing an immediate delivery failure, but its impact becomes critical the moment a misconfiguration occurs.
Define all email authentication DNS records as Terraform (or equivalent IaC) resources so changes go through version control and code review. Store DKIM public keys as Terraform variables, not as inline string literals:
# Terraform: DNS records for mail.company.com
resource "cloudflare_record" "spf" {
zone_id = var.cloudflare_zone_id
name = "mail"
type = "TXT"
value = "v=spf1 include:sendgrid.net ~all"
ttl = 3600
}
resource "cloudflare_record" "dkim" {
zone_id = var.cloudflare_zone_id
name = "k1._domainkey.mail"
type = "TXT"
value = var.dkim_public_key # Injected from secrets, not hardcoded
ttl = 3600
}
resource "cloudflare_record" "dmarc" {
zone_id = var.cloudflare_zone_id
name = "_dmarc.mail"
type = "TXT"
value = "v=DMARC1; p=quarantine; rua=mailto:dmarc@company.com; pct=100"
ttl = 3600
}
Commit the Terraform state backend configuration and lock file. Any DNS change now requires a terraform plan review and an apply with CI approval — the same bar as a code deployment.
ID: deliverability-engineering.domain-ip-strategy.dns-version-control
Severity: info
What to look for: Count all DNS record definitions in version-controlled files. Search for DNS records defined in version-controlled files: Terraform .tf files with aws_route53_record or cloudflare_record resources, Pulumi programs with DNS record resources, CloudFormation templates, or plain text zone files committed to the repository. Look for SPF, DKIM, DMARC, MX, and BIMI records defined as code rather than managed entirely via a DNS provider's web UI.
Pass criteria: At least 1 DNS record for the sending domain is defined in infrastructure-as-code (Terraform, Pulumi, CDK, CloudFormation) or in zone files checked into version control. Changes to DNS records go through the same review process as code changes.
Fail criteria: DNS records are managed entirely through a web UI (AWS Route 53 console, Cloudflare dashboard, Namecheap) with no version-controlled representation. DNS changes are not reviewed or audited.
Skip (N/A) when: The project is an early-stage prototype where infrastructure-as-code is not yet established.
Detail on fail: "No DNS record definitions found in version control — DNS is managed entirely via web UI with no audit trail or review process" or "SPF/DKIM/DMARC records not included in infrastructure-as-code"
Remediation: Define DNS records in Terraform (or equivalent):
# Terraform: Email authentication DNS records for mail.company.com
resource "cloudflare_record" "spf" {
zone_id = var.cloudflare_zone_id
name = "mail"
type = "TXT"
value = "v=spf1 include:sendgrid.net ~all"
ttl = 3600
}
resource "cloudflare_record" "dkim" {
zone_id = var.cloudflare_zone_id
name = "k1._domainkey.mail"
type = "TXT"
value = var.dkim_public_key # Stored in Terraform variables, not hardcoded
ttl = 3600
}
resource "cloudflare_record" "dmarc" {
zone_id = var.cloudflare_zone_id
name = "_dmarc.mail"
type = "TXT"
value = "v=DMARC1; p=quarantine; rua=mailto:dmarc@company.com; pct=100"
ttl = 3600
}