Amazon Route 53 and Amazon CloudFront together form the public-facing edge of every AWS workload, and on SOA-C02 they are the entire substance of Task Statement 5.2 — "Configure domains, DNS services, and content delivery." Where SAA-C03 asks you to select a routing policy at design time, SOA-C02 tests whether you can run the resulting Route 53 zone in production: a failover record that does not flip when the primary fails, a CNAME that someone tried to create at the zone apex, an example.com Alias that points at the wrong CloudFront distribution, a CloudFront distribution that keeps serving stale assets after the S3 bucket was updated, and an S3 static website that suddenly returns AccessDenied because the bucket policy was rewritten without the OAC principal. Route 53 DNS, CloudFront, and Content Delivery is the topic where every Domain 5 SOA scenario about traffic, latency, or DNS resolution lands.
This guide walks through Route 53 from the SysOps angle: hosted zone types, the Alias-vs-CNAME decision (and why the apex record forces the answer), each of the seven routing policies with the operational cue that distinguishes them, health checks (endpoint, calculated, CloudWatch alarm), Route 53 Resolver inbound and outbound endpoints for hybrid DNS, then into CloudFront — distributions and origins, OAC versus the deprecated OAI, cache behaviors and TTL, CloudFront Functions versus Lambda@Edge, price classes, cache invalidation, and S3 static website hosting wired up to a Route 53 Alias. You will also see the recurring SOA-C02 scenario shapes: traffic going to the wrong region after a failover (TTL trap), CloudFront serving stale content after an S3 update (cache invalidation), example.com apex pointing at CloudFront (Alias is mandatory), and OAI-versus-OAC migration.
Why Route 53 and CloudFront Sit at the Edge of SOA-C02
The official SOA-C02 Exam Guide v2.3 lists Task Statement 5.2 with exactly five skills: configure Route 53 hosted zones and records, implement Route 53 routing policies including geolocation and geoproximity, configure DNS via Route 53 Resolver, configure CloudFront and S3 origin access control (OAC), and configure S3 static website hosting. Every one of those skills maps to a service or feature covered in this guide. Domain 5 is worth 18 percent of the SOA-C02 score, and TS 5.2 carries roughly a third of that weight, putting Route 53 and CloudFront at 8 to 10 questions in a typical 65-question exam.
At the SysOps tier the lens is implementation and troubleshooting, not architectural selection. SAA-C03 asks "which Route 53 routing policy serves European users from the Frankfurt region?" SOA-C02 asks "the latency-based routing record points at the Frankfurt ALB but European users still hit the us-east-1 Origin — what changed?" The answer is rarely the routing policy itself; it is a stale TTL on a recursive resolver, a missing health check, a mismatched record set ID, an Alias pointing at the wrong target, or a CloudFront distribution caching the old endpoint. Route 53 and CloudFront topics plug into every later SOA-C02 conversation: ELB health checks and Multi-AZ failover (Domain 2), backup and disaster recovery cross-region failover (Domain 2.3), WAF and Shield attached to CloudFront (Domain 5.1), VPC Flow Logs and CloudFront access logs for troubleshooting (Domain 5.3), and CloudWatch alarms wired to Route 53 health checks for composite signals (Domain 1).
- Hosted zone: a Route 53 container of DNS records for a single domain (or subdomain). Public hosted zones serve internet queries; private hosted zones answer only inside associated VPCs.
- Record set: a single DNS record (name, type, value, TTL) within a hosted zone, optionally tagged with a routing policy and a health check.
- Alias record: a Route 53-specific record type that maps a name directly to a supported AWS resource (ALB, CloudFront, S3 website endpoint, API Gateway, another Route 53 record) without charging for the query and without the CNAME-at-apex restriction.
- Routing policy: the rule Route 53 uses to choose among multiple records with the same name and type — Simple, Weighted, Latency, Failover, Geolocation, Geoproximity, Multivalue.
- Health check: a Route 53-managed probe (endpoint, calculated, or CloudWatch alarm) that marks a target Healthy or Unhealthy and influences routing decisions.
- Route 53 Resolver: the AWS-managed recursive DNS resolver inside every VPC, plus optional inbound/outbound endpoints for hybrid DNS forwarding.
- CloudFront distribution: a globally deployed CDN configuration with one or more origins, cache behaviors, viewer/origin protocols, and TTL controls.
- Origin Access Control (OAC): the modern signed-request mechanism by which CloudFront proves its identity to an S3 origin so the bucket can deny everyone else; the successor to Origin Access Identity (OAI).
- Cache behavior: a path-pattern-keyed configuration block on a CloudFront distribution that controls how requests for matching paths are forwarded, cached, and protected.
- TTL (Time To Live): how long a DNS record or a CloudFront cache object remains valid before being re-fetched; default CloudFront TTL is 24 hours unless overridden by Cache-Control headers.
- Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html
白話文解釋 Route 53 DNS, CloudFront, and Content Delivery
DNS and CDN concepts can feel abstract until you anchor them with everyday systems. Three analogies cover the SOA-C02 surface area.
Analogy 1: DNS as the Phone Book of the Internet
Route 53 is the public phone book of the internet. A hosted zone is one phone-book entry section for a particular surname (example.com) — every record inside is a phone number for someone living at that address. An A record is the actual phone number (an IPv4 address). A CNAME is a forwarding note that says "for John's number, go look up Sarah's number first" — useful, but you cannot put the forwarding note at the family's main listing because the phone book reserves that spot for the actual number, not a redirection. An Alias record is Route 53's special "see also" pointer that reads other AWS resources directly without the apex-CNAME restriction — it occupies the same row a regular A record would, but resolves dynamically to whatever IP the underlying resource currently has. Routing policies are the operator's rules for deciding which number to give out when multiple are listed: Simple (always read the first one), Weighted (rotate by percentage), Latency (give the closest), Failover (only give the backup if the primary line is busy), Geolocation (use the caller's country), Geoproximity (use distance with bias), Multivalue (read up to eight at once and let the caller pick). Health checks are the operator periodically dialing each number to confirm it still rings — if it stops ringing, that number is removed from rotation.
Analogy 2: CloudFront as Neighborhood Franchise Stores
CloudFront is a fast-food franchise's neighborhood store network. The origin is the central commissary kitchen that prepares the master menu (your S3 bucket or ALB). The edge locations (over 600 globally) are the neighborhood franchise stores — when a customer walks in and orders a burger, the franchise checks its local fridge first; if it has the burger ready (cache hit), it serves immediately; if not (cache miss), it phones the commissary, gets the recipe, prepares it, stores a copy in the local fridge, then serves the customer. The TTL is the fridge expiry sticker — after 24 hours (the default) the franchise tosses the local copy and calls the commissary again on the next order. Cache invalidation is the headquarters emergency recall notice — "every store, immediately throw out all burgers, the meat is bad" — costly because every store now has to call back to the commissary on the next order. The OAC is the franchise badge — the commissary will only answer phone calls from stores that present the official badge, and rejects orders from random callers (preventing direct S3 bucket access). Cache behaviors are the per-menu-item rules — "burgers stay in the fridge 24 hours, but smoothies must be made fresh on every order" map to path patterns like /static/* (long TTL) and /api/* (zero TTL).
Analogy 3: Health Checks as the Daily Medical Checkup
A Route 53 health check is like a daily medical checkup scheduled with each of your servers. By default, the doctor (Route 53) calls the patient (your endpoint) every 30 seconds and asks "are you healthy?". After three failed calls in a row, the patient is marked unhealthy and removed from the family's emergency contact list (the DNS rotation). A fast health check runs every 10 seconds for an extra fee — useful when the patient has a critical condition that needs faster detection. A calculated health check is the family doctor's verdict that combines reports from up to 256 individual specialist doctors with a Boolean expression — "the family wedding is cancelled if both grandma and grandpa are unwell". A CloudWatch alarm health check is the lab-report-driven verdict — instead of phoning the patient, the doctor reads a CloudWatch alarm and reports unhealthy whenever the alarm is in ALARM state. The failover routing policy uses these verdicts: it always tries the primary patient first; only when the primary is marked unhealthy does it route to the secondary.
For SOA-C02, the phone book analogy is the most useful when a question mixes record types and routing policies — recall that the apex of the phone-book section cannot host a forwarding note (no CNAME at zone apex), only an actual number or Route 53's "see also" Alias. The franchise analogy is the cleanest when reasoning about CloudFront cache behavior and OAC — the franchise badge is the only way the commissary distinguishes legitimate stores from random callers. Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html
Route 53 Hosted Zones: Public vs Private
A hosted zone is the top-level container for DNS records for a domain name in Route 53. Every Route 53 deployment starts by deciding whether the zone is public, private, or both.
Public hosted zones
A public hosted zone answers DNS queries from the public internet. When you register example.com with Route 53 (or with another registrar and delegate the NS records to Route 53), Route 53 creates a public hosted zone with four authoritative name servers spread across distinct top-level domains. Every record you add — A, AAAA, CNAME, MX, TXT, SRV, NS, SOA, Alias — is resolvable globally.
Public hosted zones are billed at $0.50 per zone per month for the first 25 zones plus per-query charges, and a query budget that varies by record type (Alias to AWS resources is free; standard records cost per million queries). Operationally, the SysOps engineer configures records, attaches health checks, and rotates DNSSEC keys (Route 53 supports DNSSEC signing for public zones).
Private hosted zones
A private hosted zone answers DNS queries only from within VPCs that you explicitly associate with the zone. The same domain name example.com can have both a public hosted zone (visible to the internet) and a private hosted zone (visible only inside specified VPCs) — Route 53 calls this split-view DNS. Private zone queries originate at the Route 53 Resolver inside each VPC and never leave AWS.
Private hosted zones require two VPC settings to be enabled on every associated VPC: enableDnsSupport and enableDnsHostnames. Both default to true on the default VPC; new custom VPCs may need enableDnsHostnames enabled explicitly. Private zones also do not support DNSSEC signing (it is a public-internet feature).
Cross-account VPC association
A private hosted zone in account A can be associated with a VPC in account B. The two accounts authorize the association via route53:CreateVPCAssociationAuthorization (account A) followed by route53:AssociateVPCWithHostedZone (account B). This pattern is common in multi-account organizations where one networking account owns the private DNS namespace and shares it with workload accounts.
A common SOA-C02 pattern is "applications in our VPC must resolve db.example.com to a private RDS endpoint, but the public website must resolve www.example.com normally." The answer is two hosted zones — public for www, private for db — both named example.com. Route 53 Resolver inside the VPC always prefers the private zone for matching queries, while public users see only the public zone. Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-working-with.html
Record Types: A, AAAA, CNAME, and Alias
Route 53 supports the standard DNS record types plus its own Alias record. SOA-C02 most heavily tests the four below.
A and AAAA records
An A record maps a name to a single IPv4 address. An AAAA record maps a name to a single IPv6 address. Both are standard DNS records — clients receive them via any recursive resolver and cache them for the configured TTL. Use A and AAAA when the target has a fixed IP address (a customer-owned NLB Elastic IP, an on-prem server, a static EC2 instance behind a known EIP).
CNAME records
A CNAME (Canonical Name) record maps one DNS name to another DNS name. The classic use is www.example.com → cdn.cloudfront.net. Two operational rules govern CNAMEs and matter on every SOA-C02 attempt:
- A CNAME cannot coexist with any other record at the same name. If
www.example.comhas a CNAME, it cannot also have an A record or an MX record. - A CNAME cannot exist at the zone apex (the naked domain like
example.com). This is a hard DNS standard, not an AWS limitation. The apex must hold an SOA and NS record, and a CNAME at apex would conflict with them.
The second rule is what forces the Alias record to exist.
Alias records
An Alias record is Route 53's proprietary extension. It looks like an A or AAAA record to the client (the response is an actual IP address, not a redirection), but Route 53 looks up the IP dynamically against the target AWS resource at query time. Alias records have three properties that make them the SOA-C02 default answer for AWS-resource targets:
- Alias works at the zone apex. Because the response is an A record (or AAAA), it does not violate the no-CNAME-at-apex rule. This is the only legal way to point
example.com(naked domain) at a CloudFront distribution, ALB, S3 website endpoint, or another Route 53 record. - Alias queries to AWS resources are free. A standard CNAME query is billed per million; an Alias query to an AWS-supported target is free.
- Alias automatically tracks the resource's IPs. When ALB or CloudFront re-IPs, Route 53 updates the Alias resolution transparently — no zone edit needed.
Alias supported targets
Alias records can target:
- CloudFront distributions
- Application Load Balancers, Network Load Balancers, Gateway Load Balancers
- API Gateway custom domain names
- Elastic Beanstalk environments
- S3 buckets configured for static website hosting
- VPC interface endpoints
- Global Accelerator
- Another record set in the same hosted zone
Alias records cannot target arbitrary IP addresses, on-premises systems, or third-party SaaS endpoints — for those, use A/AAAA or CNAME.
This is the most-tested rule in TS 5.2. Whenever the SOA-C02 scenario says "point example.com (root/naked domain) at our CloudFront distribution / ALB / S3 website", the only correct answer is an Alias record. A CNAME at apex is invalid DNS. An A record at apex requires a static IP, but ALB and CloudFront have rotating IPs. Alias solves both problems. Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html
Alias vs CNAME decision matrix
| Situation | Alias | CNAME |
|---|---|---|
Pointing apex (example.com) at AWS resource |
YES (mandatory) | INVALID |
Pointing subdomain (www.example.com) at AWS resource |
YES (preferred — free queries) | Allowed, but pays per million |
| Pointing at non-AWS endpoint (third-party CDN) | NOT SUPPORTED | YES |
| Pointing at another record in same zone | YES | YES |
| Pointing at arbitrary IP | Use A record | Not applicable |
Routing Policies: Simple, Weighted, Latency, Failover, Geolocation, Geoproximity, Multivalue
Route 53 offers seven routing policies. SOA-C02 tests all seven, but the operational triggers are distinctive enough that you can pick the right one fast.
Simple routing
The default. One record, one set of values, no health checks. If you list multiple values in a single Simple record (multiple IPs in one A record), Route 53 returns all of them and the resolver picks one — no AWS-side decision logic. Use Simple for trivial DNS where intelligence is not needed.
Weighted routing
Multiple records with the same name and type, each tagged with a weight (0 to 255). Route 53 returns each record proportionally — weights of 80 and 20 distribute roughly 80/20. Setting a weight to 0 stops returning that record without deleting it.
Operational uses: blue/green deployments (start at 99/1, ramp to 50/50, ramp to 0/100), gradual region migrations, A/B testing.
Latency-based routing
Multiple records with the same name and type, each tagged with an AWS region. Route 53 returns the record whose region has the lowest measured latency from the resolver's location. Latency data comes from Amazon's continuously measured network telemetry, not from a per-query probe.
Operational uses: multi-region active-active deployments where every region has a healthy stack and the goal is to minimize user-perceived latency. Combine with health checks so a failed region drops out of the pool.
Failover routing
Two records — one tagged Primary, one tagged Secondary — both with the same name and type. Route 53 always returns the Primary unless its associated health check is failing, then returns the Secondary. The health check is mandatory on the Primary (without it, the policy has nothing to fail over from).
Operational uses: active-passive disaster recovery where the secondary is a warm-standby in another region or AZ. The classic SOA-C02 scenario is "the primary application is in us-east-1; if it fails, automatically route to us-west-2 disaster-recovery stack."
Geolocation routing
Multiple records, each tagged with a continent, country, or US state (and a special Default record). Route 53 returns the record matching the resolver's geographic location, falling back to Default if no match. Geolocation uses the resolver's IP, not the end-user's, so accuracy depends on resolver locations (good for ISP resolvers, less accurate for VPN users).
Operational uses: regulatory compliance (EU users must hit EU stack), licensing (only certain countries can stream a video catalog), language localization (Spain users go to a Spanish-content origin).
Geoproximity routing
Multiple records, each tagged with an AWS region or a literal latitude/longitude plus an optional bias between -99 and +99. Route 53 returns the record geographically closest to the resolver, but the bias expands or shrinks the geographic region the record covers. A positive bias makes the region "larger" (catch more users); a negative bias shrinks it. Geoproximity requires a Route 53 traffic flow policy (more advanced UI than basic routing).
Operational uses: active-active multi-region with manual traffic-shifting (move 10 percent of US-East users to US-West for capacity reasons by adjusting bias).
Multivalue answer routing
Up to eight records of the same name and type, each optionally with a health check. Route 53 returns the healthy records in random order on each query. Multivalue is not a load balancer (no SLA, no session affinity), but for simple round-robin DNS with health checking it is much cheaper than running an ELB.
Operational uses: small fleets behind public IPs where ELB is overkill, internal services in private hosted zones, sandbox environments.
- Simple — one target, no logic. Default for everyday DNS.
- Weighted — N targets, percentage split. Blue/green, A/B, gradual migration.
- Latency — N targets per region, lowest-latency wins. Multi-region active-active for performance.
- Failover — Primary + Secondary, health-check-driven. Active-passive DR.
- Geolocation — N targets per continent/country/state + Default. Regulatory or licensing.
- Geoproximity — N targets with bias slider. Manual traffic shifting.
- Multivalue — up to 8 healthy targets returned randomly. Cheap round-robin with health checks.
- Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html
A common SOA-C02 distractor: candidates assume Route 53 measures latency from each requesting resolver to each region at query time. It does not. Route 53 uses Amazon's pre-measured network latency dataset between user IP ranges and AWS regions, refreshed periodically. The implication: latency-based routing's accuracy depends on Amazon's coverage of the requesting resolver's IP range, and a brand-new resolver location may not be optimally classified for hours. For sub-minute precision use Global Accelerator instead. Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-latency.html
Route 53 Health Checks: Endpoint, Calculated, and CloudWatch Alarm
A health check is a Route 53-managed probe that returns a Healthy or Unhealthy verdict. Routing policies that consult health checks (Failover, Weighted, Latency, Multivalue, Geolocation, Geoproximity) drop unhealthy records from rotation.
Three health-check types
-
Endpoint health check — Route 53 itself sends HTTP, HTTPS, or TCP probes to a target IP or hostname from over a dozen global checker locations. Default interval is 30 seconds (standard); fast is 10 seconds for an additional fee. Default failure threshold is 3 consecutive failed probes before flipping to Unhealthy.
-
Calculated health check — combines the verdicts of up to 256 child health checks with a threshold rule (
X out of N must be healthy). Used for composite DR signals (the application is healthy only when both the web tier and the DB tier are healthy). -
CloudWatch alarm health check — the verdict is read from a CloudWatch alarm in the same account. Healthy when the alarm is OK or INSUFFICIENT_DATA, Unhealthy when in ALARM. This is the bridge between custom application telemetry (any CloudWatch metric) and Route 53 routing decisions.
Endpoint health check configuration knobs
- Protocol: HTTP, HTTPS, TCP. HTTPS verifies TLS handshake; HTTP/HTTPS can match a string in the response body.
- Port and path (HTTP/HTTPS): typically
/healthor/ping. - Interval: 30 (standard, free in tier) or 10 seconds (fast, paid).
- Failure threshold: 1–10 consecutive failures before unhealthy. Default 3.
- String matching: optional; the response body must contain a configured string.
- Latency graphs: visible in console; useful for detecting degradation before failure.
- SNI for HTTPS: required for endpoints behind virtual hosting or CloudFront.
- Invert health check status: useful for "expect this URL to be down".
- Disable health check: explicitly mark unhealthy (force failover for testing).
Health check intervals — the numbers to memorize
- Standard health check interval: 30 seconds (free tier eligible).
- Fast health check interval: 10 seconds (paid).
- Default failure threshold: 3 consecutive failures (configurable 1–10).
- Calculated health check children: up to 256.
- Health check checker locations: 15+ global vantage points (configurable subset).
- Default DNS TTL: 300 seconds (5 minutes) for new records — but no enforced default; you set it.
- Default CloudFront TTL: 86,400 seconds (24 hours) when origin sends no
Cache-Controlheader. - CloudFront minimum TTL: 0 seconds (no caching).
- CloudFront maximum TTL: 31,536,000 seconds (1 year).
- CloudFront edge locations: 600+ globally.
- Route 53 hosted zone limits: 500 hosted zones per account (soft); 10,000 records per zone (soft).
- Free invalidation paths: first 1,000 paths per month per AWS account.
- Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-types.html
A standard 30-second interval with the default 3-failure threshold means it takes 90 seconds of failure before Route 53 marks the endpoint unhealthy and starts the failover. Combined with a 60-second TTL, total user-visible failover time can exceed 2.5 minutes. For tighter recovery objectives, switch to fast (10-second) health checks with a 3-failure threshold (30 seconds) and a TTL of 60 seconds. This is a common SOA-C02 scenario: "the failover should complete within 60 seconds — what changes?" Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-creating-values.html
Health check best practices
- Health-check the right thing. A health check that hits
/index.htmldoes not test the backend database; build a/healthendpoint that returns 200 only when the application's critical dependencies all respond. - Use HTTPS health checks for TLS endpoints, not HTTP, because cert expiry is a real failure that HTTP probes miss.
- String matching lets you require a specific health-marker word in the body (e.g., the JSON response includes
"status":"OK"). - CloudWatch alarm health checks let you fail over on metrics that are not directly probe-able — RDS replica lag, SQS oldest message age, Lambda error rate.
- Calculated checks prevent single-component flapping; require 2 of 3 child checks to pass before declaring overall healthy.
Route 53 Resolver: Inbound and Outbound Endpoints for Hybrid DNS
The Route 53 Resolver is the recursive DNS resolver that already runs inside every VPC at the address VPC_CIDR_base + 2 (the +2 IP reserved by AWS). It answers all DNS queries originating in the VPC, including queries for private hosted zones associated with that VPC. For pure-AWS workloads no extra configuration is needed.
The interesting cases — and the cases SOA-C02 tests — are hybrid DNS, where on-premises systems and AWS systems must resolve names from each other's namespaces.
Inbound endpoints — on-prem queries AWS
A Route 53 Resolver inbound endpoint is a set of ENIs (one per AZ) inside your VPC, each with an IP address that on-premises DNS servers can forward queries to. Use case: an on-premises corporate DNS server has a forwarder rule "for any *.aws.example.com query, send it to the inbound endpoint IPs." Route 53 Resolver receives the query, looks it up in the appropriate private hosted zone (which is associated with the resolver's VPC), and returns the answer.
Inbound endpoints have a flat hourly cost per ENI plus per-query charge. Always provision at least two ENIs across two AZs for HA.
Outbound endpoints — AWS queries on-prem
A Route 53 Resolver outbound endpoint is a set of ENIs in your VPC from which Route 53 Resolver sends recursive queries forward to on-premises DNS servers. You also configure Resolver rules that pattern-match domain names and route matched queries to specified target IPs (the on-prem servers). Use case: applications in the VPC need to resolve corp.example.com (your on-prem Active Directory zone), so you create a forwarding rule "for *.corp.example.com, forward to 10.0.0.53 and 10.0.0.54" attached to an outbound endpoint.
Outbound endpoints also incur an hourly per-ENI cost plus per-query charge.
Resolver rules
Rules are reusable across VPCs and across accounts (shared via AWS RAM). Common patterns:
- System rules (built-in) for AWS-internal domains (
amazonaws.com,aws.amazon.com). - Forward rules that pattern-match a domain and forward to specified target IPs.
- Recursive rules that explicitly use Route 53 Resolver's own recursion (for autonomous internet lookups).
A common SOA-C02 confusion: candidates flip the names. Remember: Inbound receives queries into AWS from on-prem (on-prem is the client, AWS is the resolver). Outbound sends queries out of AWS to on-prem (AWS is the client, on-prem is the resolver). The inbound endpoint exposes IPs to on-prem; the outbound endpoint exposes ENIs to AWS but talks to on-prem IPs you configure as targets. If you need bidirectional hybrid DNS you need both. Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-getting-started.html
CloudFront Distribution Basics
A CloudFront distribution is the unit of CDN configuration: one distribution per public domain (or per *.example.com subdomain pattern), with one or more origins, one default cache behavior plus optional path-pattern behaviors, and a globally deployed presence at AWS edge locations.
Distribution types
- Web distribution (the only type as of the current console; the legacy "RTMP" type is retired). Serves HTTP/HTTPS content over HTTP/1.1, HTTP/2, and HTTP/3.
Anatomy of a request
- The viewer issues a DNS query for
cdn.example.comand gets a CloudFront edge location IP via Route 53 Alias. - The TCP/TLS connection terminates at the nearest CloudFront edge.
- CloudFront looks up the cache behavior matching the request path.
- If the object is in the edge cache and not expired (cache hit), CloudFront serves it.
- If not (cache miss), CloudFront forwards the request to the origin (S3, ALB, EC2, custom HTTP), receives the response, optionally caches it per the cache behavior's TTL, and returns it.
- Subsequent requests within the TTL window are served from the cache.
Distribution settings
- Alternate domain names (CNAMEs): the public hostnames the distribution responds to (e.g.,
www.example.com,cdn.example.com). Each CNAME requires a matching SSL certificate via ACM inus-east-1(CloudFront is global and reads ACM from N. Virginia). - SSL certificate: default
*.cloudfront.netcert, or custom ACM cert. - Default root object: e.g.,
index.htmlreturned for/requests when serving an SPA from S3. - Geographic restrictions: country allow-list or block-list at the distribution level.
- AWS WAF Web ACL: attached at the distribution level for L7 firewall rules.
- Logging: standard logs to S3, real-time logs to Kinesis Data Streams.
CloudFront Origins: S3, ALB, and Custom HTTP
A CloudFront distribution needs at least one origin. SOA-C02 tests the operational differences between S3, ALB, and custom HTTP origins.
S3 origin (REST endpoint)
The most common pattern: a CloudFront distribution in front of an S3 bucket holding static assets. The REST endpoint form (bucketname.s3.amazonaws.com) is the recommended choice for a CloudFront origin because it supports OAC and signed URLs natively. CloudFront forwards GET requests to S3, S3 returns the object, CloudFront caches per the cache behavior.
Crucially, the S3 bucket should not be public — instead, OAC ensures only CloudFront can read the bucket.
S3 origin (website endpoint)
The website endpoint form (bucketname.s3-website-us-east-1.amazonaws.com) is necessary only when you depend on S3 static-website features that the REST endpoint does not support: directory index documents (so /folder/ returns /folder/index.html), redirect rules, and custom error pages. The website endpoint does not support OAC — to lock it down to CloudFront-only you must rely on a Referer header secret in the bucket policy, which is weaker than OAC.
Application Load Balancer origin
For dynamic content (an EC2-hosted application, an ECS service behind an ALB), the ALB is the origin. The ALB is reached by its DNS name; the security group on the ALB's listener rules can restrict source IPs to the CloudFront managed prefix list (com.amazonaws.global.cloudfront.origin-facing) so that only CloudFront edge locations reach the ALB. Combined with a custom header that CloudFront injects (e.g., X-Custom-Origin-Verify: <secret>) and ALB listener rules that drop requests missing the header, you achieve OAC-equivalent protection.
Custom HTTP origin
Any HTTP/HTTPS endpoint reachable on the public internet — an EC2 instance with a public IP, an on-prem datacenter, a third-party API. Configuration mirrors the ALB pattern: protocol policy, port, path, custom headers.
On SOA-C02, when a question describes a CloudFront distribution in front of an S3 bucket of static assets, the canonical answer pairs the S3 REST endpoint origin with OAC and a bucket policy that grants s3:GetObject only to the CloudFront service principal scoped to the specific distribution ARN. The legacy answer pair (S3 website endpoint + OAI + bucket policy + Referer-header trick) is no longer the recommended pattern. Reference: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
OAC vs OAI for S3 Origin: The Modern Pattern
Origin Access Control (OAC) is the current AWS-recommended mechanism for restricting S3 origin access to CloudFront. Origin Access Identity (OAI) is the legacy mechanism, deprecated in favor of OAC since August 2022 — still supported for existing distributions but not recommended for new ones.
How OAC works
- You create an OAC resource in CloudFront (
OriginAccessControl) with a name, a signing protocol (SigV4 — AWS Signature Version 4), and a signing behavior (Always— always sign, recommended;Never— never sign; orNo-Override— sign unless viewer already provided one). - You attach the OAC to the S3 origin in the distribution's origin configuration.
- You update the S3 bucket policy to grant
s3:GetObject(and optionallys3:GetObjectVersion) to the CloudFront service principal (cloudfront.amazonaws.com) with a condition that matches the specific distribution ARN (AWS:SourceArn). - CloudFront signs every origin request to S3 with SigV4 using its own service-principal credentials, scoped to the specific OAC and distribution.
- S3 evaluates the bucket policy and authorizes only requests that match the configured CloudFront source ARN.
Why OAC over OAI
- OAC supports SSE-KMS-encrypted S3 objects. OAI cannot decrypt SSE-KMS objects without additional grants; OAC handles SigV4 signing including KMS context.
- OAC supports all AWS regions including opt-in regions. OAI lacks support in some newer regions.
- OAC supports HTTP methods beyond GET/HEAD (PUT, POST for upload-through-CloudFront patterns) — OAI is GET/HEAD only.
- OAC scoping is per-distribution via the
AWS:SourceArncondition; OAI scoping is via the OAI principal which is shared at the OAI-level (less precise).
Migration from OAI to OAC
The migration is straightforward:
- Create an OAC in the distribution.
- Attach the OAC to the S3 origin (the existing OAI can stay attached transiently if migrating gradually).
- Add a new statement to the S3 bucket policy granting access via the CloudFront service principal scoped to the distribution ARN.
- Test with a sample object — confirm CloudFront serves it through OAC.
- Remove the OAI principal statement from the S3 bucket policy.
- Detach and delete the OAI.
A common SOA-C02 distractor presents OAI as the answer for a "new CloudFront + S3" scenario. Since AWS introduced OAC in 2022, OAI is no longer the recommended pattern, and the exam updated to test OAC as the default. Recognize OAI in distractor options as a legacy pattern; the correct modern answer is OAC. Reference: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
Cache Behaviors and TTL
A cache behavior is a rule attached to a path pattern that controls how requests for matching paths are forwarded, cached, and modified. Every distribution has exactly one default cache behavior (*) plus zero or more path-specific behaviors. Behaviors are evaluated in order — the first matching path wins.
Behavior settings
- Path pattern: e.g.,
*.jpg,/images/*,/api/*,*(default). - Origin: which configured origin handles requests matching this path.
- Viewer protocol policy:
HTTP and HTTPS,Redirect HTTP to HTTPS,HTTPS Only. - Allowed HTTP methods:
GET, HEAD(cache-safe);GET, HEAD, OPTIONS;GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE. - Cache policy: a reusable policy that controls cache key (which request attributes form the cache key) and TTLs.
- Origin request policy: a reusable policy that controls which headers, cookies, and query strings CloudFront forwards to the origin (separate from what is part of the cache key).
- Response headers policy: appends/overwrites headers on responses (CORS, security headers).
- Function associations: CloudFront Functions or Lambda@Edge attached to the four trigger points.
TTLs and cache control
CloudFront's TTL behavior is governed by both the cache policy's MinTTL / DefaultTTL / MaxTTL and the origin's Cache-Control and Expires response headers:
- If the origin returns
Cache-Control: max-age=N, CloudFront uses N (clamped between MinTTL and MaxTTL). - If the origin returns no caching headers, CloudFront uses DefaultTTL (default 24 hours = 86,400 seconds in the AWS-managed
CachingOptimizedpolicy). Cache-Control: no-storeorno-cacheis honored — CloudFront does not cache.- Setting MinTTL = MaxTTL = DefaultTTL = 0 disables caching for that path entirely (useful for
/api/*paths).
Cache key composition
The cache key is what CloudFront uses to index the cached object. Two requests with the same cache key are served the same cached object. Cache key inclusion options:
- Query strings: none, all, or specific list.
- Headers: none, all, or specific list.
- Cookies: none, all, or specific list.
Including more attributes in the cache key fragments the cache (lower hit ratio) but allows variation; including fewer maximizes hit ratio but makes responses uniform.
Many SOA-C02 candidates assume CloudFront simply respects the origin's Cache-Control headers. It does — if the origin sends them. If the origin sends nothing, the default behavior is the cache policy's DefaultTTL, which in the AWS-managed CachingOptimized policy is 24 hours (86,400 seconds). When an S3 origin update appears not to propagate to viewers, the most common cause is the 24-hour default TTL on objects whose S3 metadata does not include Cache-Control. Fix: either set Cache-Control on S3 objects (aws s3 cp ... --cache-control "max-age=300"), use a cache policy with a shorter DefaultTTL, or invalidate. Reference: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cache-hit-ratio.html
Cache invalidations
A cache invalidation is an explicit "expire this object now" request issued against the distribution. You provide a path or path pattern (/index.html, /css/*, /* for everything). CloudFront propagates the invalidation to all edge locations within minutes; subsequent requests miss the cache and re-fetch from origin.
Invalidations cost money: the first 1,000 invalidation paths per month per AWS account are free; beyond that each path costs $0.005. A wildcard like /* counts as one path. SOA-C02 sometimes asks "is invalidation or short TTL the right answer for frequent-update content?" — the answer is short TTL (or versioned filenames like app.v123.js), because invalidating after every deploy is wasteful and slow.
The CloudFront-native pattern for frequently-updated assets is content-hashed filenames — main.a1b2c3.js — so every new deploy produces new filenames and the old cache entries simply age out. The HTML that references them gets invalidated (a small set of paths) but the bulky JS/CSS/image objects do not. This pattern is operationally cheaper, faster, and avoids the 1,000-free-paths limit. Reference: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
CloudFront Functions vs Lambda@Edge
CloudFront supports two compute options at the edge: CloudFront Functions and Lambda@Edge. They are not interchangeable; SOA-C02 tests the difference.
CloudFront Functions
Lightweight JavaScript that runs in a custom V8-based runtime at the edge location closest to the viewer. Constraints:
- JavaScript only (ECMAScript 5.1 + a small async subset).
- Sub-millisecond execution time typical, maximum 1 ms.
- No network access (cannot call other services, cannot read S3).
- Maximum memory ~2 MB.
- Runs on viewer-request and viewer-response triggers only.
- Free for first 2 million invocations per month, then $0.10 per million.
Use for: header rewriting, URL rewriting, A/B testing routing, simple authentication token validation, redirects.
Lambda@Edge
A standard Lambda function that runs at CloudFront regional edge caches (12 cache regions, not all 600+ edge locations). Constraints:
- Node.js or Python runtime.
- Up to 5 seconds for viewer-request/viewer-response, up to 30 seconds for origin-request/origin-response.
- Network access to AWS services and the internet.
- Up to 10,240 MB memory.
- Runs on all four triggers: viewer-request, origin-request, origin-response, viewer-response.
- Standard Lambda pricing plus a per-request fee.
Use for: complex logic requiring AWS API calls, dynamic responses requiring DynamoDB lookup, image manipulation, signed URL generation with secrets.
| Capability | CloudFront Functions | Lambda@Edge |
|---|---|---|
| Languages | JavaScript ES 5.1 | Node.js, Python |
| Max duration | 1 ms | 5–30 s |
| Network access | NO | YES |
| Memory | ~2 MB | up to 10,240 MB |
| Triggers | viewer-request, viewer-response | all four |
| Latency overhead | sub-millisecond | low milliseconds |
| Use for | header/URL rewrites, simple auth | DB lookup, image transform |
On SOA-C02, when the scenario describes "rewrite the URL or add a security header on every request", the answer is CloudFront Functions (cheaper, faster, no network). When the scenario requires looking up something from DynamoDB or signing an URL with a secret, the answer is Lambda@Edge (network required, longer execution allowed). Reference: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions.html
CloudFront Price Classes
CloudFront edge locations are organized into pricing tiers that reflect AWS's cost of operating the location. You can restrict your distribution to cheaper tiers if your audience is regional.
- Price Class All — uses every edge location worldwide. Default. Best performance, highest cost.
- Price Class 200 — excludes the most expensive South America, Africa, and Australia edges. Reasonable balance for global audiences excluding those regions.
- Price Class 100 — restricts to North America, Europe, and Israel. Cheapest. Use when audience is concentrated in those regions.
Restricting price class only changes which edges cache and serve the content. Viewers in excluded regions are still served — just from a more distant edge — so latency is higher for them. SOA-C02 tests this directly: "the application is used only by EU customers; minimize CloudFront cost without changing the public DNS." Answer: Price Class 100.
S3 Static Website Hosting
S3 can serve a static website directly via its website endpoint, which is a different URL from the REST endpoint and supports a few HTML-friendly features.
Enabling static website hosting
- Open the bucket → Properties → Static website hosting → Enable.
- Configure the index document (typically
index.html) and error document (typicallyerror.htmlor404.html). - Optionally configure redirection rules (e.g., redirect all 404s to
/index.htmlfor SPA-style routing). - The bucket is now reachable at
http://bucketname.s3-website-region.amazonaws.com.
Public access requirements
Static website hosting requires public read access on the bucket — typically enabled via:
- Disabling Block Public Access at the bucket level.
- Setting a bucket policy that grants
s3:GetObjecttoPrincipal: "*"for the entire bucket prefix.
This is dramatically less secure than gating access through CloudFront + OAC. The exam-correct pattern is almost always: keep S3 private, put CloudFront in front of the bucket using the S3 REST endpoint origin and OAC, and use a Route 53 Alias record from the apex (example.com) to the CloudFront distribution.
When to use the website endpoint vs the REST endpoint
| Need | Endpoint | Note |
|---|---|---|
Directory indexes (/folder/ → /folder/index.html) |
Website endpoint | REST endpoint does not auto-serve index.html. |
| Redirect rules | Website endpoint | REST endpoint cannot redirect. |
| Custom error documents | Website endpoint | Or implement via CloudFront error responses. |
| OAC support | REST endpoint | Website endpoint does not support OAC. |
| HTTPS at S3 | REST endpoint | Website endpoint is HTTP only; HTTPS only via CloudFront in front. |
| Modern recommended pattern | REST endpoint + CloudFront | Use CloudFront error pages and CloudFront default-root-object instead. |
The exam-canonical pattern for an S3-backed static website on a custom domain is: keep the bucket private, expose it via a CloudFront distribution using the S3 REST endpoint origin, attach OAC, configure CloudFront's default root object to index.html and custom error responses to map S3's 403/404 to /index.html (for SPA routing), and create a Route 53 Alias record at example.com pointing to the CloudFront distribution. Public-bucket S3 website hosting is acceptable only for trivial demos. Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html
Scenario Pattern: Traffic Going to Wrong Region After Failover
This is one of the canonical SOA-C02 scenarios. Production runs in us-east-1 (Primary) with DR warm standby in us-west-2 (Secondary), with Route 53 Failover routing and a health check on the primary ALB. The primary fails. Some users immediately route to us-west-2; others continue hitting the dead us-east-1 for many minutes. The runbook:
- Confirm the health check actually flipped. In Route 53 console, the health check status should show Unhealthy. If it stayed Healthy, the health check probe itself was wrong — the
/healthendpoint may be too shallow (e.g., returning 200 from a stuck process). - Confirm the failover record points at the correct secondary. A common mistake is having a Secondary record that targets a stale
us-west-2Alias. - Check the TTL on the DNS record. If the failover record has a 300-second TTL, recursive resolvers globally cache the Primary's IP for up to 5 minutes after Route 53 marks it unhealthy. Some users will not see the new answer until their cached entry expires. Fix: set the TTL to 60 seconds or even lower for failover-critical records.
- Check the failure threshold and interval. A standard 30-second interval with 3 failures = 90 seconds before flip. Add the TTL of 60–300 seconds and a recursive resolver's behavior, and total failover time can reach 4–5 minutes. For tighter recovery, switch to fast (10-second) health checks.
- Browser and OS caches. Even with a 60-second TTL, some browsers cache DNS for the lifetime of the tab. There is nothing Route 53 can do about that — only educate users to retry or refresh.
The fix is rarely the routing policy or even the failover configuration — it is TTL tuning and health check sensitivity. SOA-C02 tests this exact pattern; the answer is typically "lower the TTL on the failover record and use fast health checks."
Scenario Pattern: CloudFront Serves Stale Content After S3 Update
A site team uploads index.html to the S3 origin, but viewers continue to see the old content for hours. Runbook:
- Check the cached object's TTL. If
index.htmlwas uploaded without aCache-Controlheader, CloudFront uses the default 24-hour TTL. The new copy will be served only after 24 hours. - Confirm the origin actually has the new content.
aws s3 cp s3://bucket/index.html -should print the new content. If not, the upload failed. - Invalidate.
aws cloudfront create-invalidation --distribution-id ABC --paths "/index.html"flushes that path from all edges within minutes. The first 1,000 paths per month are free. - Fix the root cause for next time. Either add
Cache-Control: max-age=300to the S3 object metadata at upload (aws s3 cp ... --cache-control "max-age=300"), or use a cache policy with a shorter DefaultTTL on the relevant cache behavior, or rename to versioned filenames so cache eviction is automatic.
Common Trap: Alias Only Works for Same AWS Service Targets
A subtle distractor: candidates assume Route 53 Alias can target any DNS name. It cannot — Alias targets are limited to the supported AWS resource types listed earlier (CloudFront, ALB/NLB/GWLB, API Gateway, Beanstalk, S3 website, VPC interface endpoint, Global Accelerator, another Route 53 record). Pointing Alias at a third-party SaaS hostname is invalid; use a CNAME (which forces the record off the apex). Pointing Alias at an arbitrary IP is also invalid; use an A record.
Common Trap: CNAME at Zone Apex Is Invalid DNS
Worth repeating because it is so heavily tested: the DNS standard prohibits CNAME at the zone apex (the domain itself, like example.com), because the apex must hold an SOA and NS record and a CNAME would conflict. Route 53's Alias record exists specifically to solve this for AWS-resource targets. If a SOA-C02 distractor proposes "create a CNAME at the apex pointing to the CloudFront distribution", it is wrong by definition. Always use Alias for the apex.
Common Trap: CloudFront Default TTL Is 24 Hours
If origin headers are absent, CloudFront caches for the cache policy's DefaultTTL — 24 hours in the AWS-managed CachingOptimized policy. Fresh-content sites that do not set Cache-Control will see massively stale content. The fix is at the origin (set Cache-Control), not at the CloudFront layer (do not just lower MaxTTL — that does not affect the default when origin is silent).
Common Trap: OAI Is Deprecated — Use OAC
Existing OAI configurations still work, but every new distribution should use OAC. SOA-C02 explicitly tests "Configure CloudFront and S3 origin access control (OAC)" — the wording itself signals OAC is the expected answer.
SOA-C02 vs SAA-C03: The Operational Lens
SAA-C03 and SOA-C02 both test Route 53 and CloudFront, but with different lenses.
| Question style | SAA-C03 lens | SOA-C02 lens |
|---|---|---|
| Routing policy choice | "Which routing policy serves European users from Frankfurt?" | "The latency record points to Frankfurt but European users still hit us-east-1 — what's wrong?" |
| Health check | "Which feature provides automated failover?" | "The failover does not flip — diagnose the health check, threshold, and TTL." |
| Apex naked domain | "How do you point a domain at a CloudFront distribution?" | "Operations created a CNAME at apex; users get NXDOMAIN — what's the fix?" |
| OAC vs OAI | Rarely tested — "use OAI to restrict S3 access". | "Migrate the existing OAI configuration to OAC; what bucket policy changes?" |
| CloudFront caching | "Which feature reduces origin load?" | "The origin update is not propagating; default TTL is 24h — what fixes it?" |
| Resolver | "Hybrid DNS for on-prem AD." | "Configure inbound vs outbound endpoint with rules and ENI distribution." |
| Health check intervals | Rarely tested. | "Fast 10-second checks vs standard 30-second; what's the failover budget?" |
The SAA candidate selects the routing policy; the SOA candidate diagnoses why it isn't working in production.
Exam Signal: How to Recognize a Domain 5.2 Question
Domain 5.2 questions on SOA-C02 follow predictable shapes. Recognize them and your time on each question drops dramatically.
- "Apex domain at CloudFront / ALB" — the answer is Alias. CNAME at apex is invalid DNS.
- "Failover not flipping" — check health check probe target, failure threshold, and DNS TTL on the record.
- "CloudFront serving stale content" — origin missing
Cache-Control, default TTL 24h. Fix at origin or invalidate. - "Restrict S3 to CloudFront only" — OAC + bucket policy with
cloudfront.amazonaws.comprincipal scoped byAWS:SourceArn. OAI is the deprecated answer. - "Hybrid DNS, on-prem AD resolution from VPC" — Route 53 Resolver outbound endpoint + forwarding rule.
- "Hybrid DNS, on-prem queries AWS private zone" — Route 53 Resolver inbound endpoint + on-prem forwarder rule.
- "Reduce CloudFront cost for regional audience" — Price Class 100 or 200.
- "Lightweight URL rewrite at edge" — CloudFront Functions, not Lambda@Edge.
- "Edge function needs DynamoDB lookup" — Lambda@Edge, not CloudFront Functions.
- "Multi-region active-active for performance" — Latency-based routing with health checks.
- "Active-passive DR" — Failover routing with health check on Primary.
- "Regulatory geographic restriction" — Geolocation routing.
- "Manual fine-tuning of regional traffic split" — Geoproximity with bias.
- "Cheap round-robin for small fleet" — Multivalue answer routing.
With Domain 5 worth 18 percent and TS 5.2 carrying roughly a third of that weight, expect 6 to 8 questions hitting Route 53 routing policies, health checks, CloudFront OAC, S3 static website hosting, and the Alias-at-apex rule. Master the patterns above and you bank a meaningful portion of the exam. Reference: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html
Decision Matrix — Route 53 / CloudFront Construct for Each SysOps Goal
Use this lookup during the exam.
| Operational goal | Primary construct | Notes |
|---|---|---|
Point apex example.com at CloudFront |
Alias A record | CNAME at apex is invalid DNS. |
Point www.example.com at CloudFront |
Alias A record (preferred) or CNAME | Alias is free; CNAME is paid per query. |
| Active-passive DR across regions | Failover routing + health check on Primary | Set TTL low (60s) for fast failover. |
| Active-active multi-region for latency | Latency-based routing + per-region health checks | Health checks remove failed regions. |
| Blue/green or gradual rollout | Weighted routing | Adjust weights over time; weight 0 stops traffic. |
| Regulatory or licensing restrictions | Geolocation routing | Continent/country/state matching plus Default. |
| Manual traffic shifting between regions | Geoproximity routing with bias | Requires Route 53 traffic flow. |
| Cheap round-robin DNS for small fleet | Multivalue answer routing with health checks | Up to 8 records returned randomly. |
| Probe an HTTP endpoint | Endpoint health check | 30s standard or 10s fast. |
| Combine multiple health checks | Calculated health check | Up to 256 children, X-of-N rule. |
| Drive Route 53 from a CloudWatch metric | CloudWatch alarm health check | Healthy if alarm OK; Unhealthy if ALARM. |
| On-prem queries AWS private zone | Route 53 Resolver inbound endpoint | Two ENIs in two AZs minimum. |
| AWS queries on-prem DNS | Route 53 Resolver outbound endpoint + forwarding rules | Rule pattern + on-prem target IPs. |
| Restrict S3 origin to CloudFront only | OAC + bucket policy with cloudfront principal + AWS:SourceArn | OAI is deprecated. |
| SPA-style 404 → index.html | CloudFront custom error responses (403/404 → /index.html) | Or S3 website endpoint redirect rules. |
| Reduce CloudFront cost for EU-only audience | Price Class 100 | NA + EU + Israel only. |
| Lightweight URL rewrite at edge | CloudFront Functions | JS only, sub-millisecond, no network. |
| Edge function with DynamoDB lookup | Lambda@Edge | Network access, longer runtime. |
| Frequently updated assets | Versioned filenames + low TTL on HTML | Cheaper than invalidation. |
| Emergency content recall | Cache invalidation via API or console | First 1,000 paths/month free. |
| Manage hosted zones as code | CloudFormation AWS::Route53::HostedZone / RecordSet |
Version in Git, deploy via stack. |
| Manage CloudFront as code | CloudFormation AWS::CloudFront::Distribution |
Or CDK; never console-drift in prod. |
Common Traps Recap — Route 53 DNS and CloudFront
Every SOA-C02 attempt will see two or three of these distractors.
Trap 1: CNAME at apex
The apex (naked example.com) cannot host a CNAME. Use Alias.
Trap 2: Alias to non-AWS targets
Alias only resolves to supported AWS resources. For third-party hostnames, use CNAME (off-apex) or A record.
Trap 3: Latency routing with no health checks
Without health checks, latency-based routing keeps returning the closest-region record even when that region is down. Always pair latency with health checks.
Trap 4: Failover routing with no health check on Primary
Without a health check, Route 53 has no signal that Primary failed and never returns Secondary. The health check is mandatory on the Primary record.
Trap 5: TTL too long for failover
A 300-second (or longer) TTL means up to 5 minutes of cached stale answers after Route 53 flips. For failover-critical records, TTL of 60s or lower; pair with fast health checks.
Trap 6: Default CloudFront TTL is 24h, not 0
If the origin sends no Cache-Control, CloudFront caches for the cache policy's DefaultTTL — 24 hours by default. Set origin headers or shorten DefaultTTL for fresh content.
Trap 7: OAI for new distributions
OAI is deprecated. Use OAC.
Trap 8: Public S3 bucket for static site
Modern pattern keeps the bucket private and gates access through CloudFront with OAC. Public buckets are acceptable only for demos.
Trap 9: Inbound vs outbound resolver direction
Inbound = on-prem queries AWS. Outbound = AWS queries on-prem. Check the direction of resolution against the question's wording.
Trap 10: CloudFront Functions where Lambda@Edge is required
CloudFront Functions cannot make network calls. If the scenario needs DynamoDB, S3, or any AWS API, you must use Lambda@Edge.
Trap 11: Invalidating frequently instead of versioning filenames
Invalidation costs after the first 1,000 paths per month, and is slower than letting cache entries expire on versioned filenames. The native pattern is content-hashed filenames (main.a1b2c3.js).
FAQ — Route 53 DNS and CloudFront
Q1: Why can't I create a CNAME at example.com?
DNS standards (RFC 1035) prohibit a CNAME from coexisting with any other record at the same name, and the zone apex must hold an SOA record (the zone's start of authority) and at least one NS record (the zone's name servers). A CNAME at apex would conflict with both, so the standard disallows it. Route 53's Alias record is AWS's solution: it looks like an A or AAAA record (compatible with the apex requirements) but resolves dynamically to the IPs of supported AWS resources. Use Alias whenever you need to point a naked domain at a CloudFront distribution, ALB, S3 website endpoint, or other supported resource.
Q2: What is the difference between Failover routing and Latency-based routing?
Failover is active-passive — Route 53 always returns the Primary record unless its health check is failing, then returns the Secondary. The Secondary is dormant under normal conditions. Latency-based is active-active — every record (one per region) is in rotation, and Route 53 returns the lowest-latency one for the requesting resolver, optionally pruning unhealthy regions via health checks. Failover is for DR (warm standby in another region); latency-based is for performance optimization across regions all running the same workload. SOA-C02 tests both, and the giveaway phrase is "disaster recovery" (failover) versus "minimize user latency globally" (latency-based).
Q3: How fast can Route 53 fail over?
Total failover time is the sum of: health-check detection (interval × failure threshold), DNS TTL on the record, and any client-side DNS cache. For a standard 30-second interval with 3-failure threshold, detection is 90 seconds. With a 60-second TTL on the record, recursive resolvers refresh within another 60 seconds. Total: ~150 seconds for most users, longer for some clients with aggressive caching. To compress the budget, switch to fast (10-second) health checks (30s detection) and lower TTL (60s or even 30s on the record). Sub-30-second failover is generally not achievable through DNS alone — for that, use Global Accelerator with anycast IPs.
Q4: When should I choose Geoproximity over Geolocation?
Geolocation matches the resolver's geographic location to a fixed set of regions (continent, country, US state) and returns the matching record or the Default. It's binary — a user is either in Spain or not in Spain. Geoproximity uses geographic distance to AWS regions or arbitrary lat/long points, with an adjustable bias that expands or shrinks each region's catchment area. Use Geolocation for regulatory or licensing constraints (must be in a specific country); use Geoproximity for performance-driven routing where you want fine-tuned manual control over how much traffic each region absorbs.
Q5: Why does my CloudFront distribution still serve stale content after I updated the S3 object?
Two likely causes. (a) The origin object has no Cache-Control header, so CloudFront cached it for 24 hours (the default TTL in the AWS-managed CachingOptimized cache policy). Fix by setting Cache-Control: max-age=300 on the S3 object or by using a cache policy with a shorter DefaultTTL. (b) The cache key did not change with the update — CloudFront keys by URL plus configured headers/cookies/query strings; if the URL is identical and the cache is unexpired, CloudFront returns the cached copy regardless of the origin update. To force fresh fetches, either (i) issue a cache invalidation on the affected paths, or (ii) rename the file with a version suffix so the URL changes.
Q6: Should I use OAC or OAI for a new CloudFront-S3 setup?
Always OAC for new distributions. OAI was deprecated in August 2022 in favor of OAC, which adds support for SSE-KMS-encrypted S3 objects, all AWS regions including opt-in regions, additional HTTP methods (PUT/POST), and per-distribution scoping via the AWS:SourceArn condition. OAI is still supported on existing distributions for backward compatibility, but the SOA-C02 exam explicitly tests "Configure CloudFront and S3 origin access control (OAC)" — OAC is the expected modern answer. Migration from OAI to OAC is a four-step bucket policy update; AWS publishes the procedure in the CloudFront Developer Guide.
Q7: What's the difference between an inbound and an outbound Route 53 Resolver endpoint?
Inbound receives DNS queries into AWS from on-premises. The endpoint provisions ENIs in your VPC with private IPs that on-prem DNS servers configure as forwarders. Use case: on-prem applications need to resolve db.aws.example.com from a private hosted zone associated with the resolver's VPC. Outbound sends DNS queries out of AWS to on-premises. The endpoint provisions ENIs that Route 53 Resolver uses as its source for forwarded queries; you configure Resolver rules that pattern-match domain names and route them to specified on-prem target IPs. Use case: AWS applications need to resolve corp.example.com from on-prem Active Directory. Bidirectional hybrid DNS requires both endpoints.
Q8: When is CloudFront Functions sufficient and when do I need Lambda@Edge?
CloudFront Functions runs sub-millisecond JavaScript at every edge location, with no network access and a ~2 MB memory limit. It is ideal for header rewrites, URL rewrites, simple authentication token validation, A/B-test routing, and HTTP-to-HTTPS redirects. Lambda@Edge runs Node.js or Python at regional edge caches with full network access (AWS API calls, internet), up to 10 GB memory, and up to 30 seconds of execution time. Choose Lambda@Edge whenever you need to look up something in DynamoDB, sign a URL with a secret from Secrets Manager, transform an image, or call an external API. CloudFront Functions costs $0.10 per million invocations; Lambda@Edge costs standard Lambda pricing plus a per-request fee, so default to Functions when both could work.
Q9: How do I track CloudFront cache hit ratio?
CloudFront publishes the CacheHitRate metric in CloudWatch under the AWS/CloudFront namespace, with the dimension DistributionId. The metric is a percentage of viewer requests served from cache versus forwarded to the origin. Healthy static-content distributions hit 90 percent or higher; lower numbers indicate either fragmenting cache keys (too many headers/cookies/query strings included), short TTLs, or too many invalidations. Pair the metric with CloudFront access logs (delivered to S3) or real-time logs (Kinesis Data Streams) — the x-edge-result-type field on each request shows Hit, Miss, RefreshHit, LimitExceeded, or Error, allowing per-path cache-hit analysis.
Q10: How do I lock down an ALB origin so only CloudFront can reach it?
Two layers. Network layer: configure the ALB's security group to allow inbound on the listener ports only from the CloudFront managed prefix list (com.amazonaws.global.cloudfront.origin-facing), which AWS keeps current with all CloudFront edge IP ranges. Application layer: configure the CloudFront distribution to inject a custom secret header (e.g., X-Custom-Origin-Verify: <random-string>) on all origin requests, and configure the ALB listener rules to forward only requests carrying that header — drop the rest. The combination ensures that even an attacker who discovers the ALB DNS name and connects from a CloudFront IP range still cannot bypass CloudFront because they cannot guess the header secret. SOA-C02 tests this exact pattern as the OAC-equivalent for ALB origins.
Further Reading and Related Operational Patterns
- Amazon Route 53 Developer Guide
- Working with Hosted Zones
- Choosing a Routing Policy
- Configuring DNS Failover
- Route 53 Health Check Types
- Choosing Between Alias and Non-Alias Records
- Route 53 Resolver
- Getting Started with Route 53 Resolver Endpoints
- Amazon CloudFront Developer Guide
- Restricting Access to S3 Origins (OAC)
- Creating a CloudFront Distribution
- Increasing the Cache Hit Ratio
- Invalidating Files
- CloudFront Price Classes
- CloudFront Functions and Lambda@Edge
- S3 Static Website Hosting
- AWS SOA-C02 Exam Guide v2.3 (PDF)
Once Route 53 and CloudFront are configured correctly, the next operational layers are: VPC configuration and connectivity for the private network on which Route 53 Resolver endpoints, ALB origins, and CloudFront origin access connect; WAF, Shield, and network protection for L7 filtering and DDoS resilience attached to the CloudFront distribution; backup and disaster recovery procedures that drive the failover routing policy when a regional outage occurs; and CloudWatch metrics, alarms, and dashboards that consume Route 53 health check status and CloudFront cache-hit metrics into the operational dashboard fabric.