Amazon Route 53 Essentials
Route53 essentials, DNS routing policies, health checks, and best practices
/health endpointForgetting EvaluateTargetHealth: true in ALIAS to ALBNot testing Failover before a real disasterChanging records without considering previous TTLUnexpected costs from CNAME queriesCost ConsiderationsWhat Generates Costs in Route53Free Tier (First 12 months)Real Cost CalculationCost OptimizationIntegration with Other ServicesAdditional ResourcesOfficial AWS DocumentationWhitepapers and Best PracticesHands-On TutorialsAmazon Route53 is AWS's managed DNS (Domain Name System) service that translates human-readable domain names (myapp.com) to IP addresses that computers use to connect to each other. It's highly available, scalable, and integrates natively with other AWS services.
The problem it solves: Eliminates the need to manage your own DNS servers, provides intelligent routing based on latency/location/resource health, and enables multi-region architectures with automatic failover. Converts hard-to-remember AWS DNS names (e.g., myapp-lb-1234567890.sa-east-1.elb.amazonaws.com) into professional domains (www.myapp.com).
When to use it: ALWAYS when you have a public domain. Route53 isn't optional for production applications - it's the layer that makes your AWS infrastructure reliably and professionally accessible from the internet.
Alternatives: External DNS providers (Cloudflare, Namecheap DNS, GoDaddy DNS), on-premise DNS (BIND, PowerDNS). However, Route53 integrates better with AWS and offers routing policies that traditional DNS doesn't have.
Key Concepts
| Concept | Description |
|---|---|
| Hosted Zone | Container of DNS records for a specific domain. Works like a "DNS database" where you define how queries to your domain are resolved. Public Hosted Zones (accessible from internet) and Private Hosted Zones (only within VPC) exist |
| Record / Resource Record Set | DNS entry that maps a name to a value (IP, another name, etc.). Each record has a Type (A, AAAA, CNAME, etc.) that defines what type of information it contains |
| A Record | Maps a hostname to an IPv4 address (e.g., myapp.com → 18.231.123.45) |
| AAAA Record | Maps a hostname to an IPv6 address (e.g., myapp.com → 2600:1f18:...) |
| CNAME Record | Alias that points a name to another DNS name (e.g., www.myapp.com → myapp.com). Does NOT work at zone apex (root domain) |
| ALIAS Record | Special Route53 type that maps to AWS resources (ALB, CloudFront, S3). Works at zone apex, queries are FREE, and it's faster than CNAME |
| TTL (Time To Live) | Time in seconds that DNS resolvers cache a record before querying again. Low TTL = fast changes but more queries. High TTL = fewer queries but slow changes |
| Name Servers (NS) | Authoritative servers for your domain. Route53 assigns 4 NS when creating a Hosted Zone - you must configure them in your domain registrar |
| Routing Policy | Algorithm that Route53 uses to decide how to respond to DNS queries. Determines which resource to send traffic to based on specific criteria |
| Health Check | Active monitoring of endpoints that Route53 uses to determine if a resource is healthy. Makes periodic HTTP/HTTPS/TCP requests and marks resources as healthy/unhealthy |
| Simple Routing | Most basic policy - one record points to one or multiple values without health checks. Route53 returns all values, client chooses randomly |
| Failover Routing | Policy for DR - defines PRIMARY and SECONDARY resources. If primary fails health check, traffic automatically goes to secondary |
| Latency-Based Routing | Policy that sends users to the resource with lowest latency from their location. Route53 measures latency to each AWS region and responds with the fastest |
| Geolocation Routing | Policy that routes traffic based on user's geographic location. Useful for compliance (GDPR) and content localization |
| Weighted Routing | Policy that distributes traffic among multiple resources according to assigned weights (percentages). Ideal for A/B testing and canary deployments |
| Multivalue Answer Routing | Similar to Simple but with health checks. Returns multiple healthy values (up to 8), eliminating unhealthy resources from the response |
| Calculated Health Check | Combines multiple individual health checks with AND/OR logic. Allows creating complex health checks based on multiple conditions |
| Set Identifier | Unique ID required when using advanced routing policies (except Simple). Allows having multiple records with the same Name but different targets |
Essential AWS CLI Commands
Creating Resources
# Create Public Hosted Zone
aws route53 create-hosted-zone \
--name myapp.com \
--caller-reference $(date +%s) \
--hosted-zone-config Comment="Production domain"
# Create Private Hosted Zone (only accessible from VPC)
aws route53 create-hosted-zone \
--name internal.myapp.local \
--vpc VPCRegion=sa-east-1,VPCId=vpc-xxxxx \
--caller-reference $(date +%s) \
--hosted-zone-config PrivateZone=true
# Create Health Check (HTTP/HTTPS endpoint)
aws route53 create-health-check \
--caller-reference $(date +%s) \
--health-check-config \
Protocol=HTTPS,\
FullyQualifiedDomainName=myapp-lb.sa-east-1.elb.amazonaws.com,\
Port=443,\
ResourcePath=/health,\
Type=HTTPS,\
RequestInterval=30,\
FailureThreshold=3
# Create Health Check based on CloudWatch Alarm
aws route53 create-health-check \
--caller-reference $(date +%s) \
--health-check-config \
Type=CLOUDWATCH_METRIC,\
AlarmIdentifier={Region=sa-east-1,Name=HighCPUAlarm},\
InsufficientDataHealthStatus=Healthy
# Create ALIAS record pointing to ALB (Simple Routing)
cat > create-alias-record.json << 'EOF'
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "myapp.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2P70J7HTTTPLU",
"DNSName": "myapp-lb-123.sa-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}
EOF
aws route53 change-resource-record-sets \
--hosted-zone-id Z0123456789ABC \
--change-batch file://create-alias-record.json
# Create record with Failover Routing (PRIMARY)
cat > failover-primary.json << 'EOF'
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "myapp.com",
"Type": "A",
"SetIdentifier": "Primary-SaoPaulo",
"Failover": "PRIMARY",
"HealthCheckId": "abc123-healthcheck-id",
"AliasTarget": {
"HostedZoneId": "Z2P70J7HTTTPLU",
"DNSName": "myapp-lb-saopaulo.sa-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}
EOF
aws route53 change-resource-record-sets \
--hosted-zone-id Z0123456789ABC \
--change-batch file://failover-primary.json
# Create record with Weighted Routing (A/B testing - 80/20)
cat > weighted-stable.json << 'EOF'
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "api.myapp.com",
"Type": "A",
"SetIdentifier": "Stable-v1.0",
"Weight": 80,
"TTL": 60,
"ResourceRecords": [{"Value": "18.231.1.10"}]
}
}]
}
EOF
# Create record with Latency-Based Routing
cat > latency-saopaulo.json << 'EOF'
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "myapp.com",
"Type": "A",
"SetIdentifier": "Latency-SaoPaulo",
"Region": "sa-east-1",
"HealthCheckId": "abc123-saopaulo",
"AliasTarget": {
"HostedZoneId": "Z2P70J7HTTTPLU",
"DNSName": "myapp-lb-saopaulo.sa-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": false
}
}
}]
}
EOF
# Create record with Geolocation Routing
cat > geo-brazil.json << 'EOF'
{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "myapp.com",
"Type": "A",
"SetIdentifier": "Geo-Brazil",
"GeoLocation": {
"CountryCode": "BR"
},
"AliasTarget": {
"HostedZoneId": "Z2P70J7HTTTPLU",
"DNSName": "myapp-lb-saopaulo.sa-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}
EOFQuerying Resources
# List all Hosted Zones
aws route53 list-hosted-zones
# View details of a specific Hosted Zone
aws route53 get-hosted-zone --id Z0123456789ABC
# List all records in a Hosted Zone
aws route53 list-resource-record-sets \
--hosted-zone-id Z0123456789ABC
# List records filtering by name
aws route53 list-resource-record-sets \
--hosted-zone-id Z0123456789ABC \
--query "ResourceRecordSets[?Name=='myapp.com.']"
# List Health Checks
aws route53 list-health-checks
# View current status of a Health Check
aws route53 get-health-check-status \
--health-check-id abc123-healthcheck-id
# View Health Check details
aws route53 get-health-check \
--health-check-id abc123-healthcheck-id
# Get Name Servers of a Hosted Zone
aws route53 get-hosted-zone --id Z0123456789ABC \
--query 'DelegationSet.NameServers[]' \
--output tableModifying Resources
# Update existing record (UPSERT = create or update)
cat > update-record.json << 'EOF'
{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "myapp.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "18.231.2.20"}]
}
}]
}
EOF
aws route53 change-resource-record-sets \
--hosted-zone-id Z0123456789ABC \
--change-batch file://update-record.json
# Change TTL of a record
cat > change-ttl.json << 'EOF'
{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "api.myapp.com",
"Type": "A",
"TTL": 60,
"ResourceRecords": [{"Value": "18.231.1.10"}]
}
}]
}
EOF
# Update Health Check (change interval)
aws route53 update-health-check \
--health-check-id abc123-healthcheck-id \
--health-check-version 1 \
--health-threshold 2
# Temporarily disable a Health Check (testing failover)
aws route53 update-health-check \
--health-check-id abc123-healthcheck-id \
--disabled
# Re-enable Health Check
aws route53 update-health-check \
--health-check-id abc123-healthcheck-id \
--no-disabled
# Associate additional VPC to Private Hosted Zone
aws route53 associate-vpc-with-hosted-zone \
--hosted-zone-id Z0123456789ABC \
--vpc VPCRegion=us-east-1,VPCId=vpc-yyyyyDeleting Resources
# Delete record (requires specifying exactly the record)
cat > delete-record.json << 'EOF'
{
"Changes": [{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "old.myapp.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "18.231.1.99"}]
}
}]
}
EOF
aws route53 change-resource-record-sets \
--hosted-zone-id Z0123456789ABC \
--change-batch file://delete-record.json
# Delete Health Check
aws route53 delete-health-check \
--health-check-id abc123-healthcheck-id
# Disassociate VPC from Private Hosted Zone
aws route53 disassociate-vpc-from-hosted-zone \
--hosted-zone-id Z0123456789ABC \
--vpc VPCRegion=sa-east-1,VPCId=vpc-xxxxx
# Delete Hosted Zone (must be empty except NS and SOA)
aws route53 delete-hosted-zone \
--id Z0123456789ABCDebugging / Troubleshooting
# Test DNS resolution with dig
dig myapp.com
# Test specifically against Route53 Name Servers
dig @ns-123.awsdns-45.com myapp.com
# View recent changes in Hosted Zone
aws route53 list-resource-record-sets \
--hosted-zone-id Z0123456789ABC \
--query 'ResourceRecordSets[*].[Name,Type,TTL]' \
--output table
# Verify DNS change status
aws route53 get-change --id /change/C0123456789ABC
# Test health check manually
curl -I https://myapp-lb.sa-east-1.elb.amazonaws.com/healthArchitecture and Flows
Multi-Region Architecture with Failover
DNS Resolution Flow
Comparison of Routing Policies
Health Check States
Best Practices Checklist
Security
- Enable DNSSEC: Protect against DNS spoofing on critical domains (requires registrar support)
- Private Hosted Zones for internal resources: Never expose internal names (db.internal, redis.internal) in public DNS
- Restrictive IAM policies: Limit who can modify Hosted Zones and critical records
- CloudTrail logging: Audit all Route53 changes for compliance
- Separate Hosted Zones by environment: prod.myapp.com, staging.myapp.com in different Hosted Zones
- Validate records before applying: Use
--dry-runor test in non-prod zone first - Health checks with HTTPS: Always use HTTPS when the endpoint supports it for secure verification
Cost Optimization
- Use ALIAS records over CNAME: Queries to ALIAS are FREE vs normal queries ($0.40 per million)
- Consolidate Hosted Zones: Avoid separate Hosted Zones for subdomains (costs $0.50/month each)
- Appropriate health check interval: Use 30s instead of 10s unless you need ultra-fast failover (saves 66%)
- Delete unused Health Checks: Each health check costs $0.50/month, delete unused ones
- Calculated Health Checks for aggregation: Instead of redundant individual health checks
- Monitor queries with CloudWatch: Identify unexpected queries that generate costs
- Balanced TTL: Very low TTL generates more queries (more cost), very high slows down changes
Performance
- Low TTL for critical records: 60-300s allows fast changes during incidents
- ALIAS at zone apex: Faster than CNAME (avoids additional query)
- Latency-based routing for global apps: Users always go to the fastest endpoint
- Geoproximity with bias: Adjust routing to optimize latency in specific regions
- Adequate health check interval: Balance between fast detection (10s) and overhead (30s)
- EvaluateTargetHealth in ALIAS: Leverage native ALB/CloudFront health checks
- Multivalue Answer for simple load balancing: Economical alternative when you don't need ALB
Reliability
- Multi-region with Failover: Always have SECONDARY region for critical resources
- Robust health checks:
/healthendpoint must verify dependencies (DB, cache, external API) - Test failover regularly: Simulate primary failures monthly to validate configuration
- Appropriate health check threshold: FailureThreshold of 2-3 to tolerate temporary blips
- Calculated Health Checks for composite: Require multiple dependencies to be healthy
- Monitor Name Server availability: Although Route53 has 100% SLA, monitor anyway
- Backup DNS configuration: Export records regularly (preferably use IaC)
Operational Excellence
- Infrastructure as Code: Manage Route53 with Terraform/CloudFormation, not console
- Clear naming conventions: Descriptive SetIdentifiers (Primary-SaoPaulo, Canary-v2.0)
- Document routing logic: Especially for complex Weighted and Geolocation setups
- Tag Hosted Zones: Environment, Project, Owner for tracking
- Change tracking: Comment critical changes in commit messages or tickets
- Automate DNS updates: Integrate with CI/CD for automatic post-deploy updates
- CloudWatch alerts: Monitor health check failures, query spikes
Common Mistakes to Avoid
Not configuring Name Servers in the Domain Registrar
Why it happens: After creating the Hosted Zone in Route53, forgetting to update the NS in GoDaddy/Namecheap.
The real problem: Route53 has all records configured but isn't authoritative. DNS queries go to old NS that don't know your records → site down or points to incorrect IPs.
Symptoms:
dig myapp.com
# ;; ANSWER SECTION: (empty or incorrect IPs)
# ;; AUTHORITY SECTION: ns-old.godaddy.com (not Route53)How to avoid it:
# 1. Get NS from Route53
aws route53 get-hosted-zone --id Z0123456789ABC \
--query 'DelegationSet.NameServers[]'
# Output:
# ns-123.awsdns-45.com
# ns-678.awsdns-90.net
# ns-901.awsdns-23.org
# ns-234.awsdns-56.co.uk
# 2. Go to your registrar (GoDaddy/Namecheap)
# 3. Replace old NS with these 4 Route53 NS
# 4. Wait for propagation (can take up to 48h, typically under 1h)
# 5. Verify propagation
dig myapp.com @8.8.8.8 # Google DNS
dig myapp.com @1.1.1.1 # Cloudflare DNSUsing CNAME at zone apex (root domain)
Why it happens: Trying to create CNAME myapp.com → alb.amazonaws.com because it works for www.myapp.com.
Technical problem: RFC 1034 prohibits CNAME at zone apex. DNS requires apex to have SOA and NS records, which are incompatible with CNAME.
Route53 error:
RRSet of type CNAME with DNS name myapp.com. is not permitted at apex in zone myapp.comHow to avoid it: Use ALIAS record instead of CNAME for apex:
{
"Name": "myapp.com",
"Type": "A",
"AliasTarget": {
"DNSName": "myapp-lb.sa-east-1.elb.amazonaws.com",
"HostedZoneId": "Z2P70J7HTTTPLU",
"EvaluateTargetHealth": true
}
}Very high TTL on production records
Why it happens: Leaving default TTL (86400 = 24 hours) thinking "fewer queries = less cost".
The real problem: You need to change from old ALB to new ALB urgently (deploy, incident, migration). You change the record but users keep using the old cached IP for 24 hours.
Critical scenario:
10:00 AM - Deploy new ALB, change record
10:05 AM - Delete old ALB to save costs
10:06 AM - Users with DNS cache go to deleted ALB → 50X errorsHow to avoid it:
# Low TTL for production (60-300s)
"TTL": 60 # Changes propagate in ~1 minute
# Trade-off: more queries = more cost
# But for production the cost ($0.40/1M queries) is trivial
# compared to downtime from slow changes
# Strategy:
# - Critical production: TTL 60
# - Non-critical production: TTL 300
# - Staging/Dev: TTL 600-3600Health Check without properly implementing /health endpoint
Why it happens: Configuring health check to / (home page) or to /health that only returns 200 without verifying anything.
The problem: Health check marks healthy even though the app is broken. Database down, Redis offline, but health check says "all good" → Route53 sends traffic to non-functional instance.
Incorrect implementation:
@app.get("/health")
def health():
return {"status": "ok"}, 200 # Always 200, doesn't verify anythingCorrect implementation:
@app.get("/health")
def health():
try:
# Verify database
db.execute("SELECT 1")
# Verify Redis
redis.ping()
# Verify critical external service (if applicable)
# api.health_check()
return {"status": "healthy", "checks": {
"database": "ok",
"cache": "ok"
}}, 200
except DatabaseError:
return {"status": "unhealthy", "error": "database"}, 503
except RedisError:
return {"status": "unhealthy", "error": "cache"}, 503Forgetting EvaluateTargetHealth: true in ALIAS to ALB
Why it happens: Copying examples from the internet that use false by default.
The problem: ALIAS points to ALB, but ALB has 0 healthy targets (all instances went down). Route53 responds with ALB IP even though it's non-functional → users receive 50X errors from ALB.
Behavior:
# With EvaluateTargetHealth: false
Route53 → always responds with ALB IP
even if all ALB targets are unhealthy
# With EvaluateTargetHealth: true
Route53 → checks ALB target group health
if 0 healthy targets → doesn't respond (or failover to secondary)How to avoid it:
{
"AliasTarget": {
"DNSName": "myapp-lb.sa-east-1.elb.amazonaws.com",
"HostedZoneId": "Z2P70J7HTTTPLU",
"EvaluateTargetHealth": true
}
}Not testing Failover before a real disaster
Why it happens: "The configuration looks good in the console, it should work".
The problem: Real disaster arrives (sa-east-1 region down), failover doesn't work because:
- Health check incorrectly configured
- SECONDARY region doesn't have capacity (ASG min-size = 0)
- SECONDARY ALB in private subnet without internet access
- Records with duplicate SetIdentifier
How to avoid it: Monthly failover testing
# 1. Simulate Primary failure
aws route53 update-health-check \
--health-check-id primary-hc \
--disabled
# 2. Verify that DNS resolves to SECONDARY
dig myapp.com
# Should show us-east-1 ALB IP
# 3. Functional test
curl https://myapp.com
# Should respond correctly from secondary
# 4. Verify metrics
# CloudWatch → Route53 → HealthCheckStatus
# Should show Primary=Unhealthy, Secondary=Healthy
# 5. Re-enable Primary
aws route53 update-health-check \
--health-check-id primary-hc \
--no-disabled
# 6. Verify automatic rollback
dig myapp.com
# Should return to sa-east-1 ALB IPChanging records without considering previous TTL
Why it happens: Changing from TTL 3600 to TTL 60 and expecting it to take effect immediately.
The problem: Resolvers already cached the old record for 3600s. The new TTL only applies AFTER the old cache expires.
Real timeline:
10:00 - Record has TTL 3600
10:05 - User makes query, caches for 1 hour (until 11:05)
10:10 - You change record with TTL 60
10:15 - User still using old cache (expires 11:05)
11:05 - Only now does user make new query with TTL 60Correct strategy for important changes:
# Step 1: Reduce TTL in advance
# 24-48 hours before the change
aws route53 change-resource-record-sets ... # TTL 3600 → 60
# Step 2: Wait for old TTL to expire
# (wait 3600s = 1 hour)
# Step 3: Make the real change (change IP/ALB)
aws route53 change-resource-record-sets ... # New target
# Step 4: Changes propagate in ~60sUnexpected costs from CNAME queries
Why it happens: Using CNAME when ALIAS would be appropriate.
Financial impact:
CNAME www.myapp.com → myapp.com
User queries www.myapp.com:
1. Query to www (CNAME) → charged
2. Query to myapp.com (A) → charged
Total: 2 queries
ALIAS www.myapp.com → ALB:
1. Query to www (ALIAS) → FREE
Total: 0 chargeable queries
With 10M queries/month:
CNAME: 20M queries × $0.40/1M = $8/month
ALIAS: 0 chargeable queries = $0/monthSimple rule: Always use ALIAS for AWS resources (ALB, CloudFront, S3, API Gateway).
Cost Considerations
What Generates Costs in Route53
| Item | Cost | Unit | Notes |
|---|---|---|---|
| Hosted Zone | $0.50/month | Per hosted zone | First 25 hosted zones |
| Hosted Zones 26+ | $0.10/month | Per additional hosted zone | After the first 25 |
| Standard Queries | $0.40 | Per million queries | A, AAAA, CNAME, MX, etc. |
| ALIAS Queries | FREE | Unlimited | Only for AWS resources |
| Latency-based Queries | $0.60 | Per million | +50% vs Standard |
| Geo/Geoproximity Queries | $0.70 | Per million | +75% vs Standard |
| Health Checks (Standard) | $0.50/month | Per health check | 30s interval |
| Health Checks (Fast) | $1.00/month | Per health check | 10s interval |
| Health Checks HTTPS | +$1.00/month | Additional | SSL handshake overhead |
| Calculated Health Checks | $1.00/month | Per health check | Combines multiple checks |
| Domain Registration | Variable | Per domain/year | .com ~35/year |
Free Tier (First 12 months)
- 1 Hosted Zone FREE
- 1M queries FREE (only Standard, not Latency/Geo)
- Health Checks NOT included in free tier
- Latency-based Queries NOT included
Real Cost Calculation
Scenario: Multi-region app with failover
Infrastructure:
- 1 Hosted Zone (myapp.com)
- 2 regions (sa-east-1 PRIMARY, us-east-1 SECONDARY)
- 2 Health Checks (one per region, 30s interval)
- 5M queries/month (80% ALIAS to ALB, 20% CNAME subdomains)
- Latency-based routing on some subdomains (1M queries/month)
Monthly costs:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Hosted Zone: $0.50
Health Checks (2 × $0.50): $1.00
ALIAS Queries (4M): $0.00 ← FREE
Standard Queries (1M): $0.40
Latency Queries (1M): $0.60
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TOTAL: $2.50/monthCost Optimization
1. Maximize use of ALIAS records
# AVOID
CNAME www.myapp.com → myapp.com
CNAME api.myapp.com → api-alb.amazonaws.com
# Each query charges 2x (CNAME + target)
# PREFER
ALIAS www.myapp.com → ALB
ALIAS api.myapp.com → ALB
# Queries FREE2. Consolidate Hosted Zones
# EXPENSIVE: Separate Hosted Zones
- prod.myapp.com ($0.50/month)
- staging.myapp.com ($0.50/month)
- dev.myapp.com ($0.50/month)
Total: $1.50/month just for zones
# ECONOMICAL: One Hosted Zone with subdomains
- myapp.com ($0.50/month)
- prod.myapp.com (record)
- staging.myapp.com (record)
- dev.myapp.com (record)
Total: $0.50/month3. Appropriate health check interval
# For critical apps (finance, health):
RequestInterval: 10s # $1.00/month
FailureThreshold: 2 # Failover in ~20s
# For standard apps:
RequestInterval: 30s # $0.50/month
FailureThreshold: 3 # Failover in ~90s
# Savings: 50% per health check4. Routing Policy based on need
# Simple/Failover: $0.40/1M queries
# For most cases
# Latency-based: $0.60/1M queries (+50%)
# Only if you really optimize global latency
# Geolocation: $0.70/1M queries (+75%)
# Only for strict compliance or localizationIntegration with Other Services
| AWS Service | How It Integrates | Typical Use Case |
|---|---|---|
| Application Load Balancer (ALB) | ALIAS record points to ALB DNS | myapp.com → ALB distributes to EC2 instances |
| CloudFront | ALIAS record points to CloudFront distribution | Global CDN with custom domain (cdn.myapp.com) |
| S3 Static Website | ALIAS record points to S3 website endpoint | Static hosting (www.myapp.com → S3 bucket) |
| API Gateway | ALIAS record points to API Gateway custom domain | api.myapp.com → Lambda functions via API Gateway |
| Elastic Beanstalk | ALIAS record points to EB environment | Simplified PaaS deployment with custom domain |
| CloudWatch | Health checks based on CloudWatch Alarms | Failover if custom metric (DB connections) is critical |
| ACM (Certificate Manager) | DNS validation for HTTPS certificates | Validate domain ownership for SSL/TLS certs |
| VPC | Private Hosted Zones only accessible from VPC | Internal DNS for RDS, ElastiCache (db.internal) |
| EC2 | A/AAAA records point to Elastic IPs | Static IP for specific instance |
| Lambda | Health checks triggered by Lambda | Custom logic to determine health (check external API) |
| SNS | CloudWatch Alarms when health check fails | Notifications when failover occurs |
| RDS | CNAME record points to RDS endpoint | db-primary.myapp.com → RDS instance |
| Auto Scaling | ALIAS to ALB that distributes to ASG | Automatic scaling with fixed domain |
| Global Accelerator | ALIAS record points to accelerator | Anycast IPs for ultra-low latency global |
| CloudFormation/Terraform | IaC manages Hosted Zones and records | Infrastructure as code, version control |
Additional Resources
Official AWS Documentation
Whitepapers and Best Practices
- AWS Well-Architected Framework - Reliability Pillar
- Building a Scalable and Secure Multi-VPC Network Infrastructure
- DNS Best Practices