Filter concepts by levelShowing all levels.

AWS · Section 10

DNS and Network Connectivity

Level
intermediate
Read
30 min
Concepts
5

DNS decides which answer a name resolves to, and that answer still needs a real network path to be reachable. This section covers the Route 53 vocabulary (hosted zones, alias records, TTL), how public and private hosted zones can answer the same name differently, what each routing policy actually decides on, how the VPC Resolver and Resolver endpoints extend resolution to on-premises DNS, and the four ways to connect networks together — VPC peering, Transit Gateway, VPN, and Direct Connect — each appropriate at a different scale.

What is true here

  1. An alias record is a Route 53-specific A/AAAA record that works at the zone apex, costs nothing extra for AWS targets, and manages its own TTL.
  2. A private hosted zone only answers DNS queries from its explicitly associated VPCs — the same name can resolve differently publicly, by design.
  3. Each routing policy decides on a different signal: weighted uses a proportion, latency-based uses measured speed, failover uses health checks, geolocation uses the querier's location.
  4. The built-in VPC Resolver (at the CIDR base + 2) handles public DNS and this VPC's private hosted zones automatically — Resolver endpoints extend that to on-premises DNS.
  5. VPC peering is a direct, non-transitive link between exactly two VPCs — Transit Gateway is the hub that replaces a growing mesh of peering connections at scale.

What you will be able to do

  • Explain why an alias record works at a zone apex when a CNAME cannot
  • Predict which of a public and a private hosted zone answers a given query
  • Choose the correct routing policy for a stated requirement (canary split, lowest latency, active/passive failover, geo-targeted content)
  • Explain what extending DNS resolution to an on-premises network actually requires
  • Choose between VPC peering, Transit Gateway, VPN, and Direct Connect for a given connectivity requirement
From a name to a reachable answer
record setanswerresolved bytargetstill needs

Hosted zone

public or private

Routing policy picks an answer

VPC Resolver / hybrid DNS

Network actually reaches it

peering, Transit Gateway, VPN, Direct Connect

  • Hosted zone — public or private
    • leads to Routing policy picks an answer (record set)
  • Routing policy picks an answer
    • leads to VPC Resolver / hybrid DNS (answer resolved by)
  • VPC Resolver / hybrid DNS
    • leads to Network actually reaches it (target still needs)
  • Network actually reaches it — peering, Transit Gateway, VPN, Direct Connect

DNS and Network Connectivity

Route 53 vocabulary, public vs private zones, routing policies, hybrid DNS resolution, and the four network connectivity models.

Route 53 vocabulary: zones, records, and TTL

coreintermediate

A hosted zone holds the DNS records for a domain. An alias record is Route 53's own extension that points directly at an AWS resource (like a load balancer) without the extra lookup a CNAME needs — and unlike a CNAME, an alias record can be used at a zone apex.

Think of it as

A phone book (hosted zone) full of entries (records) — most entries list a number directly, but an "alias" entry is a special AWS shortcut that always looks up the current number for a resource that might change it, at no extra cost per lookup.

text
example.com  →  ALIAS  →  my-alb-1234.eu-west-1.elb.amazonaws.com   (apex, free, auto TTL)
www.example.com → CNAME → example.herokuapp.com   (not apex, standard billing)

What we're doing: Compare an alias record to a CNAME for the exact same target, at the zone apex.

alias-record.jsonjson
{
  "Name": "example.com",
  "Type": "A",
  "AliasTarget": {
    "HostedZoneId": "Z32O12XQLNTSW2",
    "DNSName": "my-alb-1234.eu-west-1.elb.amazonaws.com",
    "EvaluateTargetHealth": true
  }
}
3
Type A, not CNAME — an alias record is technically an A/AAAA record with an AliasTarget, which is exactly what makes apex usage legal.
5
EvaluateTargetHealth ties this record's answer to the load balancer's own health, without a separate Route 53 health check needed for this common case.

Why this works: A CNAME at "example.com" (no subdomain) violates the DNS specification, because a zone apex must also be able to hold other record types like MX — an alias record sidesteps that limit entirely by being a specially-flagged A record instead.

Trying to create a CNAME record at the zone apex

Wrong

text
# CNAME  example.com  →  my-alb-1234.eu-west-1.elb.amazonaws.com

Better

text
# ALIAS (A record)  example.com  →  my-alb-1234.eu-west-1.elb.amazonaws.com

