DNS is the first thing that breaks and the last thing you check. Understanding it properly saves hours of debugging “it works on my machine.”
Record Types You’ll Actually Use# A and AAAA# Point domain to IP address:
e e x x a a m m p p l l e e . . c c o o m m . . A A A A A 9 2 3 6 . 0 1 6 8 : 4 2 . 8 2 0 1 0 6 : . 2 3 2 4 0 : 1 : 2 4 8 : 1 8 9 3 : 2 5 c 8 : 1 9 4 6
CNAME# Alias to another domain:
w a w p w i . . e e x x a a m m p p l l e e . . c c o o m m . . C C N N A A M M E E e a x p a i m - p l l b e - . 1 c 2 o 3 m . . u s - e a s t - 1 . e l b . a m a z o n a w s . c o m .
Cannot be used at zone apex (root domain). Use ALIAS/ANAME instead.
ALIAS / ANAME (Provider-specific)# CNAME-like behavior at zone apex:
# e # e x x R a C a o m l m u p o p t l u l e e d e . f . 5 c l c 3 o a o m r m A . e . l i C a N s A M A E C L N I f A A l M S a E t t e d n e 1 i x 2 n a 3 g m . p c l l e o . u n d e f t r l o i n f t y . . n a e p t p . . ( f l a t t e n e d t o A )
Mail servers:
e e x x a a m m p p l l e e . . c c o o m m . . M M X X 1 2 0 0 m m a a i i l l 1 2 . . e e x x a a m m p p l l e e . . c c o o m m . .
Lower priority number = preferred.
TXT# Verification and policies:
# e # s # e _ x e x a S a D l D a c P m K e o m m F p I c m p e l M t a l - ( e o i e c e . r n . h m c . c a a o _ v o l i m d e m l l . o r . e m i n a a f g u i i e t n c . h k a e e T e t T x n X y i X a t T . o T m i e n p c x l a a e t " m " . i v p g c o = l o o n s e o m ) p . g . f c l 1 o e m - i . s T n i X c t T l e u T - d X v e T e " : r L _ i E s f T p " i _ f v c E . = a N g D t C o K i R o I o Y g M n P l 1 = T e ; a _ . b V c k c A o = 1 L m r 2 I s 3 D ~ a " A a ; T l I l p O " = N M _ I T G O f K . E . N . " "
SRV# Service discovery:
_ # h t P t r p i . o _ r t i c t p y . e W x e a i m g p h l t e . P c o o r m t . T a r g S e R t V 1 0 5 8 0 w w w . e x a m p l e . c o m .
Used by some protocols (SIP, XMPP, Minecraft).
CAA# Certificate Authority Authorization:
e e e x x x a a a m m m p p p l l l e e e . . . c c c o o o m m m . . . C C C A A A A A A 0 0 0 i i i s s o s s d u u e e e f w " i " l l m e d a t i s " l e l t n e o c t : r s s y e e p n c t c u . r r o y i r p t g t y " . @ o e r x g a " m p l e . c o m "
Only listed CAs can issue certificates for your domain.
TTL Strategy# Time To Live determines caching duration:
# e # a # o x p l L a S i V d o m h . e . n p o e r e g l r x y x e t a a T . m s m T c T p h p L o T l o l m L e r e ( . . t . 1 ( c c 5 o T o d m T m a m . L . y i ) n ( ) 1 - - m s i t 8 r 3 n 6 a 6 e 0 ) 0 b 4 c 0 l 0 o - e 0 r d d r s u e r c A y C i C o o N n N r u A g A d M M s m E m E i i g g 9 h a r n 3 t p a e . i t w 1 c - i . 8 h l o e 4 a b n x . n . a 2 g a m 1 e w p 6 s l . . e 3 c . 4 o c m o . m .
TTL Best Practices# Before a migration:
Lower TTL to 5 minutes (24-48 hours ahead) Wait for old TTL to expire Make the change Verify propagation Raise TTL back to normal 1
2
3
4
5
# Check current TTL
dig example.com +noall +answer
# Monitor propagation
watch -n 30 "dig @8.8.8.8 example.com +short"
Route 53 Patterns# Simple Routing# Basic DNS without health checks:
1
2
3
4
5
6
7
resource "aws_route53_record" "www" {
zone_id = aws_route53_zone . main . zone_id
name = "www.example.com"
type = "A"
ttl = 300
records = [ "93.184.216.34" ]
}
Weighted Routing# Distribute traffic by percentage:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
resource "aws_route53_record" "api_blue" {
zone_id = aws_route53_zone . main . zone_id
name = "api.example.com"
type = "A"
set_identifier = "blue"
weighted_routing_policy {
weight = 90
}
alias {
name = aws_lb . blue . dns_name
zone_id = aws_lb . blue . zone_id
}
}
resource "aws_route53_record" "api_green" {
zone_id = aws_route53_zone . main . zone_id
name = "api.example.com"
type = "A"
set_identifier = "green"
weighted_routing_policy {
weight = 10 # Canary: 10% of traffic
}
alias {
name = aws_lb . green . dns_name
zone_id = aws_lb . green . zone_id
}
}
Failover Routing# Automatic failover with health checks:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
resource "aws_route53_health_check" "primary" {
fqdn = "primary.example.com"
port = 443
type = "HTTPS"
resource_path = "/health"
failure_threshold = 3
request_interval = 30
}
resource "aws_route53_record" "api_primary" {
zone_id = aws_route53_zone . main . zone_id
name = "api.example.com"
type = "A"
set_identifier = "primary"
failover_routing_policy {
type = "PRIMARY"
}
health_check_id = aws_route53_health_check . primary . id
alias {
name = aws_lb . primary . dns_name
zone_id = aws_lb . primary . zone_id
}
}
resource "aws_route53_record" "api_secondary" {
zone_id = aws_route53_zone . main . zone_id
name = "api.example.com"
type = "A"
set_identifier = "secondary"
failover_routing_policy {
type = "SECONDARY"
}
alias {
name = aws_lb . secondary . dns_name
zone_id = aws_lb . secondary . zone_id
}
}
Latency-Based Routing# Route to nearest region:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
resource "aws_route53_record" "api_us" {
zone_id = aws_route53_zone . main . zone_id
name = "api.example.com"
type = "A"
set_identifier = "us-east-1"
latency_routing_policy {
region = "us-east-1"
}
alias {
name = aws_lb . us_east . dns_name
zone_id = aws_lb . us_east . zone_id
}
}
resource "aws_route53_record" "api_eu" {
zone_id = aws_route53_zone . main . zone_id
name = "api.example.com"
type = "A"
set_identifier = "eu-west-1"
latency_routing_policy {
region = "eu-west-1"
}
alias {
name = aws_lb . eu_west . dns_name
zone_id = aws_lb . eu_west . zone_id
}
}
Internal DNS# Private Hosted Zones# DNS for internal services:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
resource "aws_route53_zone" "internal" {
name = "internal.example.com"
vpc {
vpc_id = aws_vpc . main . id
}
}
resource "aws_route53_record" "database" {
zone_id = aws_route53_zone . internal . zone_id
name = "db.internal.example.com"
type = "A"
ttl = 60
records = [ aws_db_instance . main . address ]
}
Service Discovery# Kubernetes internal DNS:
# c c u u P r r o l l d h h c t t a t t n p p : : r / e / a a a c p p h i i - - s s s e e e r r r v v v i i i c c c e e e s . d b e # y f a S n u a a l m m t e e . s n v a c m . e c s l p u a s c t e e r s . h l o o r c t a h l a n d AWS Cloud Map for ECS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
resource "aws_service_discovery_private_dns_namespace" "internal" {
name = "internal.local"
vpc = aws_vpc . main . id
}
resource "aws_service_discovery_service" "api" {
name = "api"
dns_config {
namespace_id = aws_service_discovery_private_dns_namespace . internal . id
dns_records {
ttl = 10
type = "A"
}
}
}
Debugging DNS# dig# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Basic lookup
dig example.com
# Specific record type
dig example.com MX
# Use specific DNS server
dig @8.8.8.8 example.com
# Trace resolution path
dig +trace example.com
# Short output
dig example.com +short
Common Issues# Negative caching:
1
2
3
4
5
# Check for NXDOMAIN caching
dig nonexistent.example.com
# SOA MINIMUM field controls negative TTL
dig example.com SOA
CNAME chain too long:
1
2
3
4
# Follow CNAME chain
dig www.example.com +trace
# Most resolvers limit to 8-10 hops
Propagation delays:
1
2
3
4
5
# Check multiple DNS servers
for ns in 8.8.8.8 1.1.1.1 208.67.222.222; do
echo "=== $ns ==="
dig @$ns example.com +short
done
Security# DNSSEC# Cryptographic signatures prevent DNS spoofing:
1
2
3
4
5
# Check DNSSEC status
dig example.com +dnssec
# Verify chain of trust
delv example.com
Route 53 supports DNSSEC signing for public zones.
DNS over HTTPS/TLS# Encrypt DNS queries:
1
2
3
# DoH query
curl -H 'accept: application/dns-json' \
'https://cloudflare-dns.com/dns-query?name=example.com&type=A'
Quick Reference# Record Purpose Example A IPv4 address 93.184.216.34AAAA IPv6 address 2606:2800:...CNAME Alias (not at apex) www → example.comMX Mail server 10 mail.example.comTXT Text data SPF, DKIM, verification CAA CA authorization issue "letsencrypt.org"SRV Service location _http._tcp...
Checklist# DNS problems look like everything-else problems. When debugging connectivity, check DNS first—it’s usually the culprit.