DNS as Code (Terraform + Cloudflare)
Infrastructure-as-code for a personal web fleet of ~70 hostnames across 10 domains: DNS consolidated from four registrars onto Cloudflare and held as ~220 Terraform-managed records, with AWS S3 remote state, Ansible provisioning, and a plan-only disaster-recovery blueprint.
Problem
DNS for ten domains was scattered across four registrars - name.com, Porkbun, Bluehost, GoDaddy - with no version control, no review, and no way to reproduce it. One registrar (Bluehost) had no API at all, so the records there could not be managed as code without first moving them.
What I Built
Consolidated every domain's nameservers onto Cloudflare, then brought ~220 records across 9 zones (A, CNAME, MX, TXT, SRV) under Terraform by importing the live records rather than recreating them - reconciling the configuration to production until terraform plan reported zero changes, so no traffic-serving record was ever dropped or duplicated. Kept the state in AWS S3, deliberately off the compute provider, so a DigitalOcean outage cannot destroy both the box and the state that rebuilds it (S3-native locking, no DynamoDB). Wrote Ansible roles for one-command subdomain provisioning (Apache vhost plus Let's Encrypt, ordered so DNS resolves before the certbot challenge) and for rebuilding the base stack on a fresh host. Added a separate, plan-only Terraform module describing the droplet, volume, and firewall for disaster recovery, plus GitHub Actions running fmt, validate, and plan-on-PR.
Result
DNS is now changed by pull request instead of by clicking, with a reviewable diff and a no-op baseline plan that makes any real change visible. The decisions are written up as Architecture Decision Records, and the full repo is published as a sanitized public mirror.
Terraform
Cloudflare
AWS S3
Ansible
GitHub Actions
DNS
IaC