What you see: Route 53 rejects the record creation, or (outside Route 53) other DNS providers accept it and then produce unpredictable resolution behavior.

Why: The DNS specification does not allow a CNAME to coexist with other records at the same name, and a zone apex almost always needs other records (like MX for mail) — Route 53's alias record exists specifically to give apex domains a way to point at AWS resources without this conflict.

Alias record vs CNAME, at the zone apex

Alias record

  • +Works at the zone apex (example.com)
  • +Free for AWS resource targets
  • +TTL managed automatically

CNAME

  • Cannot be used at the zone apex
  • Standard query charge
  • TTL set explicitly by you
  • Alias record
    • Works at the zone apex (example.com)
    • Free for AWS resource targets
    • TTL managed automatically
  • CNAME
    • Cannot be used at the zone apex
    • Standard query charge
    • TTL set explicitly by you

Alias record vs CNAME

Alias record vs CNAME
PropertyAlias recordCNAME
Works at zone apex (example.com)YesNo — DNS spec disallows it
Query chargeFree for AWS resource targetsStandard query charge
TargetAWS resources (ALB, CloudFront, S3, ...)Any hostname
TTLManaged automatically by Route 53Set explicitly by you

Together

bash
aws route53 change-resource-record-sets --hosted-zone-id Z123 --change-batch file://alias.json

Remember: An alias record is a Route 53-specific A/AAAA record that works at the zone apex, costs nothing extra for AWS targets, and manages its own TTL — a CNAME cannot do any of those three things.

See also: public vs private hosted zones · routing policies

Public vs private hosted zones

standardintermediate

A public hosted zone answers DNS queries from anywhere on the internet. A private hosted zone only answers queries from the VPCs it is explicitly associated with — the same domain name can resolve differently inside a VPC than it does publicly.

Think of it as

An internal company directory that only works from inside the office network, versus the public phone book anyone can look up — both can have an entry for "reception," and they can point to different numbers.

bash
aws route53 create-hosted-zone --name internal.example.com \
  --vpc VPCRegion=eu-west-1,VPCId=vpc-0abc123 --hosted-zone-config PrivateZone=true

What we're doing: See the same domain name resolve differently depending on whether the query comes from inside the associated VPC or from the public internet.

split-horizon.txttext
# From inside the associated VPC
$ dig db.internal.example.com
db.internal.example.com. 300 IN A 10.0.4.12   # private hosted zone answer

# From the public internet
$ dig db.internal.example.com
;; connection timed out; no servers could be reached   # not publicly resolvable at all
2
Only the VPC associated with the private hosted zone can resolve this name at all.
5
From outside that VPC, the name simply does not resolve — there is no public record for it, by design.

Why this works: This is exactly the intended behavior for internal service names — a private hosted zone never leaks internal naming or addressing to the public internet, because it structurally cannot answer queries from outside its associated VPCs.

Expecting a private hosted zone record to resolve outside its associated VPC

Wrong

text
# "The record exists in Route 53 — why can't my laptop resolve it?"

Better

text
# A private hosted zone only answers queries originating from its
# associated VPC(s) — resolve it from within that VPC, or make the zone public

What you see: A DNS name that works fine for services inside the VPC returns NXDOMAIN or times out from anywhere else, including a developer's laptop.

Why: A private hosted zone is not a smaller, restricted version of a public one — it is architecturally only reachable through the Amazon-provided DNS resolver inside its associated VPCs. There is no public path to it at all, by design.

Remember: A private hosted zone only answers queries from its explicitly associated VPCs — the same domain can have a public zone and a private zone resolving to different answers, entirely by design.

See also: route53 vocabulary · resolver and private dns

Route 53 routing policies

coreintermediate

A routing policy decides which of possibly several records Route 53 hands back for the same name — simple returns the one it has, and the others each pick based on a different signal: proportion, latency, health, or the querier's location.

Think of it as

A receptionist who, when asked for "the support line," gives out one of several numbers based on a rule they were told to follow — always the same one, split evenly by a coin flip, whichever office is closest, or whichever office answered a health check most recently.

text
Same name, multiple records, each tagged with a routing policy + SetIdentifier → Route 53 picks one to answer with

What we're doing: See a weighted routing setup for a canary release: 90% of traffic to the stable version, 10% to the new one.

