Unlike some AWS services that provide one-click export options, Route 53 doesn't offer a direct "Export" button in the console for hosted zones. This creates challenges when you need to:
- Migrate DNS configurations between accounts
- Maintain version-controlled backups
- Share zone configurations with team members
Method 1: Using AWS CLI
The most efficient way is using aws route53 list-resource-record-sets
:
aws route53 list-resource-record-sets \
--hosted-zone-id /hostedzone/Z1PA6795UKMFR9 \
--output json > route53_backup.json
Method 2: AWS SDK Programmatic Export
Python example using Boto3:
import boto3
import json
route53 = boto3.client('route53')
def export_zone(zone_id, output_file):
records = route53.list_resource_record_sets(
HostedZoneId=zone_id
)
with open(output_file, 'w') as f:
json.dump(records['ResourceRecordSets'], f, indent=2)
export_zone('Z1PA6795UKMFR9', 'dns_backup.json')
Method 3: DNS Zone File Format
For compatibility with other DNS systems, convert to standard zone file format:
aws route53 list-resource-record-sets \
--hosted-zone-id Z1PA6795UKMFR9 \
--query "ResourceRecordSets[*].[Name,Type,TTL,ResourceRecords[].Value]" \
--output text | \
awk '{print $1 " " $2 " " $3 " " $4}' > zonefile.txt
- Handle pagination for zones with >100 records
- Include comments/timestamps in exports
- Compress large zone files
- Consider Terraform/AWS CDK for infrastructure-as-code approaches
Use aws route53 change-resource-record-sets
with the exported JSON to recreate records in a new hosted zone. Always verify record TTLs and values match your original configuration.
Many AWS users are surprised to discover there's no direct "Export" button for Route 53 hosted zones in the management console. While you could manually record DNS records using dig
commands, this approach becomes impractical for zones with numerous records or when you need frequent backups.
The most reliable methods come from AWS's own tools:
# AWS CLI method to list all records
aws route53 list-resource-record-sets \
--hosted-zone-id /hostedzone/Z1D633PEXAMPLE \
--output json > route53_backup.json
For programmatic access in different languages:
// Python using boto3
import boto3
import json
client = boto3.client('route53')
response = client.list_resource_record_sets(
HostedZoneId='Z1D633PEXAMPLE'
)
with open('route53_export.json', 'w') as f:
json.dump(response, f, indent=4)
Several open-source tools can simplify the process:
- Route53-export (Node.js)
- terraform-aws-route53 (for Terraform users)
- awscli-zsh-plugin (adds export shortcuts)
When you need to convert between formats:
# Convert JSON to BIND format
jq -r '.ResourceRecordSets[] |
"\(.Name) \(.TTL) IN \(.Type) \(.ResourceRecords[].Value)"' \
route53_backup.json > zonefile.txt
Create a Lambda function triggered by CloudWatch Events:
// Lambda backup function
exports.handler = async (event) => {
const AWS = require('aws-sdk');
const route53 = new AWS.Route53();
const s3 = new AWS.S3();
const params = { HostedZoneId: 'Z1D633PEXAMPLE' };
const data = await route53.listResourceRecordSets(params).promise();
await s3.putObject({
Bucket: 'route53-backups',
Key: backups/${new Date().toISOString()}.json,
Body: JSON.stringify(data)
}).promise();
};