Step 1-2: Client initiates DNS query to local resolver (typically ISP or configured DNS server like 8.8.8.8)
Step 3-4: Resolver performs recursive lookup starting with root servers, then TLD servers
Step 5-8: Authoritative server responds with actual IP address, response travels back through the chain
Caching: Each level caches responses based on TTL to reduce future query time
DNSSEC: Provides cryptographic validation to prevent DNS spoofing attacks
A Record: Maps domain name to IPv4 address (most common)
AAAA Record: Maps domain name to IPv6 address
CNAME Record: Creates alias pointing to another domain name
MX Record: Specifies mail servers with priority values
TXT Record: Stores text data for verification, SPF, DKIM policies
NS Record: Delegates subdomain to other name servers
PTR Record: Reverse DNS lookup (IP to domain name)
SRV Record: Specifies service location with port and priority
Hosted Zones: Container for DNS records for a domain
Public Hosted Zone: Responds to DNS queries from the internet
Private Hosted Zone: Responds to DNS queries from within associated VPCs
Health Checks: Monitor endpoint health for routing decisions
Traffic Policies: Complex routing configurations with visual editor
Resolver: Hybrid DNS solution connecting on-premises and AWS
Simple: Single resource record with one or more IP addresses
Weighted: Distribute traffic based on assigned weights (A/B testing, gradual deployments)
Latency-based: Route to resource with lowest latency from user's location
Failover: Active-passive failover with health check monitoring
Geolocation: Route based on user's geographic location
Multivalue: Return multiple IP addresses with health checks (simple load balancing)
Step 1: Create hosted zone first - this is the foundation
Step 2: Set up health checks before creating records that depend on them
Step 3: Create DNS records with appropriate routing policies
Step 4: For private zones, associate with VPCs
Step 5: Configure Route 53 Resolver for hybrid scenarios
Step 6: Implement complex traffic policies if needed
Step 7: Enable logging and monitoring
aws route53 create-hosted-zone \
--name "example.com" \
--caller-reference "$(date +%s)" \
--hosted-zone-config Comment="Public hosted zone for example.com",PrivateZone=false
--name: The domain name for the hosted zone (must be a valid DNS name)
--caller-reference: Unique string to prevent duplicate requests (using timestamp)
--hosted-zone-config: Additional configuration options
Comment: Description for the hosted zone (optional but recommended)
PrivateZone: Set to false for public zones, true for private zones
aws route53 create-hosted-zone \
--name "internal.company.com" \
--caller-reference "private-$(date +%s)" \
--vpc VPCRegion=us-east-1,VPCId=vpc-12345678 \
--hosted-zone-config Comment="Private hosted zone for internal services",PrivateZone=true
--vpc: Specifies the VPC to associate with this private hosted zone
VPCRegion: AWS region where the VPC is located
VPCId: The ID of the VPC to associate
PrivateZone=true: Makes this zone only accessible from associated VPCs
aws route53 create-health-check \
--caller-reference "health-check-$(date +%s)" \
--health-check-config Type=HTTP,ResourcePath="/health",FullyQualifiedDomainName="api.example.com",Port=80,RequestInterval=30,FailureThreshold=3 \
--cloud-watch-alarm-region us-east-1
Type: HTTP, HTTPS, HTTP_STR_MATCH, HTTPS_STR_MATCH, TCP, CALCULATED, CLOUDWATCH_METRIC
ResourcePath: Path to check on the target server
FullyQualifiedDomainName: Domain name or IP address to check
Port: Port number to connect to (80 for HTTP, 443 for HTTPS)
RequestInterval: 10 or 30 seconds between checks
FailureThreshold: Number of consecutive failures before marking unhealthy (1-10)
aws route53 change-resource-record-sets \
--hosted-zone-id Z123456789 \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "www.example.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "192.168.1.100"}]
}
}]
}'
Action: CREATE, UPSERT, or DELETE
Name: The DNS name for this record
Type: A, AAAA, CNAME, MX, TXT, NS, PTR, SRV
TTL: Time to live in seconds (how long to cache)
ResourceRecords: Array of values for this record
aws route53 change-resource-record-sets \
--hosted-zone-id Z123456789 \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "A",
"SetIdentifier": "server-a-70-percent",
"Weight": 70,
"TTL": 60,
"ResourceRecords": [{"Value": "192.168.1.100"}],
"HealthCheckId": "abc123def456"
}
}]
}'
SetIdentifier: Unique identifier for this record set
Weight: Relative weight (0-255), higher weight = more traffic
HealthCheckId: Optional health check to associate with this record
Lower TTL: Recommended for weighted routing to enable faster traffic shifts
aws route53 change-resource-record-sets \
--hosted-zone-id Z123456789 \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "A",
"SetIdentifier": "us-east-1-server",
"Region": "us-east-1",
"TTL": 60,
"ResourceRecords": [{"Value": "192.168.1.100"}],
"HealthCheckId": "abc123def456"
}
}]
}'
Region: AWS region where this resource is located
SetIdentifier: Unique identifier for this record in the latency set
Route 53 measures latency: From users to AWS regions and routes to lowest latency
aws route53 change-resource-record-sets \
--hosted-zone-id Z123456789 \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "api.example.com",
"Type": "A",
"SetIdentifier": "primary-server",
"Failover": "PRIMARY",
"TTL": 60,
"ResourceRecords": [{"Value": "192.168.1.100"}],
"HealthCheckId": "primary-health-check"
}
}]
}'
Failover: PRIMARY or SECONDARY
Primary must have health check: Required to determine when to failover
Secondary is optional health check: Can have health check for better reliability
Active-Passive setup: Traffic goes to primary unless unhealthy
aws route53 associate-vpc-with-hosted-zone \
--hosted-zone-id Z123456789 \
--vpc VPCRegion=us-west-2,VPCId=vpc-87654321 \
--comment "Adding additional VPC to private hosted zone"
--hosted-zone-id: ID of the private hosted zone
VPCRegion: Region of the VPC to associate
VPCId: ID of the VPC to associate
--comment: Optional description of this association
aws route53resolver create-resolver-endpoint \
--creator-request-id "inbound-$(date +%s)" \
--security-group-ids sg-12345678 \
--direction INBOUND \
--ip-addresses SubnetId=subnet-12345678,Ip=10.0.1.100 SubnetId=subnet-87654321,Ip=10.0.2.100 \
--name "Corporate-Inbound-Endpoint" \
--tags Key=Environment,Value=Production Key=Purpose,Value=HybridDNS
--direction INBOUND: Allows on-premises to query AWS DNS
--security-group-ids: Security groups allowing DNS traffic (port 53)
--ip-addresses: Minimum 2 IPs in different AZs for high availability
SubnetId: Subnet where the resolver endpoint IP will be placed
Ip: Optional specific IP address (must be in subnet range)
aws route53resolver create-resolver-endpoint \
--creator-request-id "outbound-$(date +%s)" \
--security-group-ids sg-12345678 \
--direction OUTBOUND \
--ip-addresses SubnetId=subnet-12345678 SubnetId=subnet-87654321 \
--name "Corporate-Outbound-Endpoint"
--direction OUTBOUND: Allows AWS resources to query on-premises DNS
Security groups: Must allow outbound DNS traffic to on-premises servers
High availability: Multiple AZs ensure continued operation during AZ failure
aws route53resolver create-resolver-rule \
--creator-request-id "rule-$(date +%s)" \
--rule-type FORWARD \
--domain-name "corp.company.com" \
--resolver-endpoint-id rslvr-out-abc123def456 \
--target-ips Ip=192.168.100.10,Port=53 Ip=192.168.100.11,Port=53 \
--name "Corporate-Domain-Forwarding"
--rule-type: FORWARD (to on-premises) or SYSTEM (use Route 53)
--domain-name: Domain to forward (can use wildcards like *.corp.company.com)
--resolver-endpoint-id: Outbound endpoint to use for forwarding
--target-ips: On-premises DNS servers (minimum 1, maximum 6)
Port: Usually 53, but can specify different ports if needed
aws route53resolver associate-resolver-rule \
--resolver-rule-id rslvr-rr-abc123def456 \
--vpc-id vpc-12345678 \
--name "Corp-Domain-Rule-Association"
--resolver-rule-id: ID of the rule to associate
--vpc-id: VPC where this rule should apply
Propagation: Rules can be shared across accounts and regions
Inbound Resolution: On-premises clients can resolve AWS private DNS names
Outbound Resolution: AWS resources can resolve on-premises DNS names
Conditional Forwarding: Each environment forwards specific domains to the other
Security: DNS traffic flows over VPN or Direct Connect
High Availability: Multiple resolver endpoints across AZs
aws route53 enable-hosted-zone-dnssec \
--hosted-zone-id Z123456789
Cryptographic signing: Route 53 automatically manages key generation and rotation
Chain of trust: Must configure DS records with parent zone
Validation: Clients can verify DNS responses haven't been tampered with
aws route53 create-query-logging-config \
--hosted-zone-id Z123456789 \
--cloud-watch-logs-log-group-arn "arn:aws:logs:us-east-1:123456789012:log-group:route53-queries"
CloudWatch integration: All DNS queries logged to CloudWatch Logs
Log format: Includes timestamp, query name, type, response code, edge location
Analysis: Can analyze patterns, detect anomalies, troubleshoot issues
aws route53domains register-domain \
--domain-name "newcompany.com" \
--duration-in-years 2 \
--auto-renew \
--admin-contact '{
"FirstName": "John",
"LastName": "Smith",
"ContactType": "PERSON",
"AddressLine1": "123 Main St",
"City": "Seattle",
"State": "WA",
"CountryCode": "US",
"ZipCode": "98101",
"PhoneNumber": "+1.2065551234",
"Email": "admin@newcompany.com"
}' \
--registrant-contact '{
"FirstName": "John",
"LastName": "Smith",
"ContactType": "PERSON",
"AddressLine1": "123 Main St",
"City": "Seattle",
"State": "WA",
"CountryCode": "US",
"ZipCode": "98101",
"PhoneNumber": "+1.2065551234",
"Email": "registrant@newcompany.com"
}' \
--tech-contact '{
"FirstName": "Jane",
"LastName": "Doe",
"ContactType": "PERSON",
"AddressLine1": "123 Main St",
"City": "Seattle",
"State": "WA",
"CountryCode": "US",
"ZipCode": "98101",
"PhoneNumber": "+1.2065551235",
"Email": "tech@newcompany.com"
}' \
--privacy-protect-admin-contact \
--privacy-protect-registrant-contact \
--privacy-protect-tech-contact
--duration-in-years: Registration period (1-10 years depending on TLD)
--auto-renew: Automatically renew before expiration
Contact types: PERSON, COMPANY, ASSOCIATION, PUBLIC_BODY, RESELLER
Privacy protection: Hides contact info from WHOIS lookups
Three contacts: Admin, Registrant, and Technical contacts (can be same person)
Multi-level routing: Combine different routing policies in a hierarchy
Geographic first: Route based on user location, then apply sub-policies
Weighted distribution: A/B testing or gradual rollouts within regions
Failover redundancy: Automatic failover when primary endpoints fail
Latency optimization: Route to closest available endpoint
aws route53 create-traffic-policy \
--name "Global-API-Distribution" \
--type A \
--document '{
"AWSPolicyFormatVersion": "2015-10-01",
"RecordType": "A",
"StartRule": "geolocation_rule",
"Rules": {
"geolocation_rule": {
"RuleType": "geolocation",
"Locations": [
{
"CountryCode": "US",
"Rule": "us_weighted_rule"
},
{
"CountryCode": "GB",
"Rule": "eu_failover_rule"
},
{
"IsDefault": true,
"Rule": "default_latency_rule"
}
]
},
"us_weighted_rule": {
"RuleType": "weighted",
"Items": [
{
"Weight": 70,
"EndPoint": {
"Type": "value",
"Value": "192.168.1.100"
}
},
{
"Weight": 30,
"EndPoint": {
"Type": "value",
"Value": "192.168.1.101"
}
}
]
}
}
}' \
--comment "Complex multi-region traffic distribution policy"
AWSPolicyFormatVersion: Policy format version (currently 2015-10-01)
StartRule: Entry point rule for traffic policy evaluation
Rules object: Contains all routing rules referenced in the policy
Nested policies: Rules can reference other rules for complex routing
EndPoint types: "value" (IP/domain), "rule" (reference to another rule)
Issue | Cause | Solution | AWS CLI Command |
---|---|---|---|
DNS not resolving | Name servers not configured | Update domain registrar NS records | aws route53 get-hosted-zone --id Z123456789 |
High DNS query latency | TTL too low | Increase TTL for stable records | aws route53 change-resource-record-sets |
Failover not working | Health check misconfigured | Verify health check settings | aws route53 get-health-check --health-check-id abc123 |
Private zone not resolving | VPC not associated | Associate VPC with hosted zone |
# Test DNS resolution
dig @8.8.8.8 example.com A
nslookup example.com 8.8.8.8
# Test specific Route 53 name servers
dig @ns-123.awsdns-12.com example.com A
# Test health check endpoint
curl -I http://api.example.com/health
# Trace DNS resolution path
dig +trace example.com A
aws cloudwatch put-metric-alarm \
--alarm-name "Route53-Health-Check-Failed" \
--alarm-description "Alert when health check fails" \
--metric-name "HealthCheckStatus" \
--namespace "AWS/Route53" \
--statistic "Minimum" \
--period 60 \
--threshold 1 \
--comparison-operator "LessThanThreshold" \
--dimensions Name=HealthCheckId,Value=abc123def456 \
--evaluation-periods 2 \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:dns-alerts"
HealthCheckStatus metric: 1 = healthy, 0 = unhealthy
LessThanThreshold 1: Triggers when health check fails
evaluation-periods 2: Must fail for 2 consecutive periods
alarm-actions: SNS topic to notify when alarm triggers
# Delete unused health checks
aws route53 list-health-checks --query 'HealthChecks[?Config.Disabled==`true`].Id' --output text
# Optimize TTL values to reduce query volume
aws route53 change-resource-record-sets \
--hosted-zone-id Z123456789 \
--change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "static.example.com",
"Type": "A",
"TTL": 86400,
"ResourceRecords": [{"Value": "192.168.1.100"}]
}
}]
}'