weighted-canary.jsonjson
[
  { "Name": "api.example.com", "SetIdentifier": "stable",
    "Weight": 90, "AliasTarget": { "DNSName": "stable-alb..." } },
  { "Name": "api.example.com", "SetIdentifier": "canary",
    "Weight": 10, "AliasTarget": { "DNSName": "canary-alb..." } }
]
3
Weight 90 out of a total of 100 (90+10) — roughly 90% of queries resolve to the stable target.
6
The remaining 10% resolve to the canary target — enough real traffic to validate it without risking the majority.

Why this works: Weighted routing works at the DNS layer, before any request reaches either target — a client that resolves the canary answer sends 100% of its own traffic there for as long as that answer is cached (its TTL), which is why canary rollouts often pair a short TTL with weighted routing.

Choosing latency-based routing to solve a failover requirement

Wrong

text
# "We want to fail over to the backup Region if the primary goes down — use latency-based routing."

Better

text
# Use failover routing — health-check-driven, specifically designed for
# active/passive failover, not latency optimization

What you see: Traffic still routes to the primary Region's unhealthy endpoint, because latency-based routing has no concept of health at all — only measured network latency.

Why: Latency-based routing answers "which Region is fastest," not "which Region is healthy" — the two questions look related but are answered by entirely different signals. Failover routing is the policy actually built around health check status.

What signal each policy answers on
Simple
a single fixed answer
Weighted
a proportion you assign
Latency-based
measured latency to each Region
Geolocation
the querier's location
Failover
health check status
  • Simple: fixed rule, no health awareness — a single fixed answer
  • Weighted: fixed rule, no health awareness — a proportion you assign
  • Latency-based: reacts to live signal, no health awareness — measured latency to each Region
  • Geolocation: between fixed rule and reacts to live signal, health/location aware — the querier's location
  • Failover: reacts to live signal, health/location aware — health check status

Route 53 routing policies and what decides the answer

Route 53 routing policies and what decides the answer
PolicyDecided by
SimpleNothing — a single fixed answer
WeightedA proportion you assign per record
Latency-basedMeasured latency from the querier to each Region
FailoverHealth check status — passive record only answers if primary is unhealthy
GeolocationThe querier's geographic location
Multivalue answerRandom selection among up to 8 healthy records

Together

json
{ "SetIdentifier": "canary", "Weight": 10, "AliasTarget": { "DNSName": "new-alb..." } }

Remember: Each routing policy answers a different question — simple has nothing to decide, weighted uses a proportion, latency-based uses measured speed, failover uses health, geolocation uses the querier's location.

See also: route53 vocabulary · public vs private hosted zones

Route 53 Resolver and private DNS

standardintermediate

