Creating a programmatic backup of your Route 53 hosted zone records involves understanding how AWS services interact and leveraging the right tools to extract and store that data.
Here’s a live example of how you might do this using the AWS CLI:
aws route53 list-hosted-zones --query "HostedZones[?Name == 'example.com.']" --output json > hosted_zone.json
ZONE_ID=$(jq -r '.[0].Id' hosted_zone.json | sed 's/\/hostedzone\///')
aws route53 list-resource-record-sets --hosted-zone-id $ZONE_ID --output json > record_sets_$ZONE_ID.json
echo "Backup complete for example.com. Zone ID: $ZONE_ID"
This script first finds the hosted_zone.json for example.com, then extracts its Zone ID, and finally dumps all resource record sets for that zone into record_sets_$ZONE_ID.json.
The problem this solves is the risk of accidental deletion or misconfiguration of DNS records, which can lead to significant downtime. Route 53, while robust, doesn’t offer a built-in, granular backup feature for individual hosted zones that can be easily restored. Programmatic backups provide an auditable, versionable, and restorable snapshot of your DNS configuration.
Internally, list-hosted-zones queries the Route 53 API to retrieve information about all hosted zones associated with your AWS account. The --query parameter uses JMESPath to filter this output, specifically looking for the zone whose Name matches example.com.. The list-resource-record-sets command then uses the identified Zone ID to fetch all the individual DNS records (like A, CNAME, MX, etc.) within that zone. The output is JSON, which is both human-readable and easily parseable by scripts or other services.
The exact levers you control are the AWS CLI commands themselves, the filtering criteria in the --query parameter (e.g., filtering by zone name, or by tags if you use them), and where you store the resulting JSON files. You can automate this process using cron jobs, AWS Lambda functions triggered on a schedule, or integrate it into broader CI/CD pipelines for disaster recovery.
The most surprising true thing about this process is that the list-resource-record-sets API call does not include the authoritative name servers for the zone in its output. To get those, you’d typically look at the DelegationSet property when you create a hosted zone, or if you’re dealing with a zone that isn’t your primary zone for a domain, you’d need to query the parent zone’s NS records to discover them. This detail is crucial if your backup needs to be fully self-contained for restoration without relying on external lookups.
The next concept to explore is how to programmatically restore these backups into a Route 53 hosted zone.