← All decisions jacob@stephens.page
Decision Record

Import live DNS into Terraform over recreating it from a desired-state list

ADR 0014 · Accepted ยท in production · ~586 words

Context

A fleet of ~220 DNS records across 9 zones (A, CNAME, MX, TXT, SRV) had just been consolidated onto one provider and was serving live traffic - web, and the email records that matter more: MX, SPF, DKIM selectors, DMARC. The goal was to bring all of it under Terraform so every later change is a reviewable diff.

Two ways to put existing infrastructure under code. Recreate: author a desired-state list and let Terraform create it, deleting whatever doesn't match. Import: pull the records that already exist into Terraform state and write configuration that matches them, changing nothing.

Recreate is tempting because the config is hand-authored and clean from the start, but against live records it is the wrong default. Terraform's create path would try to make records that already exist (duplicates or API errors), and any record the hand-authored list forgot - an obscure DKIM selector, a verification TXT - would be deleted as drift. For DNS that is an outage and a silently broken mail domain, in exchange for tidier source files.

Decision

Import the live records; never recreate them.

Consequences

When I'd revisit

For a greenfield zone with no live records, recreate is right: author the desired state directly and let Terraform build it, no import dance. The same holds if a record set is small enough to recreate inside a planned maintenance window where a brief inconsistency is acceptable. The import-first rule is specifically for adopting infrastructure already serving traffic - most of the interesting cases, and the one where recreating quietly breaks things.

Narrative writeup: Importing Live DNS into Terraform Without Downtime. One of a set of architecture decision records. Source markdown lives in the infrastructure-patterns repo, which is the canonical copy.