Every VPC has a built-in Resolver (at the base of the VPC's CIDR range plus two) that answers DNS queries for both public names and any private hosted zones associated with that VPC — Resolver endpoints extend that same resolution to and from on-premises networks.

Think of it as

A single internal switchboard operator who already knows both the public phone book and the office's internal extensions — and, with an added line installed (a Resolver endpoint), can also route calls to and from a partner office's switchboard.

text
VPC 10.0.0.0/16 → Resolver at 10.0.0.2
Outbound endpoint: *.corp.internal → forwarded to on-prem DNS server
Inbound endpoint:  on-prem → can query *.internal.example.com in this VPC

What we're doing: See a conditional forwarding rule that sends only a specific domain's queries on-premises, letting everything else resolve normally through the VPC Resolver.

forwarding-rule.jsonjson
{
  "DomainName": "corp.internal.",
  "TargetIps": [{ "Ip": "192.0.2.10", "Port": 53 }],
  "RuleType": "FORWARD"
}
2
This rule only applies to queries for corp.internal and its subdomains — every other query keeps using the VPC Resolver's normal path.
3
The matching queries are forwarded to a specific on-premises DNS server IP, reached over Direct Connect or VPN.

Why this works: Conditional forwarding scopes hybrid DNS to exactly the domains that need it, rather than routing every query through the on-premises link — public AWS service names and any private hosted zone records keep resolving locally through the VPC Resolver, unaffected.

Assuming the VPC Resolver automatically knows about an on-premises DNS zone

Wrong

text
# "Our EC2 instances can't resolve names from the on-prem Active Directory domain."

Better

text
# The VPC Resolver only knows public DNS and this VPC's private hosted
# zones — an outbound Resolver endpoint + forwarding rule is required for on-prem names

What you see: Instances in the VPC can resolve every AWS and public name correctly but get NXDOMAIN for anything in the company's on-premises DNS domain.

Why: The built-in VPC Resolver has no knowledge of DNS zones outside AWS by default — an outbound Resolver endpoint paired with a conditional forwarding rule is what explicitly extends resolution to an on-premises DNS server over Direct Connect or VPN.

Remember: The VPC Resolver (at CIDR base + 2) handles public DNS and this VPC's private hosted zones automatically — Resolver endpoints and conditional forwarding rules are what extend resolution to and from on-premises DNS.

See also: public vs private hosted zones · connectivity models

VPC peering, Transit Gateway, VPN, and Direct Connect

coreintermediate

These four connect networks together, but at different scales: peering is one VPC to another, Transit Gateway is a hub for many VPCs and on-prem links at once, VPN goes over the public internet, and Direct Connect is a dedicated private line to AWS.

Think of it as

Peering is a direct phone line between two offices. Transit Gateway is a company-wide switchboard everyone plugs into once. VPN is a phone call over the public phone network, encrypted. Direct Connect is a private leased line straight to the building.

text
2-3 VPCs, simple    → VPC peering
Many VPCs + on-prem  → Transit Gateway
Quick, over internet → Site-to-Site VPN
Dedicated, low-latency, high-bandwidth → Direct Connect

What we're doing: See why peering does not scale the way a hub does, once a third VPC joins.

peering-vs-hub.txttext
# 3 VPCs, fully connected via peering — needs 3 separate connections
vpc-a <-peer-> vpc-b
vpc-a <-peer-> vpc-c
vpc-b <-peer-> vpc-c

# 3 VPCs via Transit Gateway — needs 3 attachments, not 3 connections,
# and a 4th VPC needs only 1 more attachment, not 3 more peering links
vpc-a, vpc-b, vpc-c → attached to tgw-0xyz
2
Peering is pairwise — vpc-a and vpc-c need their own direct connection even though both already peer with vpc-b.
8
Every VPC attaches to the same hub once — the number of connections needed grows linearly with VPC count, not quadratically.

Why this works: Peering's non-transitivity is fine for two or three VPCs but becomes an operational burden past that — Transit Gateway exists specifically to replace a growing mesh of pairwise peering connections with one hub every network attaches to exactly once.

Assuming peering is transitive

Wrong

text
# vpc-a peers with vpc-b; vpc-b peers with vpc-c
# "so vpc-a should be able to reach vpc-c through vpc-b"

Better

text
# vpc-a needs its own direct peering connection to vpc-c —
# or all three should attach to a Transit Gateway instead

What you see: Traffic from vpc-a to vpc-c fails even though both are separately peered with vpc-b, with no error explaining why.

Why: VPC peering is explicitly non-transitive — a route through an intermediate VPC is never established automatically, regardless of how many peering connections that intermediate VPC has. Reaching a third VPC always needs either its own direct peering connection or a hub like Transit Gateway.

Peering vs Transit Gateway at scale

VPC peering (few VPCs)

  • +Direct connection per pair
  • +Non-transitive — no hub
  • +N pairs of VPCs need up to N(N−1)/2 connections

Transit Gateway (many VPCs)

  • One hub, every VPC attaches once
  • Transitive through the gateway
  • On-premises networks attach the same way
  • VPC peering (few VPCs)
    • Direct connection per pair
    • Non-transitive — no hub
    • N pairs of VPCs need up to N(N−1)/2 connections
  • Transit Gateway (many VPCs)
    • One hub, every VPC attaches once
    • Transitive through the gateway
    • On-premises networks attach the same way

Connectivity models and what they scale to

Connectivity models and what they scale to
ModelConnectsTransitive?
VPC peeringExactly two VPCsNo — each pair needs its own peering connection
Transit GatewayMany VPCs + on-prem, one hubYes — through the gateway
Site-to-Site VPNAWS to on-premises, over the internetN/A — one connection to one on-prem network
Direct ConnectAWS to on-premises, dedicated private lineN/A — one physical/logical connection

Together

bash
aws ec2 create-vpc-peering-connection --vpc-id vpc-0a --peer-vpc-id vpc-0b

Remember: Peering is a direct, non-transitive link between exactly two VPCs — Transit Gateway is the hub that replaces a growing mesh of peering connections; VPN is quick and over the internet, Direct Connect is dedicated and private.

See also: resolver and private dns · non overlapping cidr design

Advertisement