Amazon CloudFront β
Content Delivery Network
AWS's global CDN β caches content at 450+ edge locations, reduces latency to single-digit milliseconds, protects origins from direct access, and accelerates both static and dynamic content. Not just caching β it's your edge security + routing layer.
β‘ CloudFront in 30 Seconds
- CDN β caches content at 450+ edge locations in 90+ cities worldwide
- Latency reduction β serves from nearest edge (single-digit ms) instead of origin (100-300 ms)
- Not just caching β also edge compute, security, DDoS protection, and access control
- Global service β like Route 53 and IAM, not region-scoped
- Integrates with S3, ALB, API Gateway, Lambda@Edge, and any HTTP origin
What is CDN & CloudFront
Your origin server (S3 bucket, ALB, API) lives in one region (e.g., us-east-1 in Virginia). A user in Tokyo makes a request β that request travels ~14,000 km across the Pacific Ocean, through multiple network hops. Round-trip time: 200-300 ms before any content is even being sent. Multiply that by every image, CSS file, and API call β your site feels slow.
π The fundamental problem: Physics. Light in fiber travels ~200 km/ms. Distance = latency. You can't beat physics β but you can cheat it by putting copies closer to users.
A Content Delivery Network (CDN) solves this by placing copies of your content at edge locations around the world. When a user in Tokyo requests your image, instead of traveling to Virginia, the request hits an edge server in Tokyo β distance: 0 km, latency: 1-5 ms.
Without CDN
- Every request travels to origin (Virginia)
- Tokyo user: ~200 ms per request
- London user: ~80 ms per request
- Origin handles ALL traffic (overloaded)
- DDoS hits origin directly
- HTTPS termination at origin (slower)
With CloudFront
- First request cached at edge; subsequent requests served locally
- Tokyo user: ~5 ms (from Tokyo edge)
- London user: ~5 ms (from London edge)
- Origin handles only cache misses (90%+ offloaded)
- DDoS absorbed by AWS edge network
- HTTPS termination at edge (faster TLS handshake)
Amazon CloudFront is AWS's managed CDN service. It has 450+ Points of Presence (PoPs) in 90+ cities across 49 countries. But CloudFront is far more than just a cache β it's an edge compute + security + routing layer:
Edge Caching
Cache content at 450+ locations. Static files (images, CSS, JS) served directly from edge. Reduces origin load by 90%+.
Edge Security
DDoS protection (AWS Shield Standard included), HTTPS termination, OAC (block direct S3 access), signed URLs for private content.
Edge Compute
Lambda@Edge and CloudFront Functions run code at edge locations β URL rewrites, A/B testing, auth, header manipulation without origin contact.
Origin = Central Kitchen
- One location (your S3 bucket / ALB in Virginia)
- Makes everything from scratch
- Far from most customers
- Gets overwhelmed with all orders directly
- If it goes down, everyone is affected
Edge Locations = Local Coffee Shops
- 450+ shops around the world (edge locations)
- Stock the most popular items (cached content)
- Serve customers in seconds (local, no travel)
- If an item isn't in stock β order from kitchen (cache miss)
- Once received, keep it stocked for next customer (cache fill)
- Kitchen only handles restock orders (reduced load)
| Property | Value | Why It Matters |
|---|---|---|
| Edge Locations | 450+ in 90+ cities, 49 countries | Content is always near your users, regardless of where they are |
| Scope | Global service (not regional) | One distribution serves the entire world. No per-region config. |
| Protocols | HTTP/1.1, HTTP/2, HTTP/3 (QUIC), WebSocket | Modern protocols for fastest delivery + real-time apps |
| HTTPS | Free SSL/TLS with ACM certificates | No cost for HTTPS. Custom domain requires ACM cert in us-east-1. |
| DDoS Protection | AWS Shield Standard (included free) | Layer 3/4 DDoS mitigation at edge β never hits your origin. |
| Origins Supported | S3, ALB, EC2, API Gateway, any HTTP endpoint | Works with any web server β AWS or non-AWS (custom origin). |
| Pricing | Pay per GB transferred + per request | No upfront. Free tier: 1 TB/month transfer + 10M requests for 12 months. |
| User Location | Direct to Origin (Virginia) | With CloudFront | Improvement |
|---|---|---|---|
| Virginia (US-East) | ~10 ms | ~5 ms | 2Γ faster |
| London (EU) | ~80 ms | ~5 ms | 16Γ faster |
| Tokyo (APAC) | ~200 ms | ~5 ms | 40Γ faster |
| Sydney (APAC) | ~250 ms | ~8 ms | 31Γ faster |
| SΓ£o Paulo (SA) | ~150 ms | ~10 ms | 15Γ faster |
Most people think "CloudFront = CDN = caching." But the real understanding:
π CloudFront = edge compute + security + routing layer. Caching is just one function. It also: reduces latency for dynamic content (TCP/TLS optimization), protects your origin (Shield + WAF), controls access (OAC + signed URLs), and runs code at edge (Lambda@Edge).
| Function | What It Does | Benefit |
|---|---|---|
| Edge Caching | Store copies of static content at edge | 90%+ requests never hit origin |
| TLS Optimization | Terminate HTTPS at edge (closer TLS handshake) | Faster even for dynamic content (no cache) |
| DDoS Shield | Absorb L3/L4 attacks at edge network | Origin never sees attack traffic |
| Origin Shield | Extra caching layer between edge and origin | Reduces origin load further (collapse requests) |
| OAC | Block direct access to S3 β only via CloudFront | Content only served through CDN (secure + fast) |
| Lambda@Edge | Run code at edge before/after cache | URL rewrites, A/B testing, auth, personalization |
CloudFront is not just a cache β it's your global edge layer for security, performance, and compute. 450+ edge locations serve content in single-digit milliseconds. Origins are protected and offloaded. Use it for ALL internet-facing content, not just static files.
- CDN = copies of content at edge locations near users. Reduces latency from 200 ms to 5 ms.
- CloudFront = AWS's CDN. 450+ PoPs in 90+ cities. Global service (not regional).
- Not just caching: also TLS optimization, DDoS protection, access control, edge compute.
- Origins: S3 (static), ALB (dynamic), API Gateway (serverless), any HTTP endpoint.
- Cache flow: User β Edge (HIT = instant, MISS = fetch from origin, cache for next request).
- Free DDoS: AWS Shield Standard included. HTTPS free via ACM (cert must be in us-east-1).
- Pricing: Pay per GB + per request. Free tier: 1 TB/month for 12 months.
- Exam mental model: "Content needs to be fast globally" β CloudFront. "Protect S3 from direct access" β CloudFront + OAC.
Core Concepts (Distributions, Edge Locations)
A Distribution is the main CloudFront resource β it represents your entire CDN configuration. When you create a distribution, CloudFront gives you a domain name (e.g., d111abc.cloudfront.net) that routes requests through the edge network to your origins.
Think of a distribution as the blueprint for how CloudFront handles your traffic β it defines: where content comes from (origins), how requests are routed (behaviors), how long to cache (TTL), and who can access content (security).
| Distribution Component | What It Is | Example |
|---|---|---|
| Domain Name | CloudFront-assigned URL | d111abc.cloudfront.net |
| Origin(s) | Where content lives (source of truth) | S3 bucket, ALB, API Gateway |
| Cache Behavior(s) | Rules for how to handle requests by path | /api/* β ALB, /* β S3 |
| Price Class | Which edge locations to use | All edges, NA+EU only, NA only |
| Alternate Domain | Custom domain (CNAME) | www.example.com |
| SSL Certificate | HTTPS cert (ACM or custom) | ACM cert in us-east-1 |
| WAF Web ACL | Firewall rules (optional) | Block by IP, rate limit, geo-restrict |
CloudFront has a two-tier caching architecture. Understanding this is key for optimization:
Edge Locations (450+)
- Closest to users β lowest latency
- First point of contact for all requests
- Smaller cache capacity (popular content only)
- If content not cached here β check Regional Edge Cache
- Located in 90+ cities worldwide
Regional Edge Caches (13)
- Larger cache, fewer locations (one per major region)
- Sits between edge locations and your origin
- Catches content that's not popular enough for edge
- Reduces origin fetches for "warm" content
- Invisible β you don't configure them
A distribution can have multiple cache behaviors β each one matches a URL path pattern and defines how CloudFront handles those requests. This lets you send different paths to different origins with different caching rules.
| Path Pattern | Origin | Cache Policy | Use Case |
|---|---|---|---|
/api/* | ALB (dynamic) | No cache (TTL=0) | API calls β always fresh from backend |
/static/* | S3 bucket | Cache 1 year (immutable assets) | CSS, JS, images with hash filenames |
/images/* | S3 bucket | Cache 24 hours | User-uploaded images β change occasionally |
Default (*) | ALB (app server) | Cache 5 minutes | HTML pages β semi-dynamic |
π Exam tip: The Default behavior (*) is mandatory β it catches all requests not matched by other patterns. More specific patterns take priority. Path patterns use standard glob syntax (* = wildcard).
You can limit which edge locations CloudFront uses to reduce cost (fewer edges = cheaper but higher latency for excluded regions):
| Price Class | Edge Locations Included | Cost | Use When |
|---|---|---|---|
| All Edge Locations | All 450+ worldwide | Highest | Global audience, lowest latency everywhere |
| 200 | NA, EU, Asia, Middle East, Africa | Medium | Most apps β excludes only South America + Australia |
| 100 | NA + EU only | Lowest | US/EU-focused apps, budget optimization |
π¨ Critical exam trap: ACM certificates for CloudFront MUST be created in us-east-1 (N. Virginia). Certificates from any other region will not appear in CloudFront distribution settings. This applies regardless of where your origin or users are located. It is the most common real-world mistake and a frequent exam question.
| Price Class | Approx. Cost (per GB, US) | Savings vs All | Trade-off |
|---|---|---|---|
| All (450+ edges) | ~$0.085/GB | Baseline | Lowest latency everywhere |
| 200 (most edges) | ~$0.080/GB | ~6% | Excludes South America + Australia |
| 100 (NA+EU only) | ~$0.075/GB | ~12% | Higher latency for APAC/SA users |
Recommendation: Start with Price Class 200 (covers 95% of users cheaply). Use All only if you have significant traffic from South America or Australia. Price Class 100 is fine for internal tools or US/EU-only apps.
By default, CloudFront gives you d111abc.cloudfront.net. To use your own domain (www.example.com):
Steps to Custom Domain
- 1. Request ACM certificate in us-east-1 (must be this region)
- 2. Add alternate domain name to distribution
- 3. Attach ACM certificate
- 4. Create Route 53 Alias record β CloudFront distribution
Common Mistakes
- ACM cert in wrong region (must be us-east-1 for CloudFront)
- Forgetting to add CNAME to distribution settings
- Using CNAME DNS record instead of Alias (works but charged)
- Certificate doesn't match domain (www vs naked)
A Distribution is the CDN config. It has origins (where content lives), behaviors (path-based routing rules), and edge locations (where content is cached). Two-tier caching: Edge β Regional Edge Cache β Origin. Custom domains require ACM cert in us-east-1.
- Distribution: top-level CloudFront resource. Gets a d111.cloudfront.net domain. Contains origins, behaviors, security config.
- Edge Locations (450+): closest to users. Small cache. First point of contact.
- Regional Edge Caches (13): larger cache between edges and origin. Invisible, automatic.
- Cache Behaviors: path-based routing. /api/* β ALB (no cache). /static/* β S3 (long cache). Default (*) required.
- Price Classes: limit edges to reduce cost. All (global) / 200 (most) / 100 (NA+EU only).
- Custom domain: ACM cert in us-east-1 + alternate CNAME in distribution + Route 53 Alias record.
- Exam trap: ACM cert MUST be in us-east-1 for CloudFront (regardless of your app's region).
Caching Behavior
Caching is CloudFront's core function. Understanding the cache flow is critical for both the exam and production optimization:
The cache key is how CloudFront identifies a unique cached object. By default, the cache key is just the URL path + query string. But you can customize it to include headers, cookies, or query parameters.
| Cache Key Component | Default | Customizable? | Impact |
|---|---|---|---|
| URL Path | Always included | No | /images/logo.png and /images/hero.png are different cache entries |
| Query Strings | None (ignored) | Yes β include all, none, or specific | ?v=1 and ?v=2 can be same or different cache entries |
| Headers | None | Yes β include specific headers | Accept-Language in key β cache per language |
| Cookies | None | Yes β include all, none, or specific | Session cookie in key β cache per user (bad!) |
π Golden rule: The more items in the cache key, the lower your cache hit ratio. Include only what truly changes the response. Including ALL cookies = cache per user = no caching benefit. Keep the key minimal.
TTL (Time To Live) controls how long CloudFront caches an object before checking with the origin for a fresh copy. There are three TTL settings that interact:
| TTL Setting | Default | Purpose | How It Works |
|---|---|---|---|
| Minimum TTL | 0 seconds | Floor β CloudFront caches at least this long | Even if origin says Cache-Control: max-age=0, CloudFront keeps for Minimum TTL |
| Default TTL | 86400 (24 hours) | Used when origin sends no cache headers | If origin omits Cache-Control/Expires, use this value |
| Maximum TTL | 31536000 (1 year) | Ceiling β CloudFront never caches longer than this | Even if origin says max-age=9999999, capped at Maximum TTL |
TTL Priority (What Wins)
- 1. Origin sends
Cache-Control: max-age=N - 2. CloudFront clamps:
min(max(N, MinTTL), MaxTTL) - 3. If origin sends NO cache headers β use Default TTL
- 4.
Cache-Control: no-cache/no-storeβ respects it (if Min TTL = 0)
Practical Guidelines
- Static assets (hashed): max-age=31536000 (1 year). Filename changes = new cache entry.
- HTML pages: max-age=300 (5 min) or no-cache. Users get fresh content quickly.
- API responses: TTL=0 or no-store. Always fresh from backend.
- Images: max-age=86400 (24 hrs). Balance freshness vs performance.
π Origin Cache-Control Example (S3 metadata):
Cache-Control: max-age=86400, publicβ CloudFront caches 24h (clamped to MinTTL/MaxTTL range)Cache-Control: no-cacheβ forces revalidation with origin every request (If-Modified-Since)Cache-Control: no-storeβ disables caching entirely (CloudFront never stores the response)Cache-Control: max-age=31536000, immutableβ 1 year cache, browser won't revalidate (hashed filenames)
When you update content at origin, the cached version at edge is stale until TTL expires. To force immediate removal, use invalidation:
| Method | How It Works | Cost | Best For |
|---|---|---|---|
| Create Invalidation | Tell CloudFront to remove specific paths from all edges | First 1000/month free, then $0.005 per path | Emergency content update, bug fix deployment |
| Versioned File Names | Use style.abc123.css β new deploy = new file name = new cache entry | Free (no invalidation needed) | Production best practice for static assets |
| Wait for TTL | Do nothing β old content expires naturally | Free | Non-urgent changes, short TTL content |
π Best practice: Never rely on invalidation as your primary cache-busting strategy. Use versioned filenames for static assets (e.g., app.3f4a2b.js). Invalidation is for emergencies β it's slow (takes 5-10 minutes to propagate to all edges) and costs money at scale.
Cache Hit Ratio = percentage of requests served from cache (without origin contact). Higher = faster + cheaper. Target: 90%+ for static content.
| Factor | Improves Hit Ratio | Worsens Hit Ratio |
|---|---|---|
| TTL | Longer TTL (content stays cached) | Short TTL (frequent re-fetches) |
| Cache Key | Minimal key (URL only) | Including cookies/all headers (cache per user) |
| Query Strings | Ignore or whitelist specific ones | Include all (random params = cache miss) |
| Origin Shield | Enabled (collapses duplicate misses) | Disabled (each edge fetches independently) |
| Content Type | Static assets (highly cacheable) | Personalized/dynamic (per-user responses) |
CloudFront separates what affects caching from what's forwarded to origin:
Cache Policy
- Defines the cache key (what makes entries unique)
- Controls TTL (min, max, default)
- Which headers/cookies/query strings are in the key
- More in key = lower hit ratio
- AWS provides managed policies (e.g., CachingOptimized)
Origin Request Policy
- Defines what's forwarded to origin on cache miss
- Independent of cache key β forward headers without caching on them
- Forward Auth header to origin without including in cache key
- Allows origin to use headers for logic without breaking cache
- AWS provides managed policies (e.g., AllViewer)
π Key distinction: Cache Policy = "what differentiates cache entries." Origin Request Policy = "what does my backend need to see." These are separate since 2020 β before that, forwarding a header automatically added it to the cache key (bad for hit ratio).
| Scenario | Solution | Why |
|---|---|---|
| "Content updated but users see old version" | Create invalidation OR use versioned filenames | Edge cache serves stale content until TTL expires |
| "Low cache hit ratio despite long TTL" | Remove unnecessary items from cache key (cookies, headers) | Too many key components = each request is "unique" |
| "API responses must always be fresh" | Set TTL = 0 OR Cache-Control: no-store | Disables caching β every request goes to origin |
| "Different content per language" | Include Accept-Language header in cache key | Separate cache entries per language |
| "Origin overloaded during traffic spike" | Enable Origin Shield + increase TTL | Collapses duplicate requests + content stays cached longer |
Cache key = what differentiates entries (keep minimal). TTL = how long to cache (longer = better hit ratio). Invalidation = emergency override (use versioned filenames instead). Separate cache policy (key) from origin request policy (forwarding). Target 90%+ hit ratio.
- Cache flow: Request β check key β HIT (return cached) or MISS (fetch origin β cache β return).
- Cache key: URL path + optionally query strings, headers, cookies. Minimal key = best hit ratio.
- TTL: Min/Default/Max. Origin Cache-Control takes priority, clamped by Min and Max TTL.
- Invalidation: removes cached objects. Emergency only. Use versioned filenames in production.
- Cache Hit Ratio: target 90%+. Improve with: longer TTL, minimal cache key, Origin Shield.
- Cache Policy: defines cache key + TTL. Origin Request Policy: defines what's forwarded (separate since 2020).
- Static assets: max-age=1year + hashed filenames. API: TTL=0. HTML: short TTL (5 min).
- Exam key: "users see old content" β invalidation or versioning. "low hit ratio" β reduce cache key items.
Origins & Integrations
An origin is where CloudFront fetches content when there's a cache miss. It's the source of truth β the actual server or bucket that holds your original content. A distribution can have multiple origins, each handling different path patterns.
S3 Bucket Origin
- Best for: static assets (images, CSS, JS, HTML)
- Use S3 REST API endpoint (not website endpoint) with OAC
- OAC blocks direct S3 access β only CloudFront can read the bucket
- Supports: SSE-S3 and SSE-KMS encryption at origin
- Path-based: /static/* β S3, /api/* β ALB
S3 Website Endpoint (Different!)
- Uses S3 static website hosting URL (s3-website-region.amazonaws.com)
- Supports: index documents, redirects, custom error pages
- Cannot use OAC β bucket must be public (or use Referer header trick)
- Treated as a "custom origin" by CloudFront
- Use when you need S3 website features (redirects, index.html)
π Exam distinction: "S3 origin" (REST API endpoint) = private bucket + OAC = secure. "S3 website endpoint" = public bucket, no OAC, treated as custom origin. If the question mentions OAC or private S3 β use REST API endpoint.
ALB Origin
- Best for: dynamic content, API backends, SSR apps
- ALB must be public-facing (CloudFront connects over internet)
- Restrict ALB to only accept CloudFront via custom header or security group
- Supports HTTP/HTTPS to origin (configure origin protocol policy)
- Path: /api/* β ALB origin
EC2 Origin (Custom)
- Direct EC2 public IP as custom origin
- Must have public IP + web server running
- No health checks from CloudFront (rely on origin timeout)
- Less common β prefer ALB for HA + health checks
- Use when: single-instance dev/test, legacy apps
CloudFront can front an API Gateway endpoint for additional caching, edge security (WAF), and custom domain support:
| API Gateway Type | CloudFront Integration | Notes |
|---|---|---|
| Edge-Optimized API | Already has built-in CloudFront (AWS-managed) | Adding your own CF = double CDN. Usually not needed. |
| Regional API | Add CloudFront distribution in front | Best approach β full control over caching, WAF, custom domain. |
| HTTP API | Add CloudFront distribution in front | Cheapest API GW option + CloudFront for edge features. |
π Exam tip: "API Gateway + CloudFront" β use Regional API Gateway as origin (not Edge-Optimized, which already has a hidden CloudFront). This gives you control over caching, WAF, and custom headers.
Origin Groups enable automatic failover between a primary and secondary origin. If the primary returns specific error codes (5xx, 4xx), CloudFront retries the request against the secondary.
How Origin Groups Work
- Define primary origin + secondary origin
- Configure failover criteria (e.g., 500, 502, 503, 504)
- On failure β CloudFront automatically retries on secondary
- Transparent to user β they get a response either way
Common Pattern
- Primary: S3 bucket in us-east-1
- Secondary: S3 bucket in eu-west-1 (cross-region replica)
- Result: if us-east-1 S3 fails β content served from eu-west-1
- Also works: Primary=ALB, Secondary=S3 static error page
| Origin Type | Best For | OAC Support | Protocol | Notes |
|---|---|---|---|---|
| S3 (REST) | Static files | β Yes | HTTPS | Private bucket. Most secure. |
| S3 (Website) | Static site with redirects | β No | HTTP only | Public bucket. Custom origin. |
| ALB | Dynamic apps, APIs | β (use custom header) | HTTP/HTTPS | Must be public-facing ALB. |
| EC2 | Legacy single-instance | β | HTTP/HTTPS | Needs public IP. No HA. |
| API Gateway | Serverless APIs | β | HTTPS | Use Regional type. |
| Custom Origin | Any HTTP server (on-prem, other cloud) | β | HTTP/HTTPS | Any public HTTP endpoint. |
S3 REST origin + OAC = secure static content (private bucket). ALB origin = dynamic content (restrict via custom header). API Gateway Regional = serverless APIs. Origin Groups = automatic failover between primary + secondary origins.
- S3 REST origin + OAC: private bucket, only CloudFront can read. Best for static assets.
- S3 Website endpoint: public bucket, supports redirects/index.html. No OAC. Custom origin.
- ALB origin: dynamic content. Must be public. Restrict via custom header or SG prefix list.
- API Gateway: use Regional type (not Edge-Optimized) when fronting with CloudFront.
- Origin Groups: primary + secondary. Auto-failover on 5xx/4xx errors. HA for content.
- Custom origin: any HTTP endpoint (on-prem, other cloud) β just needs public access.
- Exam key: "private S3" β OAC. "ALB + CloudFront" β custom header restriction. "failover" β Origin Group.
Security & Access Control
OAC (Origin Access Control) is the modern way to restrict S3 bucket access so that only CloudFront can read your objects. Users cannot bypass CloudFront and access S3 directly.
Without OAC β Problem
- S3 bucket is public (anyone can access directly)
- Users bypass CloudFront β no caching, no security
- No WAF protection on direct S3 access
- No signed URL enforcement
- Origin overloaded β CDN benefit lost
With OAC β Solution
- S3 bucket is private (Block Public Access = ON)
- Bucket policy allows only CloudFront's service principal
- Direct S3 URL returns 403 Forbidden
- All traffic forced through CloudFront (cache + WAF + signed URLs work)
- Supports SSE-KMS encrypted objects
π OAC replaces OAI (Origin Access Identity) β OAI is legacy. Always use OAC for new distributions. OAC supports SSE-KMS, all S3 regions, and POST/PUT methods. OAI doesn't.
For private content that only authorized users should access (paid content, premium downloads), use signed URLs or cookies:
| Feature | Signed URL | Signed Cookie |
|---|---|---|
| Scope | One specific file/URL | Multiple files (entire path pattern) |
| Use When | Individual file download (video, PDF) | Entire premium section (/premium/*) |
| How | App generates URL with signature + expiry | App sets cookies; CloudFront validates |
| Expiry | Set per URL (minutes to days) | Set in cookie (same flexibility) |
| Client Change | URL changes (link is unique per user/time) | URL stays same; auth is in cookie |
| Exam Tip | "Restrict single file" β Signed URL | "Restrict multiple files" β Signed Cookie |
| Setting | Options | Recommended | Notes |
|---|---|---|---|
| Viewer Protocol Policy | HTTP+HTTPS, Redirect HTTPβHTTPS, HTTPS Only | Redirect HTTPβHTTPS | User-facing. Always force HTTPS. |
| Origin Protocol Policy | HTTP Only, HTTPS Only, Match Viewer | Depends on origin | S3 REST = HTTPS. ALB = HTTPS. S3 website = HTTP only. |
Attach AWS WAF (Web Application Firewall) to CloudFront for Layer 7 protection at the edge β before traffic reaches your origin:
WAF Capabilities
- IP allowlists / blocklists
- Rate limiting (requests/second per IP)
- Geo-restriction (block countries)
- SQL injection / XSS protection (managed rules)
- Bot control (block scrapers, credential stuffers)
Geo-Restriction (Built-in)
- CloudFront has built-in geo-restriction (no WAF needed)
- Allow list: only specified countries can access
- Deny list: block specified countries
- Uses GeoIP database at edge
- For complex rules (IP + geo + rate) β use WAF instead
| Layer | Protection | Cost | What It Does |
|---|---|---|---|
| AWS Shield Standard | L3/L4 DDoS | Free (automatic) | Absorbs volumetric attacks (SYN floods, UDP reflection) at edge |
| AWS Shield Advanced | L3/L4/L7 DDoS | $3,000/month | Enhanced detection, DRT team support, cost protection credits |
| AWS WAF | L7 (application) | Per-rule pricing | Rate limiting, bot mitigation, IP blocking at edge |
Response Headers Policies let you add, modify, or remove HTTP headers in CloudFront responses β without changing your origin. Essential for security headers:
Security Headers (Add at Edge)
- HSTS: Strict-Transport-Security (force HTTPS)
- CSP: Content-Security-Policy (prevent XSS/injection)
- X-Frame-Options: DENY/SAMEORIGIN (prevent clickjacking)
- Referrer-Policy: control referrer info leakage
- X-Content-Type-Options: nosniff (prevent MIME sniffing)
Other Capabilities
- CORS headers: Access-Control-Allow-Origin for cross-origin resources
- Remove headers: strip Server, X-Powered-By, X-AspNet-Version
- Custom headers: add X-Request-Id, X-Cache-Status
- Managed policies: AWS provides SecurityHeadersPolicy, SimpleCORS
- Benefit: origin doesn't need to implement security headers
π Exam tip: "Add security headers without modifying the application" β Response Headers Policy on CloudFront. This is a common scenario for legacy apps that can't be easily modified.
Field-Level Encryption (FLE) encrypts specific form field data at the edge before forwarding to your origin β even your own servers never see plaintext sensitive data:
How FLE Works
- Encrypts specific POST form fields at edge using public key
- Data stays encrypted through CloudFront β ALB β app server
- Only the service with the private key can decrypt
- Uses asymmetric encryption (RSA)
- Only works with POST requests (not GET)
Use Cases
- Credit card numbers (PCI compliance)
- Social Security Numbers (SSNs)
- Medical records (HIPAA)
- Personal identification data (PII)
- Certificate management is separate from HTTPS cert
π Key point: FLE adds encryption on top of HTTPS. HTTPS protects data in transit; FLE protects specific fields even at rest in your application layer. Only the designated service (e.g., payment processor) can decrypt.
WAF rate-based rules are a common exam pattern β they throttle excessive requests at the edge:
| Config | Example | Notes |
|---|---|---|
| Threshold | 100 requests per 5 minutes per IP | Aggregated at edge across all CloudFront locations |
| Action | Block request for 10 minutes | Returns 403 Forbidden to client |
| Scope | Specific URI path (e.g., /login, /api/*) | Don't rate-limit static assets |
| Protection | Login brute-force, API abuse, scraping | Origin never sees throttled requests |
π Exam scenario: "Protect login endpoint from brute-force attacks" β attach WAF to CloudFront with rate-based rule. All rate limiting happens at edge β origin stays protected and unaffected.
OAC makes S3 private (only CloudFront reads it). Signed URLs = single file access control. WAF = L7 firewall at edge (rate limiting, bot control). Shield Standard = free DDoS. Response Headers Policy = security headers without touching origin. Field-Level Encryption = protect PII at edge. All security happens at edge β your origin never sees attack traffic.
- OAC: makes S3 bucket private. Only CloudFront can read. Replaces legacy OAI. Supports SSE-KMS.
- Signed URLs: restrict single file. App generates URL with expiry + signature.
- Signed Cookies: restrict multiple files under a path pattern. Auth in cookie, URL unchanged.
- HTTPS: Viewer = Redirect HTTPβHTTPS. Origin = HTTPS when possible. ACM cert free (us-east-1 only!).
- WAF: L7 firewall at edge. Rate limiting, geo-block, SQLi/XSS, bot control.
- WAF Rate Limiting: throttle excessive requests per IP at edge. Protects login/API from brute-force.
- Response Headers Policy: add HSTS, CSP, X-Frame-Options at edge without modifying origin.
- Field-Level Encryption: encrypt sensitive POST fields (PII, credit cards) at edge. Origin never sees plaintext.
- Geo-Restriction: built-in allow/deny list by country. Free. For complex rules β use WAF.
- Shield Standard: free L3/L4 DDoS at edge. Advanced = $3K/mo for L7 + DRT support.
- Exam key: "private S3 + CloudFront" β OAC. "premium content" β Signed URLs/Cookies. "block country" β Geo-restriction. "security headers" β Response Headers Policy.
Performance & Optimization
CloudFront can automatically compress responses before sending them to viewers, reducing transfer size by 60-80% for text-based content:
| Setting | Detail | Impact |
|---|---|---|
| Gzip | Standard compression. Enable in cache behavior. | 60-70% smaller for HTML, CSS, JS, JSON |
| Brotli | Modern, better compression. CloudFront auto-selects based on Accept-Encoding. | 15-20% smaller than Gzip |
| File Types | Text-based: HTML, CSS, JS, JSON, XML, SVG, fonts | Do NOT compress images/video (already compressed) |
| Min Size | Objects must be > 1000 bytes | Small files don't benefit from compression overhead |
π Enable compression in every cache behavior. It's free performance β faster delivery + lower data transfer costs. CloudFront handles Brotli/Gzip negotiation automatically based on viewer's Accept-Encoding header.
Origin Shield adds a centralized caching layer between Regional Edge Caches and your origin. It collapses duplicate origin fetches from multiple edges into a single request:
Without Origin Shield
- Cache miss at Tokyo edge β fetch from origin
- Cache miss at London edge β another fetch from origin
- Cache miss at Virginia edge β yet another fetch
- Origin hit 3 times for same content
- Origin under load during cache-fill events
With Origin Shield
- All edge misses route through Origin Shield region
- First miss β fetches from origin, caches at Shield
- Subsequent misses β served from Shield cache
- Origin hit only once regardless of how many edges miss
- Best for: spiky traffic, large fan-out, expensive origin
π Origin Shield region selection: Choose the AWS region closest to your origin (not closest to users). Traffic flows: Edge β Regional Edge Cache β Origin Shield β Origin. Same region for Shield and Origin = lowest latency on the ShieldβOrigin leg. Example: origin in us-east-1 β enable Origin Shield in us-east-1.
Run code at the edge without touching your origin β for URL manipulation, auth, personalization, A/B testing:
| Feature | CloudFront Functions | Lambda@Edge |
|---|---|---|
| Runtime | JavaScript only | Node.js, Python |
| Execution Time | <1 ms (ultralight) | Up to 5-30 seconds |
| Triggers | Viewer Request / Viewer Response only | All 4 events (Viewer + Origin Request/Response) |
| Network Access | β No | β Yes (call APIs, DBs) |
| Scale | Millions of RPS (massive) | Thousands of RPS |
| Cost | ~$0.10 per million invocations | ~$0.60 per million + duration |
| Use Cases | URL rewrite, header manipulation, simple redirects, cache key normalization | Auth with external IdP, A/B testing, image transformation, SSR |
π Decision: If you can solve it in <1 ms with no network calls β CloudFront Functions (cheaper, faster). If you need network access, longer execution, or origin-side logic β Lambda@Edge.
Lambda@Edge is powerful but has significant limitations compared to standard Lambda functions:
| Restriction | Detail | Workaround |
|---|---|---|
| No environment variables | Cannot use env vars like standard Lambda | Hardcode values, or fetch from SSM Parameter Store at cold start |
| Body size limit | Request/response body limited to 1 MB (1,048,576 bytes) | For larger payloads, modify at origin instead |
| No VPC access | Cannot access VPC resources (RDS, ElastiCache, etc.) | Call external APIs or use DynamoDB (public endpoint) |
| Limited runtimes | Node.js 18/20 and Python 3.9/3.11/3.12 only | No Go, Java, Ruby, .NET at edge |
| Execution time | Viewer events: max 5s. Origin events: max 30s. | Keep logic lightweight; offload heavy work to origin |
| No /tmp (viewer) | Viewer events have no /tmp; origin events have 512 MB /tmp | Use in-memory processing for viewer events |
| Region | Must be deployed in us-east-1 (replicated globally) | Always create Lambda@Edge functions in N. Virginia |
π Exam scenario: "Lambda@Edge function needs to access RDS" β not possible. Lambda@Edge cannot access VPC resources. Solution: call the database via an API endpoint, or move the logic to origin-side Lambda.
CloudFront supports HTTP/3 (QUIC) β a UDP-based protocol that reduces connection setup time and handles packet loss better than TCP. Benefits:
- 0-RTT connection: repeat visitors connect instantly (no TCP+TLS handshake)
- Better on mobile: handles network switches (WiFiβcellular) without reconnecting
- Faster on lossy networks: single lost packet doesn't block entire stream (unlike HTTP/2)
- Enable per-distribution. Falls back to HTTP/2 if client doesn't support QUIC.
CloudFront offers two logging options with different latency and delivery targets:
| Feature | Standard Logs | Real-Time Logs |
|---|---|---|
| Latency | Minutes to hours | 5-10 seconds |
| Delivery | S3 bucket (free storage cost) | Kinesis Data Streams (extra cost) |
| Use Case | Analytics, auditing, historical archives | Real-time monitoring, security alerting, live dashboards |
| Fields | 20+ fields per log line | Configurable (choose specific fields) |
| Sampling | All requests (no sampling) | Configurable sampling rate (1-100%) |
| Cost | Free (you pay for S3 storage) | Kinesis pricing + per log line |
π Exam tip: "Near real-time analysis of CloudFront traffic" β Real-Time Logs + Kinesis Data Streams. "Store logs for compliance/audit" β Standard Logs to S3. They can be enabled simultaneously.
Enable compression (free 60-80% size reduction). Use Origin Shield for high-traffic workloads (region closest to origin). CloudFront Functions for lightweight edge logic; Lambda@Edge for complex compute (but no VPC, no env vars, 1 MB body limit). HTTP/3 for mobile/lossy networks. Standard Logs for archives; Real-Time Logs for live monitoring.
- Compression: enable Gzip/Brotli. 60-80% smaller text files. Free. Always enable.
- Origin Shield: centralizes cache fills. Origin hit once instead of per-edge. Choose region closest to origin.
- CloudFront Functions: JS only, <1 ms, viewer events only, no network. URL rewrites, headers.
- Lambda@Edge: Node/Python, up to 30s, all events, network access. Auth, SSR, image resize.
- Lambda@Edge limits: no env vars, no VPC, 1 MB body, must deploy in us-east-1, viewer events 5s max.
- HTTP/3: QUIC protocol. 0-RTT, better mobile, handles packet loss. Enable per-distribution.
- Standard Logs: free to S3. Minutes-hours delay. Good for analytics and audit.
- Real-Time Logs: 5-10s delay. Kinesis Data Streams. Good for live monitoring and security.
- Exam key: "reduce origin load" β Origin Shield. "code at edge" β CF Functions (simple) or Lambda@Edge (complex). "real-time monitoring" β Real-Time Logs + Kinesis.
Architecture Patterns
Setup: S3 bucket (private, Block Public Access ON) + CloudFront distribution with OAC + ACM cert in us-east-1 + Route 53 Alias record. Result: global HTTPS static site for pennies/month.
Key insight: even for dynamic content, CloudFront helps via TLS optimization (terminate HTTPS at edge = fewer round-trips), connection reuse to origin, and Shield/WAF protection.
Front a Regional API Gateway with CloudFront for WAF protection, edge caching of GET responses, and custom domain management:
π Architecture: Route 53 β CloudFront (WAF attached, cache GET /products for 60s) β API Gateway (Regional) β Lambda. Result: API protected by WAF at edge, common responses cached, custom domain with HTTPS.
Combine multiple origins with origin groups for high availability:
| Behavior | Primary Origin | Secondary Origin (Failover) | Result |
|---|---|---|---|
/static/* | S3 us-east-1 | S3 eu-west-1 (CRR replica) | Static files survive region failure |
/api/* | ALB us-east-1 | ALB eu-west-1 | API fails over to DR region |
Default | ALB us-east-1 | S3 "maintenance" page | App down β users see maintenance page |
| Scenario | Architecture | Key Config |
|---|---|---|
| "Static site with custom domain + HTTPS" | Route 53 β CloudFront β S3 (OAC) | ACM cert in us-east-1. S3 private. |
| "Reduce latency for global API" | Route 53 β CloudFront β API GW (Regional) | Cache GET responses. WAF for protection. |
| "Serve dynamic app faster globally" | Route 53 β CloudFront β ALB | TTL=0 for dynamic. Still benefits from TLS+Shield. |
| "Premium content for paying users only" | CloudFront + Signed URLs | App generates signed URL. CF validates signature. |
| "High availability for static content" | CloudFront + Origin Group (S3 + S3 replica) | CRR between buckets. Origin Group failover. |
| "Block specific countries" | CloudFront Geo-Restriction | Deny list by country code. Or WAF for complex rules. |
Pattern 1: S3 + CloudFront + OAC = cheapest, fastest static hosting. Pattern 2: ALB + CloudFront = dynamic apps with edge security. Pattern 3: API GW + CloudFront = cached + protected APIs. Pattern 4: Origin Groups = automatic cross-region failover.
- Static site: S3 (private) + CloudFront (OAC) + ACM (us-east-1) + Route 53 Alias. Global HTTPS for pennies.
- Dynamic app: CloudFront β ALB. Caches static assets, passes dynamic through. TLS + Shield at edge.
- API acceleration: CloudFront β API Gateway Regional. Cache GET responses. WAF protection at edge.
- Multi-origin failover: Origin Groups. Primary S3 fails β secondary S3 (CRR). Transparent to user.
- Even dynamic benefits: TLS termination at edge = fewer round-trips. Connection reuse to origin. DDoS absorbed.
- Use CloudFront for ALL: not just static files. Every internet-facing workload benefits from edge.