Amazon Route 53 Essentials

Route53 essentials, DNS routing policies, health checks, and best practices

@geomenaMon Jul 28 20251,009 views

Amazon 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

ConceptDescription
Hosted ZoneContainer 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 SetDNS 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 RecordMaps a hostname to an IPv4 address (e.g., myapp.com18.231.123.45)
AAAA RecordMaps a hostname to an IPv6 address (e.g., myapp.com2600:1f18:...)
CNAME RecordAlias that points a name to another DNS name (e.g., www.myapp.commyapp.com). Does NOT work at zone apex (root domain)
ALIAS RecordSpecial 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 PolicyAlgorithm that Route53 uses to decide how to respond to DNS queries. Determines which resource to send traffic to based on specific criteria
Health CheckActive 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 RoutingMost basic policy - one record points to one or multiple values without health checks. Route53 returns all values, client chooses randomly
Failover RoutingPolicy for DR - defines PRIMARY and SECONDARY resources. If primary fails health check, traffic automatically goes to secondary
Latency-Based RoutingPolicy 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 RoutingPolicy that routes traffic based on user's geographic location. Useful for compliance (GDPR) and content localization
Weighted RoutingPolicy that distributes traffic among multiple resources according to assigned weights (percentages). Ideal for A/B testing and canary deployments
Multivalue Answer RoutingSimilar to Simple but with health checks. Returns multiple healthy values (up to 8), eliminating unhealthy resources from the response
Calculated Health CheckCombines multiple individual health checks with AND/OR logic. Allows creating complex health checks based on multiple conditions
Set IdentifierUnique 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
      }
    }
  }]
}
EOF

Querying 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 table

Modifying 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-yyyyy

Deleting 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 Z0123456789ABC

Debugging / 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/health

Architecture 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-run or 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: /health endpoint 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 DNS

Using 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.com

How 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 errors

How 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-3600

Health 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 anything

Correct 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"}, 503

Forgetting 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 IP

Changing 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 60

Correct 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 ~60s

Unexpected 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/month

Simple rule: Always use ALIAS for AWS resources (ALB, CloudFront, S3, API Gateway).

Cost Considerations

What Generates Costs in Route53

ItemCostUnitNotes
Hosted Zone$0.50/monthPer hosted zoneFirst 25 hosted zones
Hosted Zones 26+$0.10/monthPer additional hosted zoneAfter the first 25
Standard Queries$0.40Per million queriesA, AAAA, CNAME, MX, etc.
ALIAS QueriesFREEUnlimitedOnly for AWS resources
Latency-based Queries$0.60Per million+50% vs Standard
Geo/Geoproximity Queries$0.70Per million+75% vs Standard
Health Checks (Standard)$0.50/monthPer health check30s interval
Health Checks (Fast)$1.00/monthPer health check10s interval
Health Checks HTTPS+$1.00/monthAdditionalSSL handshake overhead
Calculated Health Checks$1.00/monthPer health checkCombines multiple checks
Domain RegistrationVariablePer domain/year.com ~12/year,.io 12/year, .io ~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/month

Cost 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 FREE

2. 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/month

3. 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 check

4. 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 localization

Integration with Other Services

AWS ServiceHow It IntegratesTypical Use Case
Application Load Balancer (ALB)ALIAS record points to ALB DNSmyapp.com → ALB distributes to EC2 instances
CloudFrontALIAS record points to CloudFront distributionGlobal CDN with custom domain (cdn.myapp.com)
S3 Static WebsiteALIAS record points to S3 website endpointStatic hosting (www.myapp.com → S3 bucket)
API GatewayALIAS record points to API Gateway custom domainapi.myapp.com → Lambda functions via API Gateway
Elastic BeanstalkALIAS record points to EB environmentSimplified PaaS deployment with custom domain
CloudWatchHealth checks based on CloudWatch AlarmsFailover if custom metric (DB connections) is critical
ACM (Certificate Manager)DNS validation for HTTPS certificatesValidate domain ownership for SSL/TLS certs
VPCPrivate Hosted Zones only accessible from VPCInternal DNS for RDS, ElastiCache (db.internal)
EC2A/AAAA records point to Elastic IPsStatic IP for specific instance
LambdaHealth checks triggered by LambdaCustom logic to determine health (check external API)
SNSCloudWatch Alarms when health check failsNotifications when failover occurs
RDSCNAME record points to RDS endpointdb-primary.myapp.com → RDS instance
Auto ScalingALIAS to ALB that distributes to ASGAutomatic scaling with fixed domain
Global AcceleratorALIAS record points to acceleratorAnycast IPs for ultra-low latency global
CloudFormation/TerraformIaC manages Hosted Zones and recordsInfrastructure as code, version control

Additional Resources

Official AWS Documentation

Whitepapers and Best Practices

Hands-On Tutorials