DEV Community

Cover image for Amazon CloudFront Demystified: The Complete Architect-Level Guide
Manish Kumar
Manish Kumar

Posted on

Amazon CloudFront Demystified: The Complete Architect-Level Guide

1. Overview / Introduction

What is Amazon CloudFront?

  • Amazon CloudFront is a fast, globally distributed Content Delivery Network (CDN) service that securely delivers data, videos, applications, and APIs to users worldwide
  • Managed service by AWS that caches and serves content from edge locations closest to end users
  • Operates on a pay-as-you-go model with no upfront costs or long-term commitments

Why It Exists

  • Eliminates high latency caused by geographic distance between users and origin servers
  • Reduces load on origin infrastructure by serving cached content from edge locations
  • Provides built-in security and DDoS protection without additional infrastructure
  • Enables global application delivery without deploying and managing distributed infrastructure

Core Problems It Solves

  • Latency reduction: Routes requests through AWS backbone network to nearest edge location
  • Origin offloading: Reduces compute and bandwidth costs on origin servers by caching
  • Security threats: Protects against DDoS, SQL injection, and XSS attacks through AWS Shield and WAF integration
  • Global scalability: Handles traffic spikes without origin infrastructure changes
  • Cost optimization: More economical data transfer rates than direct EC2/S3 delivery

Where It Fits in AWS Architecture

  • Sits between end users and origin infrastructure (S3, EC2, ELB, on-premises servers)
  • Integrates with Route 53 for DNS routing, ACM for SSL/TLS certificates, Lambda for edge computing
  • Works as the front door for web applications, APIs, video streaming, and software distribution
  • Part of the AWS Global Infrastructure alongside edge locations and regional edge caches

2. Key Concepts & Terminology

Core Definitions

Term Definition
Distribution Configuration unit that defines how CloudFront delivers content (origins, behaviors, caching rules)
Origin Source server where CloudFront fetches content (S3, EC2, ELB, custom HTTP/HTTPS servers)
Edge Location Physical data center where CloudFront caches and serves content to users
Regional Edge Cache Intermediate cache layer between edge locations and origin for less-popular content
Cache Behavior Rules defining how CloudFront handles requests based on path patterns, headers, query strings
TTL (Time To Live) Duration content remains cached before CloudFront checks origin for updates
Invalidation Process to remove cached objects before TTL expires (typically under 2 minutes)
Origin Access Control (OAC) Mechanism to restrict S3 bucket access to only CloudFront
Lambda@Edge Serverless compute that runs code at edge locations for request/response manipulation
CloudFront Functions Lightweight JavaScript runtime for high-scale, latency-sensitive transformations

Component Relationships

End User Request
      ↓
Route 53 (DNS Resolution)
      ↓
CloudFront Edge Location (Cache Check)
      ↓
If MISS → Regional Edge Cache
      ↓
If MISS → Origin Server (S3/EC2/Custom)
      ↓
Content Cached at Edge
      ↓
Response to User
Enter fullscreen mode Exit fullscreen mode

Distribution Types

  • Web Distribution: HTTP/HTTPS content delivery for websites, APIs, applications
  • RTMP Distribution: (Deprecated) Previously used for Adobe Flash Media streaming

3. Architecture & Components

Core Building Blocks

  • Edge Network: Hundreds of globally distributed Points of Presence (PoPs) across dozens of countries
  • Network Backbone: Multiple 400GbE parallel fibers connecting edge locations to AWS Regions
  • Tier 1/2/3 ISP Peering: Direct connections with thousands of carriers globally
  • Origin Fetch Infrastructure: Redundant paths from edge locations to origin servers
  • Control Plane: API-driven management layer for distribution configuration
  • Data Plane: Actual content delivery path from edge to user

How Components Interact

Request Flow:

  1. User requests content via domain name (CNAME or CloudFront domain)
  2. DNS resolves to nearest edge location based on latency and health
  3. Edge location checks local cache for content matching request parameters
  4. If cached (HIT): Content served immediately with sub-millisecond latency
  5. If not cached (MISS): Request forwarded to regional edge cache
  6. If not in regional cache: Origin fetch occurs via optimized AWS network
  7. Content cached at edge location and regional cache based on TTL policies
  8. Response returned to user with appropriate headers and metadata

Origin Failover Flow:

  • Primary origin unhealthy → Automatic failover to secondary origin
  • Health checks determine origin availability
  • Seamless transition without user-facing errors

Control Plane vs Data Plane

Aspect Control Plane Data Plane
Function Configuration, management, monitoring Actual content delivery and caching
Access AWS Console, CLI, API, CloudFormation End-user requests via HTTP/HTTPS
Propagation Configuration changes take 5-15 minutes Real-time request routing and serving
Components Distribution settings, cache policies, origins Edge locations, caches, network routing
Scaling API rate limits, change propagation queues Unlimited edge location scaling

4. Detailed Features & Capabilities

Content Delivery Capabilities

  • Static content: Images, CSS, JavaScript, fonts, HTML files
  • Dynamic content: API responses, personalized pages, real-time data
  • Video streaming: On-demand and live streaming (HLS, DASH, CMAF, Smooth Streaming)
  • Software distribution: Large file downloads, patch distribution
  • API acceleration: Optimized routing for RESTful and GraphQL APIs

Caching & Performance Features

  • Custom cache policies: Control TTL, query string forwarding, cookie handling, header forwarding
  • Compression: Automatic Gzip and Brotli compression for text-based content
  • HTTP/2 and HTTP/3 support: Multiplexing and faster connection establishment
  • Origin connection pooling: Reuses connections to reduce origin load
  • Cache key normalization: Consistent caching regardless of parameter order
  • Query string and cookie caching: Selective caching based on specific parameters

Security Features

  • AWS Shield Standard: Automatic DDoS protection at no additional cost
  • AWS Shield Advanced: Enhanced DDoS protection with 24/7 response team (additional cost)
  • AWS WAF integration: Application-layer firewall for SQL injection, XSS protection
  • SSL/TLS encryption: Full support for HTTPS with custom certificates from ACM
  • Field-level encryption: Encrypts specific sensitive data fields at edge
  • Signed URLs and cookies: Time-limited, authenticated access to private content
  • Origin Access Control (OAC): Restricts S3 bucket access to CloudFront only
  • Geo-restriction: Whitelist or blacklist countries for content access

Programmability & Customization

  • Lambda@Edge: Execute Node.js functions at edge for viewer/origin request/response manipulation
  • CloudFront Functions: Lightweight JavaScript for sub-millisecond request transformations (URL rewrites, header manipulation)
  • Custom error pages: Serve branded error pages for 4xx/5xx errors
  • Origin request policies: Control headers, cookies, query strings sent to origin
  • Response headers policies: Add security headers (CORS, HSTS, CSP) at edge

Limits and Quotas (Per Account - As of Dec 2024)

Resource Default Limit Adjustable
Distributions per account 200 Yes (via support)
Alternate domain names (CNAMEs) per distribution 100 Yes
Origins per distribution 25 Yes
Cache behaviors per distribution 25 Yes
Invalidation requests per month 1,000 paths per month free additional paths are charged
Paths per invalidation 3,000 No
Lambda@Edge functions per distribution 25 Yes
Request rate per distribution Unlimited N/A
Maximum file size 20 GB (PUT/POST) No

Regional vs Global Behavior

  • Global service: No region selection during distribution creation
  • Edge location coverage: All edge locations active by default (can restrict to specific price classes)
  • Price classes: Control which edge locations serve content (all locations, exclude expensive regions, US/Europe/Asia only)
  • Origin regions: Origins can be in any AWS region or on-premises
  • Cross-region origin fetches: Optimized via AWS backbone network
  • Regional edge caches: 13 regional caches for tier-2 caching

5. Security & IAM Considerations

IAM Permissions Required

Read-Only Access:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "cloudfront:GetDistribution",
      "cloudfront:GetDistributionConfig",
      "cloudfront:ListDistributions",
      "cloudfront:ListCloudFrontOriginAccessIdentities",
      "cloudfront:GetCloudFrontOriginAccessIdentity"
    ],
    "Resource": "*"
  }]
}
Enter fullscreen mode Exit fullscreen mode

Full Management Access:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "cloudfront:*",
      "acm:ListCertificates",
      "wafv2:ListWebACLs",
      "s3:ListBucket",
      "s3:GetBucketPolicy",
      "s3:PutBucketPolicy"
    ],
    "Resource": "*"
  }]
}
Enter fullscreen mode Exit fullscreen mode

Least Privilege Examples

Developer - Deploy New Distributions:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "cloudfront:CreateDistribution",
      "cloudfront:UpdateDistribution",
      "cloudfront:GetDistribution",
      "cloudfront:CreateInvalidation"
    ],
    "Resource": "*"
  },
  {
    "Effect": "Allow",
    "Action": ["s3:GetObject", "s3:ListBucket"],
    "Resource": ["arn:aws:s3:::my-origin-bucket/*"]
  }]
}
Enter fullscreen mode Exit fullscreen mode

Operations - Invalidation Only:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "cloudfront:CreateInvalidation",
      "cloudfront:GetInvalidation",
      "cloudfront:ListInvalidations"
    ],
    "Resource": "arn:aws:cloudfront::123456789012:distribution/*"
  }]
}
Enter fullscreen mode Exit fullscreen mode

S3 Origin Security - Origin Access Control (OAC)

S3 Bucket Policy for OAC:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowCloudFrontServicePrincipal",
    "Effect": "Allow",
    "Principal": {
      "Service": "cloudfront.amazonaws.com"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-bucket/*",
    "Condition": {
      "StringEquals": {
        "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1234EXAMPLE"
      }
    }
  }]
}
Enter fullscreen mode Exit fullscreen mode

Common Misconfigurations

  • Public S3 buckets: Using S3 website endpoints instead of bucket endpoints with OAC
  • Missing HTTPS enforcement: Allowing HTTP when HTTPS-only should be enforced
  • Overly permissive signed URLs: Not setting proper expiration times or IP restrictions
  • Forwarding all headers: Breaks caching by forwarding unnecessary headers to origin
  • No WAF protection: Exposing applications without Web Application Firewall rules
  • Weak cipher suites: Using outdated TLS protocols (TLS 1.0/1.1)
  • Missing logging: Not enabling access logs for security auditing

Security Best Practices

  • Always use Origin Access Control (OAC) instead of Origin Access Identity (OAI) for S3 origins
  • Enable AWS WAF for application-layer protection on public-facing distributions
  • Use ACM-managed certificates with automatic renewal
  • Enforce HTTPS with "Redirect HTTP to HTTPS" or "HTTPS Only" viewer protocol policy
  • Implement signed URLs/cookies for premium or private content with short expiration times
  • Enable field-level encryption for sensitive data like credit cards or PII
  • Use Security Headers Policy to add HSTS, X-Frame-Options, CSP headers
  • Enable access logging to S3 for security monitoring and compliance
  • Restrict geographic access using geo-blocking for compliance requirements
  • Regularly rotate custom SSL certificates if not using ACM
  • Use CloudFront Functions to validate JWTs or implement custom authentication at edge

6. Pricing & Cost Optimization

Pricing Model Overview (2025)

Amazon CloudFront offers two distinct pricing models as of November 2025:

1. Pay-As-You-Go Pricing (Traditional)

  • No upfront costs, no long-term commitments
  • Charged based on actual usage
  • Variable rates by region and volume tiers

2. Flat-Rate Pricing Plans (New in November 2025)

  • Simplified predictable monthly billing
  • Four tiers: Free, Pro, Business, Premium
  • Best for predictable traffic patterns

Pay-As-You-Go Pricing Components

1. Data Transfer Out to Internet (Per GB)

Regional pricing tiers with volume discounts:

Monthly Volume North America Europe Asia Pacific Japan Australia India South America Middle East & Africa
First 10 TB $0.085 $0.085 $0.120 $0.114 $0.114 $0.109 $0.110 $0.110
Next 40 TB $0.080 $0.080 $0.105 $0.105 $0.089 $0.098 $0.100 $0.085
Next 100 TB $0.060 $0.060 $0.090 $0.090 $0.086 $0.094 $0.095 $0.082
Next 350 TB $0.040 $0.040 $0.080 $0.080 $0.084 $0.092 $0.090 $0.080
Next 524 TB $0.030 $0.030 $0.060 $0.060 $0.080 $0.090 $0.080 $0.078
Next 4 PB $0.025 $0.025 $0.050 $0.050 $0.070 $0.085 $0.070 $0.075
Over 5 PB $0.020 $0.020 $0.040 $0.040 $0.060 $0.080 $0.060 $0.072

Key Insights:

  • North America and Europe have the lowest rates starting at $0.085/GB
  • South America and Asia Pacific are significantly more expensive (40-50% higher)
  • Volume discounts can reduce costs by up to 76% (from $0.085 to $0.020 at 5PB+)
  • Data transfer from AWS origins to CloudFront is FREE

2. HTTP/HTTPS Requests

Request Type Price per 10,000 Requests
HTTP Requests $0.0075
HTTPS Requests $0.0100

Note: HTTPS requests cost 33% more than HTTP requests

3. Invalidation Requests

  • First 1,000 paths per month: FREE
  • Beyond 1,000 paths: $0.005 per path
  • Wildcard invalidations (/*) count as one path

4. Field-Level Encryption

  • $0.02 per 10,000 requests with field-level encryption enabled

5. Lambda@Edge Pricing

Component Price
Request charges $0.60 per 1 million requests
Duration charges $0.00005001 per GB-second
Duration charges (US East - N. Virginia) $0.00005001 per GB-second
Duration charges (other regions) $0.00005001 per GB-second

Example: 1 million requests with 128MB memory, 50ms duration:

  • Requests: $0.60
  • Duration: 1M × 0.128GB × 0.05s × $0.00005001 = $0.32
  • Total: $0.92

6. CloudFront Functions

  • $0.10 per 1 million invocations
  • 10x cheaper than Lambda@Edge for simple operations

7. Dedicated IP Custom SSL (Legacy)

  • $600 per month per distribution
  • Avoid by using SNI (Server Name Indication) - FREE with modern browsers

8. Real-Time Logs

  • Charged at Amazon Kinesis Data Streams rates
  • Approximately $0.015 per GB ingested
  • Can be expensive at scale (millions of requests)

9. Origin Shield

  • $0.010 per 10,000 requests to Origin Shield
  • Reduces origin load by acting as additional cache layer
  • Available in 12 AWS regions

Flat-Rate Pricing Plans (New November 2025)

AWS introduced simplified flat-rate pricing alongside traditional pay-as-you-go:

Tier Monthly Cost Included Traffic Overage Rate Best For
Free $0 1 TB data transfer + 10M requests Pay-as-you-go rates Personal projects, testing
Pro $15 1 TB data transfer + 10M requests $0.040/GB, $0.005/10K req Small websites, blogs
Business $200 10 TB data transfer + 100M requests $0.030/GB, $0.004/10K req Growing businesses
Premium $1,000 100 TB data transfer + 1B requests $0.020/GB, $0.003/10K req Enterprise applications

Key Benefits of Flat-Rate Plans:

  • Predictable monthly billing
  • Simplified cost forecasting
  • No need to track regional variations
  • Automatic volume discounts built-in
  • Can mix and match per distribution (some pay-as-you-go, some flat-rate)

When to Choose Flat-Rate:

  • Predictable, consistent traffic patterns
  • Simplified billing preferred over optimization
  • Traffic primarily within tier limits
  • Easier budget approval process

When to Choose Pay-As-You-Go:

  • Highly variable traffic (seasonal spikes)
  • Very low or very high traffic volumes
  • Need granular cost control by region
  • Want to optimize with price class restrictions

AWS Free Tier (Always Free)

  • 1 TB of data transfer out per month for 12 months (new AWS accounts)
  • 10,000,000 HTTP/HTTPS requests per month for 12 months
  • 2,000,000 CloudFront Function invocations per month (always free)
  • No charge for data transfer from AWS origins to CloudFront

Cost Drivers

Primary Cost Factors:

  • Geographic traffic distribution: Asia/South America 40-50% more expensive than US/Europe
  • Request volume: HTTPS costs 33% more than HTTP
  • Cache hit ratio: Low hit ratio increases origin fetch and data transfer costs
  • Price class selection: All edge locations vs restricted regions
  • Invalidation frequency: Beyond 1,000 paths/month adds costs
  • Lambda@Edge usage: Heavy compute increases costs significantly
  • Compression settings: Uncompressed traffic costs 3-4x more

Secondary Cost Factors:

  • Origin-to-CloudFront data transfer in different regions
  • Failed origin fetches (still charged for CloudFront requests)
  • Real-time logging at high volume
  • Dedicated IP SSL certificates ($600/month)
  • Access log storage in S3
  • WAF charges (separate service, $5/month + rules + requests)

Common Hidden Costs

Hidden Cost Description Impact Mitigation
Cross-region origin transfers Data transfer from origin region to CloudFront edge $0.02/GB inter-region Collocate origin near CloudFront regional cache
Failed origin fetches Charged for CloudFront delivery even if origin errors Wasted spend on errors Monitor origin health, implement proper caching
Lambda@Edge cold starts High memory allocation for infrequent functions Increased GB-second charges Use CloudFront Functions or optimize memory
Real-time logs at scale Kinesis ingestion for millions of requests $150-500+/month Use standard logs, sample real-time logs at 10%
Invalidation overuse Beyond 1,000 paths per month $0.005/path adds up Use versioned URLs instead
Dedicated IP SSL Legacy SSL implementation $600/month per distribution Migrate to SNI (free)
S3 log storage Access logs accumulate quickly $0.023/GB/month + retrieval Implement S3 lifecycle policies (delete after 90 days)
WAF per-request charges $0.60 per million requests Adds 10-30% to CloudFront bill Optimize rules, use managed rule groups efficiently

Real-World Cost Examples (2025)

Example 1: Small Blog/Portfolio Site

Traffic Profile:

  • 100 GB/month data transfer (US/Europe)
  • 500,000 HTTPS requests/month
  • 95% cache hit ratio

Pay-As-You-Go Cost:

Data Transfer: 100GB × $0.085 = $8.50
HTTPS Requests: 50 × $0.0100 = $0.50
Total: $9.00/month
Enter fullscreen mode Exit fullscreen mode

Flat-Rate (Pro Plan) Cost:

Pro Plan: $15/month (includes 1TB + 10M requests)
Total: $15/month
Enter fullscreen mode Exit fullscreen mode

Recommendation: Pay-as-you-go saves $6/month (40% cheaper)

Example 2: Medium E-Commerce Site

Traffic Profile:

  • 5 TB/month data transfer (60% US, 30% Europe, 10% Asia)
  • 50 million HTTPS requests/month
  • 85% cache hit ratio
  • 500 invalidations/month

Detailed Calculation:

Data Transfer:
- US: 3TB × $0.085 = $255.00
- Europe: 1.5TB × $0.085 = $127.50
- Asia: 0.5TB × $0.120 = $60.00

HTTPS Requests: 5,000 × $0.0100 = $50.00
Invalidations: FREE (under 1,000 paths)

Total: $492.50/month
Enter fullscreen mode Exit fullscreen mode

Flat-Rate (Business Plan):

Business Plan: $200/month (includes 10TB + 100M requests)
No overage (within limits)
Total: $200/month
Enter fullscreen mode Exit fullscreen mode

Recommendation: Flat-rate saves $292.50/month (59% cheaper)

Example 3: Large Video Streaming Platform

Traffic Profile:

  • 150 TB/month data transfer (global distribution)
  • 500 million HTTPS requests/month
  • 98% cache hit ratio (video segments cached aggressively)
  • Origin Shield enabled
  • Lambda@Edge for authentication (10M invocations, 128MB, 50ms)

Detailed Calculation:

Data Transfer (weighted average across regions):
- First 10TB: 10TB × $0.095 (avg) = $950.00
- Next 40TB: 40TB × $0.090 = $3,600.00
- Next 100TB: 100TB × $0.075 = $7,500.00

HTTPS Requests: 50,000 × $0.0100 = $500.00

Origin Shield: 500M × $0.010/10K = $500.00

Lambda@Edge:
- Requests: 10M × $0.60/1M = $6.00
- Duration: 10M × 0.128GB × 0.05s × $0.00005001 = $3.20
- Subtotal: $9.20

Total: $13,059.20/month
Enter fullscreen mode Exit fullscreen mode

Flat-Rate (Premium Plan + Overages):

Premium Plan: $1,000/month (includes 100TB + 1B requests)
Overage: 50TB × $0.020 = $1,000.00
Origin Shield: $500.00
Lambda@Edge: $9.20

Total: $2,509.20/month
Enter fullscreen mode Exit fullscreen mode

Recommendation: Flat-rate saves $10,550/month (81% cheaper) for high-volume predictable traffic

Example 4: Global SaaS API Platform

Traffic Profile:

  • 25 TB/month data transfer (40% US, 30% Europe, 20% Asia, 10% Other)
  • 1 billion API requests/month (HTTPS)
  • 40% cache hit ratio (dynamic APIs)
  • CloudFront Functions for JWT validation (1B invocations)
  • WAF enabled with rate limiting

Detailed Calculation:

Data Transfer:
- US (10TB): (10TB × $0.085) + (0 × $0.080) = $850.00
- Europe (7.5TB): $637.50
- Asia (5TB): $600.00
- Other (2.5TB): $275.00

HTTPS Requests: 100,000 × $0.0100 = $1,000.00

CloudFront Functions: 1,000 × $0.10/1M = $100.00

WAF (separate service):
- Web ACL: $5.00
- Rules (5): $5.00
- Requests: 1B × $0.60/1M = $600.00
- Subtotal: $610.00

Total: $4,072.50/month
Enter fullscreen mode Exit fullscreen mode

With Price Class Optimization (US + Europe only):

Data Transfer (excluding Asia/Other):
- US (10TB): $850.00
- Europe (7.5TB): $637.50

Requests: $1,000.00
CloudFront Functions: $100.00
WAF: $610.00

Total: $3,197.50/month
Savings: $875/month (21% reduction)
Enter fullscreen mode Exit fullscreen mode

FinOps Optimization Strategies (2025)

1. Maximize Cache Hit Ratio (Highest Impact)

Target: 85-95% cache hit ratio

Tactics:

  • Increase TTL for static content to 30+ days (2,592,000 seconds)
  • Normalize cache keys (case-insensitive, parameter ordering)
  • Use cache policies with whitelist approach (only forward necessary headers/cookies)
  • Separate cache behaviors for static vs dynamic content
  • Implement versioned URLs (app.v123.js) instead of frequent invalidations

Cost Impact: Every 10% improvement in cache hit ratio reduces origin costs by ~10% and data transfer by 5-8%

Example: Improving from 70% to 90% cache hit ratio on 10TB/month site:

  • Before: 3TB origin fetches + 7TB cached = $950/month
  • After: 1TB origin fetches + 9TB cached = $850/month
  • Savings: $100/month (11% reduction)

2. Enable Compression (Quick Win)

Tactic:

  • Enable automatic Gzip/Brotli compression in CloudFront
  • Compress text-based content at origin for consistent savings

Cost Impact: 70-80% reduction in data transfer for HTML, CSS, JS, JSON

Example: 5TB/month of uncompressed text content:

  • Without compression: 5TB × $0.085 = $425/month
  • With compression: 1TB × $0.085 = $85/month
  • Savings: $340/month (80% reduction)

3. Optimize Price Class Selection

Tactic:

  • Use "PriceClass_100" (US, Europe, Israel) for Western-focused audiences
  • Use "PriceClass_200" (adds Asia, Africa, Middle East) for global audiences
  • Analyze traffic logs to identify minimal-traffic expensive regions

Cost Impact: 20-30% savings by excluding expensive edge locations

Example: 10TB/month with 5% traffic from South America:

  • All edge locations: (9.5TB × $0.085) + (0.5TB × $0.110) = $863
  • Exclude South America: 10TB × $0.085 = $850 (users routed to nearest included region)
  • Savings: $13/month (1.5% reduction) with minimal latency impact

4. Use CloudFront Functions Over Lambda@Edge

Tactic:

  • Move lightweight logic to CloudFront Functions (URL rewrites, header manipulation)
  • Reserve Lambda@Edge for complex operations requiring external API calls

Cost Impact: 10x cost reduction for eligible use cases

Example: 100M invocations/month for URL normalization:

  • Lambda@Edge: 100M × $0.60/1M = $60 + duration charges (~$30) = $90/month
  • CloudFront Functions: 100M × $0.10/1M = $10/month
  • Savings: $80/month (89% reduction)

5. Optimize Invalidations

Tactic:

  • Use versioned URLs (style.v123.css) instead of invalidating /style.css
  • Batch invalidations to stay under 1,000 free paths/month
  • Use wildcard invalidations (/*) when bulk updates needed (counts as 1 path)

Cost Impact: Eliminate invalidation costs entirely

Example: Site deploying 5x/day with 50 files each (7,500 invalidations/month):

  • With invalidations: (7,500 - 1,000) × $0.005 = $32.50/month
  • With versioned URLs: $0/month
  • Savings: $32.50/month (100% elimination)

6. Implement Origin Shield (For High-Traffic Sites)

Tactic:

  • Enable Origin Shield in region closest to origin
  • Consolidates requests from multiple edge locations
  • Reduces origin load and data transfer

Cost Impact: Origin Shield costs $0.010/10K requests but can save more in origin infrastructure

When to Use: Traffic >50TB/month or high origin compute costs

Example: 100M origin requests/month causing EC2 scaling:

  • Origin Shield cost: 10,000 × $0.010 = $100/month
  • Origin infrastructure savings: Reduced from 20 → 5 EC2 instances = $900/month saved
  • Net savings: $800/month

7. Choose Right Pricing Model

Decision Matrix:

Use Pay-As-You-Go If: Use Flat-Rate If:
Traffic < 500GB/month or > 100TB/month Traffic 1-50TB/month with consistency
Highly variable traffic (3x+ seasonal spikes) Predictable monthly traffic (variance <30%)
Need regional optimization (price classes) Want simplified billing and budgeting
Can achieve >90% cache hit ratio Cache hit ratio 60-80% (dynamic content)
Technical team can optimize continuously Limited DevOps resources for optimization

Example: 8TB/month consistent traffic:

  • Pay-as-you-go: ~$680/month (optimized)
  • Flat-rate (Business): $200/month
  • Savings with flat-rate: $480/month (71% reduction)

8. Leverage Data Transfer Waivers

Tactic:

  • Data transfer FROM AWS origins (S3, EC2, ELB) TO CloudFront is FREE
  • Serve large files through CloudFront instead of direct S3 egress

Cost Impact: Eliminate double data transfer charges

Example: 10TB/month video files:

  • Direct S3 egress: 10TB × $0.090/GB = $900/month
  • Via CloudFront: $0 S3→CF + (10TB × $0.085 CF→Internet) = $850/month
  • Savings: $50/month (6% reduction) + CDN benefits

9. Optimize Real-Time Logs

Tactic:

  • Use standard access logs (free, delivered to S3) for most use cases
  • Enable real-time logs only for critical distributions
  • Sample real-time logs at 10-25% instead of 100%
  • Send logs to S3 via Kinesis Firehose (cheaper than CloudWatch Logs)

Cost Impact: 70-90% reduction in logging costs

Example: 100M requests/month with real-time logging:

  • 100% real-time to CloudWatch: ~$150/month (Kinesis + CloudWatch ingestion)
  • 10% sampling to S3: ~$15/month
  • Standard logs only: $0/month (just S3 storage ~$3/month)
  • Savings: $135-147/month

10. Use SNI for SSL Certificates

Tactic:

  • Use SNI (Server Name Indication) instead of dedicated IP custom SSL
  • Modern browsers (>99% of traffic) support SNI

Cost Impact: $600/month savings per distribution

Example: 5 distributions requiring custom SSL:

  • Dedicated IP: 5 × $600 = $3,000/month
  • SNI: $0/month (included)
  • Savings: $3,000/month (100% elimination)

11. Implement Tiered Caching Strategy

Tactic:

  • Use multiple cache behaviors with different TTLs
  • Aggressive caching for immutable content (CSS, images)
  • Moderate caching for semi-static content (product listings)
  • No caching or short TTL for dynamic content (user sessions)

Example Configuration:

/static/*      → TTL: 30 days (2,592,000s)
/images/*      → TTL: 7 days (604,800s)
/api/products  → TTL: 5 minutes (300s)
/api/cart      → TTL: 0 (no caching)
Enter fullscreen mode Exit fullscreen mode

Cost Impact: Optimized balance between freshness and cache efficiency

12. Monitor and Alert on Cost Anomalies

Tactic:

  • Set CloudWatch billing alarms at 80%, 100%, 120% of expected monthly cost
  • Use AWS Cost Explorer to analyze trends and anomalies
  • Tag distributions by project/environment for cost allocation
  • Weekly cost reviews to catch drift early

Tools:

  • AWS Budgets: Set fixed or usage-based budgets
  • Cost Explorer: Identify cost drivers by service, region, tag
  • CloudWatch Metrics: Track data transfer and requests daily

13. Volume Commitment Discounts

Tactic:

  • Contact AWS for Enterprise Discount Program (EDP) if traffic >10TB/month
  • CloudFront Security Bundle: Combines CloudFront + WAF with volume discounts
  • Private pricing agreements for >100TB/month

Cost Impact: 10-40% additional discounts beyond standard tiering

Eligibility: Typically requires:

  • $10,000+/month AWS spend
  • Annual commitment
  • 10TB+/month CloudFront traffic

Cost Optimization Checklist

Immediate Actions (0-1 week):

  • [ ] Enable Gzip/Brotli compression (70-80% savings on text)
  • [ ] Switch dedicated IP SSL to SNI ($600/month savings per distribution)
  • [ ] Review and restrict price class if traffic is regional (20-30% savings)
  • [ ] Set up billing alarms for unexpected cost spikes
  • [ ] Implement versioned URLs to eliminate invalidation costs

Short-term Actions (1-4 weeks):

  • [ ] Analyze and optimize cache hit ratio (target 85%+)
  • [ ] Migrate simple Lambda@Edge to CloudFront Functions (10x cheaper)
  • [ ] Implement separate cache behaviors for static vs dynamic content
  • [ ] Review and optimize query string/cookie forwarding
  • [ ] Disable or sample real-time logs if not critical

Medium-term Actions (1-3 months):

  • [ ] Evaluate flat-rate pricing plans vs pay-as-you-go
  • [ ] Implement origin shield for high-traffic distributions (>50TB/month)
  • [ ] Optimize Lambda@Edge memory allocation and execution time
  • [ ] Set up comprehensive cost allocation tags
  • [ ] Analyze geographic traffic to optimize price classes

Long-term Actions (3-12 months):

  • [ ] Negotiate volume commitment discounts with AWS ($10K+/month spend)
  • [ ] Consider CloudFront Security Bundle for combined savings
  • [ ] Implement automated cost optimization in CI/CD pipelines
  • [ ] Build cost forecasting models based on traffic patterns
  • [ ] Regular quarterly cost optimization reviews

Cost Comparison: 2025 Pricing Models

Scenario: Growing SaaS Application (12TB/month)

Approach Monthly Cost Effort Flexibility Best For
Unoptimized pay-as-you-go $1,200 Low High Quick deployment, no optimization
Optimized pay-as-you-go $780 High High Technical teams, variable traffic
Flat-rate (Business + overage) $260 Low Medium Predictable traffic, simplified billing
Enterprise agreement $650 Medium Low Large scale, multi-year commitment

Conclusion: For 12TB/month predictable traffic, flat-rate Business plan offers 78% savings vs unoptimized and 67% savings vs optimized pay-as-you-go with significantly less operational overhead.

7. Practical Use Cases

Real-World Enterprise Use Cases

1. Global E-Commerce Platform:

  • Serve product images, CSS, JS from CloudFront (reduces S3 egress costs by 60%)
  • API acceleration for checkout and inventory lookups
  • Signed URLs for downloadable digital products
  • WAF rules to block bot traffic and scraping attempts
  • Geographic restrictions for region-specific product catalogs

2. Video Streaming Service (Netflix-style):

  • Adaptive bitrate streaming (HLS/DASH) delivery
  • Lambda@Edge for user authentication and token validation
  • Regional edge caches for popular content
  • Origin failover between multiple S3 buckets
  • Real-time metrics for QoS monitoring

3. SaaS Application with Global Users:

  • Accelerate API responses for dashboard and data queries
  • Cache static assets (React/Angular bundles)
  • Lambda@Edge for A/B testing and feature flags
  • Custom error pages for maintenance windows
  • CORS headers injection via CloudFront Functions

4. Media and Publishing:

  • WordPress/Drupal static asset caching
  • Image optimization via Lambda@Edge (resize, format conversion)
  • Paywall implementation with signed cookies
  • DDoS protection during breaking news traffic spikes
  • Real-time log analysis for content popularity

5. Software Distribution:

  • Deliver OS images, game clients, firmware updates
  • Reduce origin bandwidth costs by 80%+ via edge caching
  • Progressive download optimization for large files
  • Checksum verification at edge
  • Geographic distribution metrics for release planning

6. Mobile App Backend:

  • API Gateway + CloudFront for mobile API delivery
  • JWT validation at edge via CloudFront Functions
  • Binary protocol acceleration (protobuf)
  • Device-specific content delivery based on User-Agent
  • Offline content caching strategy

Startup vs Enterprise Usage

Aspect Startup Enterprise
Primary Use Static website hosting, simple CDN Multi-region applications, complex architectures
Origins Single S3 bucket Multiple origins, origin groups, failover
Customization Basic cache policies Lambda@Edge, CloudFront Functions, custom logic
Security HTTPS, basic WAF rules Advanced WAF, Shield Advanced, field-level encryption
Cost Free tier eligible, price class optimization Reserved capacity, Security Bundle, enterprise discounts
Monitoring Basic CloudWatch metrics Real-time logs, custom dashboards, SIEM integration
Domains 1-2 CNAMEs Hundreds of domains, wildcard certificates

When NOT to Use CloudFront

  • Intranet applications: Internal-only apps with users in single office/datacenter (use VPC endpoints instead)
  • Low traffic websites: Sites with < 1GB/month traffic may not benefit from CDN overhead
  • Frequently changing content: Content with TTL < 1 second (websocket-heavy apps better served directly)
  • Compliance restrictions: Some regulations prohibit data caching outside controlled environments
  • Cost-sensitive internal tools: Development/staging environments don't need global CDN
  • Real-time bidirectional communication: WebRTC, gaming servers need direct UDP/TCP connections
  • Geographic concentration: 100% of users in single city may have latency overhead to edge location

8. Hands-on Examples

AWS CLI Examples

Create a Web Distribution with S3 Origin:

aws cloudfront create-distribution \
  --distribution-config file://distribution-config.json \
  --profile production

# distribution-config.json
{
  "CallerReference": "unique-string-123456",
  "Comment": "Production website distribution",
  "Enabled": true,
  "Origins": {
    "Quantity": 1,
    "Items": [{
      "Id": "S3-my-website-bucket",
      "DomainName": "my-website-bucket.s3.us-east-1.amazonaws.com",
      "S3OriginConfig": {
        "OriginAccessIdentity": ""
      },
      "OriginAccessControlId": "E1234ABCD5678"
    }]
  },
  "DefaultCacheBehavior": {
    "TargetOriginId": "S3-my-website-bucket",
    "ViewerProtocolPolicy": "redirect-to-https",
    "AllowedMethods": {
      "Quantity": 2,
      "Items": ["GET", "HEAD"]
    },
    "Compress": true,
    "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
  }
}
Enter fullscreen mode Exit fullscreen mode

List All Distributions:

aws cloudfront list-distributions \
  --query 'DistributionList.Items[*].[Id,DomainName,Status,Comment]' \
  --output table
Enter fullscreen mode Exit fullscreen mode

Create Cache Invalidation:

aws cloudfront create-invalidation \
  --distribution-id E1234EXAMPLE \
  --paths "/*" "/images/*" "/css/style.css"
Enter fullscreen mode Exit fullscreen mode

Get Invalidation Status:

aws cloudfront get-invalidation \
  --distribution-id E1234EXAMPLE \
  --id I2J3K4L5M6N7O8
Enter fullscreen mode Exit fullscreen mode

Update Distribution Configuration:

# Get current config
aws cloudfront get-distribution-config \
  --id E1234EXAMPLE \
  --output json > current-config.json

# Edit current-config.json with changes

# Update distribution
aws cloudfront update-distribution \
  --id E1234EXAMPLE \
  --distribution-config file://updated-config.json \
  --if-match ETAG_VALUE_FROM_GET
Enter fullscreen mode Exit fullscreen mode

Get Distribution Metrics:

aws cloudwatch get-metric-statistics \
  --namespace AWS/CloudFront \
  --metric-name Requests \
  --dimensions Name=DistributionId,Value=E1234EXAMPLE \
  --start-time 2024-12-20T00:00:00Z \
  --end-time 2024-12-27T00:00:00Z \
  --period 3600 \
  --statistics Sum
Enter fullscreen mode Exit fullscreen mode

Terraform Configuration

Basic CloudFront Distribution with S3 Origin:

# S3 bucket for origin
resource "aws_s3_bucket" "website" {
  bucket = "my-cloudfront-website-origin"
}

resource "aws_s3_bucket_public_access_block" "website" {
  bucket = aws_s3_bucket.website.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# Origin Access Control
resource "aws_cloudfront_origin_access_control" "website" {
  name                              = "website-oac"
  description                       = "OAC for S3 website origin"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

# CloudFront Distribution
resource "aws_cloudfront_distribution" "website" {
  enabled             = true
  is_ipv6_enabled     = true
  comment             = "Production website distribution"
  default_root_object = "index.html"
  price_class         = "PriceClass_100" # US, Europe only

  origin {
    domain_name              = aws_s3_bucket.website.bucket_regional_domain_name
    origin_id                = "S3-${aws_s3_bucket.website.id}"
    origin_access_control_id = aws_cloudfront_origin_access_control.website.id
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-${aws_s3_bucket.website.id}"

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    compress               = true
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  tags = {
    Environment = "production"
    Project     = "website"
  }
}

# S3 bucket policy for CloudFront OAC
resource "aws_s3_bucket_policy" "website" {
  bucket = aws_s3_bucket.website.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid    = "AllowCloudFrontServicePrincipal"
      Effect = "Allow"
      Principal = {
        Service = "cloudfront.amazonaws.com"
      }
      Action   = "s3:GetObject"
      Resource = "${aws_s3_bucket.website.arn}/*"
      Condition = {
        StringEquals = {
          "AWS:SourceArn" = aws_cloudfront_distribution.website.arn
        }
      }
    }]
  })
}

# Output the CloudFront domain
output "cloudfront_domain" {
  value = aws_cloudfront_distribution.website.domain_name
}
Enter fullscreen mode Exit fullscreen mode

Advanced: Custom Domain with ACM Certificate:

# ACM Certificate (must be in us-east-1)
resource "aws_acm_certificate" "website" {
  provider          = aws.us-east-1
  domain_name       = "www.example.com"
  validation_method = "DNS"

  subject_alternative_names = ["example.com"]

  lifecycle {
    create_before_destroy = true
  }
}

# CloudFront with custom domain
resource "aws_cloudfront_distribution" "website_custom" {
  enabled         = true
  is_ipv6_enabled = true
  aliases         = ["www.example.com", "example.com"]

  origin {
    domain_name              = aws_s3_bucket.website.bucket_regional_domain_name
    origin_id                = "S3-origin"
    origin_access_control_id = aws_cloudfront_origin_access_control.website.id
  }

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD", "OPTIONS"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "S3-origin"
    viewer_protocol_policy = "redirect-to-https"
    compress               = true

    # Use managed cache policy
    cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
  }

  restrictions {
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["US", "CA", "GB", "DE"]
    }
  }

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate.website.arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }

  logging_config {
    include_cookies = false
    bucket          = aws_s3_bucket.logs.bucket_domain_name
    prefix          = "cloudfront/"
  }
}

# Route53 records
resource "aws_route53_record" "website" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.example.com"
  type    = "A"

  alias {
    name                   = aws_cloudfront_distribution.website_custom.domain_name
    zone_id                = aws_cloudfront_distribution.website_custom.hosted_zone_id
    evaluate_target_health = false
  }
}
Enter fullscreen mode Exit fullscreen mode

Lambda@Edge Function for A/B Testing:

# Lambda function code
data "archive_file" "lambda_edge" {
  type        = "zip"
  source_file = "${path.module}/lambda/ab-test.js"
  output_path = "${path.module}/lambda/ab-test.zip"
}

# IAM role for Lambda@Edge
resource "aws_iam_role" "lambda_edge" {
  name = "cloudfront-lambda-edge-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = [
          "lambda.amazonaws.com",
          "edgelambda.amazonaws.com"
        ]
      }
    }]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_edge" {
  role       = aws_iam_role.lambda_edge.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# Lambda function (must be in us-east-1)
resource "aws_lambda_function" "ab_test" {
  provider         = aws.us-east-1
  filename         = data.archive_file.lambda_edge.output_path
  function_name    = "cloudfront-ab-test"
  role             = aws_iam_role.lambda_edge.arn
  handler          = "ab-test.handler"
  source_code_hash = data.archive_file.lambda_edge.output_base64sha256
  runtime          = "nodejs18.x"
  publish          = true
  timeout          = 5
  memory_size      = 128
}

# Attach Lambda@Edge to CloudFront
resource "aws_cloudfront_distribution" "with_lambda" {
  # ... other configuration ...

  default_cache_behavior {
    # ... other settings ...

    lambda_function_association {
      event_type   = "viewer-request"
      lambda_arn   = aws_lambda_function.ab_test.qualified_arn
      include_body = false
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Lambda@Edge JavaScript (ab-test.js):

'use strict';

exports.handler = (event, context, callback) => {
    const request = event.Records.cf.request;
    const headers = request.headers;

    // Check for existing A/B test cookie
    const cookieHeader = headers.cookie ? headers.cookie.value : '';
    let variant = 'A';

    if (cookieHeader.includes('ab-variant=B')) {
        variant = 'B';
    } else if (!cookieHeader.includes('ab-variant=A')) {
        // Assign variant randomly for new users
        variant = Math.random() < 0.5 ? 'A' : 'B';
    }

    // Modify request URI based on variant
    if (variant === 'B') {
        request.uri = request.uri.replace(/^\//, '/variant-b/');
    }

    // Add variant cookie to response
    const response = {
        status: '200',
        headers: {
            'set-cookie': [{
                key: 'Set-Cookie',
                value: `ab-variant=${variant}; Path=/; Max-Age=2592000; Secure; HttpOnly`
            }],
            'x-ab-variant': [{
                key: 'X-AB-Variant',
                value: variant
            }]
        }
    };

    callback(null, request);
};
Enter fullscreen mode Exit fullscreen mode

CloudFormation Template

Complete Distribution with Monitoring:

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFront distribution with S3 origin and monitoring

Parameters:
  DomainName:
    Type: String
    Description: Custom domain name for CloudFront
    Default: www.example.com

Resources:
  OriginBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${AWS::StackName}-origin'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  OriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Name: !Sub '${AWS::StackName}-oac'
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4

  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        HttpVersion: http2and3
        IPV6Enabled: true
        Comment: !Sub 'Distribution for ${AWS::StackName}'
        DefaultRootObject: index.html

        Origins:
          - Id: S3Origin
            DomainName: !GetAtt OriginBucket.RegionalDomainName
            OriginAccessControlId: !GetAtt OriginAccessControl.Id
            S3OriginConfig: {}

        DefaultCacheBehavior:
          TargetOriginId: S3Origin
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
          CachedMethods:
            - GET
            - HEAD
          Compress: true
          CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
          OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf

        CustomErrorResponses:
          - ErrorCode: 403
            ResponseCode: 404
            ResponsePagePath: /404.html
            ErrorCachingMinTTL: 300
          - ErrorCode: 404
            ResponseCode: 404
            ResponsePagePath: /404.html
            ErrorCachingMinTTL: 300

        PriceClass: PriceClass_100

        ViewerCertificate:
          CloudFrontDefaultCertificate: true

        Logging:
          Bucket: !GetAtt LogsBucket.DomainName
          Prefix: cloudfront/
          IncludeCookies: false

  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref OriginBucket
      PolicyDocument:
        Statement:
          - Sid: AllowCloudFrontServicePrincipal
            Effect: Allow
            Principal:
              Service: cloudfront.amazonaws.com
            Action: s3:GetObject
            Resource: !Sub '${OriginBucket.Arn}/*'
            Condition:
              StringEquals:
                AWS:SourceArn: !Sub 'arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}'

  LogsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${AWS::StackName}-logs'
      LifecycleConfiguration:
        Rules:
          - Id: DeleteOldLogs
            Status: Enabled
            ExpirationInDays: 90

  CacheHitRateAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub '${AWS::StackName}-low-cache-hit-rate'
      AlarmDescription: Alert when cache hit rate drops below 85%
      MetricName: CacheHitRate
      Namespace: AWS/CloudFront
      Statistic: Average
      Period: 300
      EvaluationPeriods: 2
      Threshold: 85
      ComparisonOperator: LessThanThreshold
      Dimensions:
        - Name: DistributionId
          Value: !Ref CloudFrontDistribution

Outputs:
  DistributionId:
    Value: !Ref CloudFrontDistribution
    Export:
      Name: !Sub '${AWS::StackName}-distribution-id'

  DistributionDomain:
    Value: !GetAtt CloudFrontDistribution.DomainName
    Export:
      Name: !Sub '${AWS::StackName}-domain'

  OriginBucketName:
    Value: !Ref OriginBucket
    Export:
      Name: !Sub '${AWS::StackName}-origin-bucket'
Enter fullscreen mode Exit fullscreen mode

9. Best Practices

Architecture Best Practices

  • Use origin groups with primary and secondary origins for automatic failover
  • Implement multiple cache behaviors for different content types (static vs dynamic)
  • Leverage regional edge caches by setting appropriate TTLs (>24 hours for popular content)
  • Use separate distributions for different environments (dev, staging, prod) to isolate configurations
  • Implement origin connection pooling and keep-alive for high-traffic applications
  • Use CloudFront Functions for lightweight transformations instead of Lambda@Edge (cost and latency)
  • Deploy Lambda@Edge functions in us-east-1 region (global replication happens automatically)
  • Use versioned URLs or query strings instead of frequent invalidations
  • Implement proper cache key strategies using cache policies (avoid forwarding unnecessary parameters)

Operational Best Practices

  • Enable access logging to S3 for compliance and debugging (with lifecycle policies for cost control)
  • Use standard logging initially; upgrade to real-time logs only when necessary (significant cost difference)
  • Configure CloudWatch alarms for key metrics: 4xx/5xx error rates, cache hit ratio, origin latency
  • Implement automated invalidation in CI/CD pipelines for application deployments
  • Use distribution tags for cost allocation and resource organization
  • Maintain separate IAM roles for distribution management vs content publishing
  • Document custom cache behaviors and origin configurations in infrastructure-as-code
  • Test configuration changes in non-production distributions before deploying to production
  • Use AWS Config rules to enforce security standards across distributions
  • Implement change management process for distribution updates (use ETag for optimistic locking)

Security Best Practices

  • Always enforce HTTPS with "redirect-to-https" or "https-only" viewer protocol policy
  • Use TLS 1.2 or higher as minimum protocol version (disable TLS 1.0/1.1)
  • Implement AWS WAF with OWASP top 10 rules for public-facing applications
  • Use Origin Access Control (OAC) instead of legacy Origin Access Identity (OAI) for S3
  • Enable AWS Shield Advanced for mission-critical applications requiring DDoS response team
  • Implement signed URLs/cookies with short expiration times (hours, not days) for private content
  • Use field-level encryption for sensitive data like credit cards or personally identifiable information
  • Add security headers via response headers policy (HSTS, X-Content-Type-Options, X-Frame-Options, CSP)
  • Restrict geographic access using geo-blocking when appropriate for compliance
  • Rotate custom SSL certificates 30 days before expiration (or use ACM for automatic rotation)
  • Implement custom error pages to avoid exposing origin server information
  • Use Lambda@Edge for JWT validation or custom authentication at the edge
  • Enable CloudTrail logging for API calls to CloudFront for audit trails
  • Regularly review and update WAF rules based on threat intelligence
  • Implement rate limiting via AWS WAF to prevent abuse and API exhaustion

Performance Best Practices

  • Maximize cache hit ratio by normalizing cache keys and avoiding unnecessary variations
  • Set aggressive TTLs for static content (weeks/months) and reasonable TTLs for dynamic content (minutes/hours)
  • Enable automatic compression (Gzip/Brotli) for text-based content to reduce data transfer
  • Use HTTP/2 and HTTP/3 for multiplexing and faster connection establishment
  • Implement image optimization via Lambda@Edge (WebP conversion, responsive sizing)
  • Configure origin response headers correctly (Cache-Control, Expires, ETag)
  • Use query string whitelisting to cache only relevant parameters
  • Implement origin shield for high-traffic sites with multiple edge locations hitting same origin
  • Pre-warm cache for major launches or traffic spikes by programmatically requesting content
  • Use CloudFront Functions for URL rewrites instead of origin redirects (eliminates round-trip)
  • Optimize Lambda@Edge function memory and timeout settings for cost and performance
  • Monitor and optimize origin response times (CloudFront can't accelerate slow origins)

Cost Optimization Best Practices

  • Select appropriate price class based on user geographic distribution
  • Use versioned file names (app.v123.js) instead of cache invalidations
  • Batch invalidation requests to stay under 1,000 free paths per month
  • Implement wildcard invalidations (/*) instead of per-file when bulk updates needed
  • Enable compression to reduce data transfer costs by 70-80%
  • Use CloudFront Functions instead of Lambda@Edge for simple transformations (10x cheaper)
  • Optimize Lambda@Edge memory allocation and execution time to reduce compute costs
  • Use SNI for custom SSL certificates instead of dedicated IP ($600/month savings)
  • Implement proper cache strategies to reduce origin fetch costs
  • Monitor cache hit ratio and optimize to achieve >85% for cost efficiency
  • Use S3 Intelligent-Tiering for origin content to optimize storage costs
  • Consider CloudFront Security Bundle for combined CloudFront + WAF discounts
  • Set up cost allocation tags to track per-project or per-environment spending
  • Use AWS Cost Explorer to identify cost anomalies and optimization opportunities

10. Common Pitfalls & Mistakes

Configuration Mistakes

  • Forwarding all headers to origin: Breaks caching by making every request unique (cache hit ratio drops to near zero)
  • Not using cache policies: Using legacy cache settings instead of managed or custom cache policies
  • Incorrect origin protocol: Using HTTP for S3 website endpoints instead of S3 REST API endpoints with OAC
  • Missing compression: Not enabling automatic compression, wasting 70%+ bandwidth on text content
  • Wrong price class: Using "All Edge Locations" when user base is regional (unnecessary cost)
  • Public S3 buckets: Exposing S3 bucket publicly and using website endpoint instead of OAC
  • Invalidation overuse: Invalidating entire distribution daily instead of using versioned URLs
  • No default root object: Forgetting to set index.html, causing 403 errors for directory requests
  • Mixed content errors: Using HTTP origins when CloudFront serves HTTPS (browser blocks mixed content)

Performance Issues

  • Low cache hit ratio: Not optimizing cache keys, forwarding unnecessary cookies/headers
  • Origin latency: CloudFront can't compensate for slow origin response times (optimize origin first)
  • Large Lambda@Edge functions: Using heavy dependencies or long execution times at edge
  • No regional edge cache utilization: Setting TTLs too low (< 24 hours) prevents regional cache benefits
  • Query string forwarding: Forwarding all query strings when only specific parameters affect content
  • Cookie forwarding: Forwarding all cookies to origin when only session cookies needed
  • Case-sensitive URLs: Not normalizing URLs (same content served from /Image.jpg and /image.jpg)
  • Missing pre-warming: Not pre-populating cache before major traffic events
  • Origin connection limits: Origin server can't handle concurrent connections from edge locations
  • No origin shield: Multiple edge locations simultaneously requesting same uncached content from origin

Security Risks

  • HTTP allowed: Not enforcing HTTPS, exposing user data in transit
  • Old TLS versions: Allowing TLS 1.0/1.1 which have known vulnerabilities
  • No WAF protection: Exposing public APIs without Web Application Firewall rules
  • Overly permissive signed URLs: Setting expiration times in days/weeks instead of hours
  • Missing security headers: Not adding HSTS, CSP, X-Frame-Options headers
  • Direct origin access: Allowing internet access to origin servers instead of restricting to CloudFront IPs
  • No geo-restriction: Not implementing geographic blocks when compliance requires it
  • Exposed S3 bucket: S3 bucket policy allows public read access alongside CloudFront OAC
  • No monitoring/alerting: Not setting up CloudWatch alarms for 4xx/5xx error spikes
  • Logging disabled: No audit trail for security investigations or compliance requirements
  • Weak origin authentication: Not validating custom headers from CloudFront to origin
  • Field-level encryption not used: Sending sensitive PII through CDN without encryption

Cost Surprises

  • Unexpected geographic traffic: High costs from South America/Asia traffic without price class restrictions
  • Invalidation overuse: Exceeding 1,000 free paths per month with frequent invalidations
  • Real-time logs at scale: Enabling real-time logs for high-traffic sites (can cost thousands/month)
  • Lambda@Edge cold starts: High memory allocation and frequent invocations driving up costs
  • Cross-region origin fetches: Origin in different region than CloudFront causing double data transfer charges
  • Dedicated IP SSL: Accidentally using dedicated IP custom SSL ($600/month per distribution)
  • Failed origin fetches: CloudFront still charges for requests even when origin returns errors
  • No compression: Paying 3-4x more for data transfer without Gzip/Brotli enabled
  • Low cache hit ratio: High origin fetch costs due to poor caching strategy
  • Unnecessary distribution count: Creating separate distributions when cache behaviors would suffice

Operational Mistakes

  • No testing in lower environments: Deploying configuration changes directly to production
  • Missing ETag in updates: Not using ETag for optimistic locking causing conflicting updates
  • Hardcoded distribution IDs: Not using variables/parameters in CI/CD pipelines
  • No rollback plan: No ability to quickly revert to previous working configuration
  • Undocumented custom logic: Lambda@Edge or CloudFront Functions without documentation
  • No health checks: Not monitoring origin health before deploying changes
  • Synchronous deployments: Waiting for distribution deployment (10-15 minutes) in deployment pipeline
  • Missing alarms: No CloudWatch alarms for critical metrics (error rates, cache hit ratio)
  • No cost monitoring: Not setting billing alarms for unexpected usage spikes
  • Origin certificate expiration: Custom origin SSL certificates expiring without renewal process

11. Monitoring, Logging & Troubleshooting

Key CloudWatch Metrics

Metric Description Threshold Action
Requests Total number of requests N/A Track traffic patterns, capacity planning
BytesDownloaded Total bytes served to viewers N/A Monitor bandwidth usage, cost tracking
4xxErrorRate Percentage of 4xx errors > 5% Check cache behaviors, URL patterns, origin config
5xxErrorRate Percentage of 5xx errors > 1% Investigate origin health, timeout settings
CacheHitRate Percentage of requests served from cache < 85% Optimize cache policies, TTLs, cache keys
OriginLatency Time to first byte from origin > 2000ms Optimize origin performance, consider caching
BytesUploaded Data uploaded to origin (POST/PUT) N/A Monitor write operations, API usage

Standard Logging vs Real-Time Logs

Standard Access Logs (Batch):

  • Delivered to S3 bucket within minutes to hours
  • No additional charge (only S3 storage costs)
  • Contains all request details (timestamp, IP, URI, status, user-agent, etc.)
  • Best for: Cost-effective historical analysis, compliance, debugging
  • Log fields: 30+ fields including geo data, SSL protocol, cache behavior

Real-Time Logs:

  • Delivered to Kinesis Data Streams within seconds
  • Charged per log line ($0.01 per million lines)
  • Configurable fields (select only needed fields)
  • Best for: Security monitoring, real-time analytics, immediate alerting
  • Integration: Stream to Elasticsearch, Splunk, custom processing

Log Configuration Example (Terraform):

resource "aws_s3_bucket" "cloudfront_logs" {
  bucket = "my-cloudfront-logs"
}

resource "aws_cloudfront_distribution" "main" {
  # ... other config ...

  logging_config {
    include_cookies = false
    bucket          = aws_s3_bucket.cloudfront_logs.bucket_domain_name
    prefix          = "cloudfront/"
  }
}

# Real-time logs configuration
resource "aws_kinesis_stream" "cloudfront_logs" {
  name             = "cloudfront-realtime-logs"
  shard_count      = 2
  retention_period = 24
}

resource "aws_cloudfront_realtime_log_config" "main" {
  name          = "realtime-logs"
  sampling_rate = 100 # 100% of requests

  endpoint {
    stream_type = "Kinesis"

    kinesis_stream_config {
      role_arn   = aws_iam_role.cloudfront_realtime_logs.arn
      stream_arn = aws_kinesis_stream.cloudfront_logs.arn
    }
  }

  fields = [
    "timestamp",
    "c-ip",
    "cs-uri-stem",
    "sc-status",
    "cs-protocol",
    "cs-bytes",
    "time-taken"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Debugging Strategies

403 Forbidden Errors:

  1. Check S3 bucket policy - ensure CloudFront OAC has GetObject permission
  2. Verify Origin Access Control is attached to distribution
  3. Check S3 public access block settings (should block public access)
  4. Confirm object exists in bucket and has correct permissions
  5. Review CloudFront cache behavior path patterns
  6. Check WAF rules if enabled (may be blocking requests)

504 Gateway Timeout:

  1. Check origin server health and response times
  2. Increase origin response timeout in CloudFront (default 30s)
  3. Verify origin server can handle concurrent connections from edge locations
  4. Check origin security groups allow CloudFront IPs
  5. Review origin server logs for errors or resource exhaustion
  6. Consider implementing origin shield to reduce origin load

Low Cache Hit Ratio:

  1. Review CloudWatch CacheHitRate metric by distribution
  2. Analyze access logs to identify unique URLs causing misses
  3. Check if unnecessary query strings or cookies are forwarded
  4. Verify Cache-Control headers from origin are correct
  5. Look for case sensitivity issues in URLs
  6. Check if users are bypassing cache with unique parameters
  7. Review cache policy configuration for header/cookie forwarding

High 4xx Error Rate:

  1. Analyze access logs to identify common 404 URLs
  2. Check for broken links or outdated sitemaps
  3. Verify default root object configuration
  4. Review custom error page configuration
  5. Check if bot traffic is causing errors
  6. Implement WAF rules to block malicious requests

SSL/TLS Certificate Issues:

  1. Verify certificate is in us-east-1 region (ACM requirement for CloudFront)
  2. Check certificate validation status in ACM
  3. Confirm alternate domain names (CNAMEs) match certificate SAN
  4. Verify DNS records point to CloudFront domain
  5. Check certificate expiration date
  6. Test with different browsers (SNI support)

Origin Connection Issues:

  1. Verify origin security groups allow HTTPS from CloudFront managed prefix list
  2. Check origin server SSL certificate validity
  3. Test origin connectivity from edge locations using curl with appropriate headers
  4. Review CloudFront custom origin settings (protocol, port, path)
  5. Check origin keep-alive timeout settings
  6. Verify origin server can handle persistent connections

Useful AWS CLI Commands for Troubleshooting

# Get distribution status and configuration
aws cloudfront get-distribution --id E1234EXAMPLE

# Check recent invalidations
aws cloudfront list-invalidations --distribution-id E1234EXAMPLE --max-items 10

# Get specific metric from CloudWatch
aws cloudwatch get-metric-statistics \
  --namespace AWS/CloudFront \
  --metric-name 4xxErrorRate \
  --dimensions Name=DistributionId,Value=E1234EXAMPLE \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average

# Download and analyze access logs
aws s3 sync s3://my-logs-bucket/cloudfront/ ./logs/
zgrep "503" logs/*.gz | awk '{print $5, $8, $9}' | sort | uniq -c | sort -rn

# Test CloudFront response headers
curl -I https://d1234abcd.cloudfront.net/index.html -H "User-Agent: Mozilla/5.0"

# Check cache status
curl -I https://d1234abcd.cloudfront.net/image.jpg | grep -i "x-cache"
# Hit from cloudfront = cached
# Miss from cloudfront = not cached, fetched from origin
Enter fullscreen mode Exit fullscreen mode

CloudWatch Dashboard Example

Create comprehensive monitoring dashboard:

  • Traffic: Requests per minute (line graph)
  • Errors: 4xx and 5xx error rates (line graph with alarm thresholds)
  • Performance: Cache hit rate, origin latency (line graphs)
  • Data Transfer: Bytes downloaded (area chart)
  • Geographic Distribution: Requests by edge location (bar chart)
  • Status Codes: Distribution of status codes (pie chart)

Alerting Strategy

Critical Alarms (Page oncall):

  • 5xx error rate > 5% for 2 consecutive periods
  • Distribution disabled or in error state
  • Certificate expiration within 7 days

Warning Alarms (Slack/email):

  • 4xx error rate > 10% for 5 minutes
  • Cache hit rate < 70% for 15 minutes
  • Origin latency > 5000ms for 10 minutes
  • Monthly cost exceeds budget threshold by 20%

Informational Alarms (Daily digest):

  • Traffic increase/decrease > 50% compared to previous week
  • New geographic regions detected in traffic
  • Lambda@Edge error rate > 1%

12. Integration With Other AWS Services

Common AWS Service Integrations

Amazon S3:

  • Use case: Static website hosting, origin for media files, application assets
  • Integration: Origin Access Control (OAC) for secure bucket access
  • Pattern: S3 bucket → CloudFront distribution → Users
  • Best practice: Use S3 bucket regional endpoint, not website endpoint
  • Cost benefit: CloudFront egress cheaper than direct S3 egress

Amazon EC2 / Application Load Balancer (ALB):

  • Use case: Dynamic web applications, API backends
  • Integration: Custom origin with ALB as endpoint
  • Pattern: CloudFront → ALB → Target Group (EC2/ECS)
  • Best practice: Use custom header validation to restrict origin access to CloudFront
  • Security: ALB security group allows CloudFront managed prefix list

AWS Lambda & Lambda@Edge:

  • Use case: Serverless compute at edge for request/response manipulation
  • Integration: Lambda@Edge attached to CloudFront behaviors
  • Pattern: User request → CloudFront → Lambda@Edge → Origin
  • Use cases: A/B testing, authentication, image optimization, header manipulation
  • Limitation: Functions must be in us-east-1, 128MB package size limit

AWS Certificate Manager (ACM):

  • Use case: Free SSL/TLS certificates with automatic renewal
  • Integration: Attach ACM certificate to CloudFront distribution
  • Requirement: Certificate must be in us-east-1 region
  • Best practice: Use DNS validation for automatic renewal
  • Cost: Free for CloudFront (dedicated IP SSL costs $600/month)

Amazon Route 53:

  • Use case: DNS routing to CloudFront distributions
  • Integration: Alias records pointing to CloudFront domain
  • Pattern: Route 53 hosted zone → A/AAAA alias → CloudFront distribution
  • Features: Geolocation routing, weighted routing, health checks
  • Best practice: Use alias records (free) instead of CNAME records

AWS WAF (Web Application Firewall):

  • Use case: Application-layer security, DDoS protection, bot mitigation
  • Integration: Attach Web ACL to CloudFront distribution
  • Rules: Rate limiting, geo-blocking, SQL injection protection, XSS prevention
  • Managed rules: AWS Managed Rules, marketplace rules from security vendors
  • Cost: $5/month per Web ACL + $1 per rule + $0.60 per million requests

AWS Shield:

  • Standard: Automatic DDoS protection included free with CloudFront
  • Advanced: $3,000/month with 24/7 DDoS Response Team, cost protection
  • Integration: Enabled at account level, automatically protects CloudFront distributions
  • Features: Real-time attack notifications, forensics, incident response

Amazon CloudWatch:

  • Use case: Monitoring, metrics, alarms, dashboards
  • Metrics: Requests, error rates, cache hit ratio, latency, data transfer
  • Logs: Standard access logs (S3), real-time logs (Kinesis)
  • Alarms: Error rate thresholds, cache performance, cost anomalies
  • Integration: Native CloudWatch metrics available for all distributions

AWS CloudTrail:

  • Use case: API call logging for compliance and security auditing
  • Events: CreateDistribution, UpdateDistribution, DeleteDistribution
  • Pattern: CloudTrail → S3 bucket (optional: CloudWatch Logs)
  • Best practice: Enable CloudTrail in all regions for complete audit trail
  • Compliance: Required for SOC 2, PCI-DSS, HIPAA compliance

Amazon CloudWatch Logs:

  • Use case: Centralized log aggregation and analysis
  • Integration: Real-time logs from CloudFront to Kinesis to CloudWatch Logs
  • Pattern: CloudFront → Kinesis → Lambda → CloudWatch Logs Insights
  • Use cases: Real-time security monitoring, anomaly detection
  • Cost: $0.50/GB ingested + $0.03/GB storage

AWS Elemental MediaStore / MediaPackage:

  • Use case: Live and on-demand video streaming
  • Integration: CloudFront distribution with MediaStore/MediaPackage origin
  • Protocols: HLS, DASH, CMAF, Smooth Streaming
  • Pattern: Encoder → MediaLive → MediaPackage → CloudFront → Viewers
  • Best practice: Use origin shield to reduce origin load for live streams

AWS API Gateway:

  • Use case: RESTful API acceleration and caching
  • Integration: CloudFront distribution with API Gateway as custom origin
  • Benefits: Geographic distribution, DDoS protection, lower latency
  • Pattern: CloudFront → API Gateway → Lambda / HTTP backend
  • Cost optimization: Cache API responses at CloudFront instead of API Gateway

Amazon ElastiCache (Redis/Memcached):

  • Use case: Origin-side caching for database queries
  • Integration: Indirect - EC2/Lambda origin uses ElastiCache
  • Pattern: CloudFront → ALB → EC2 → ElastiCache → RDS
  • Strategy: Multi-layer caching (CloudFront edge + origin ElastiCache)

AWS Secrets Manager:

  • Use case: Store signed URL generation keys, API keys for Lambda@Edge
  • Integration: Lambda@Edge fetches secrets at runtime
  • Best practice: Cache secrets in Lambda global scope to reduce API calls
  • Security: Use IAM roles for Lambda@Edge to access Secrets Manager

Amazon DynamoDB:

  • Use case: Store user sessions, A/B test configurations for Lambda@Edge
  • Integration: Lambda@Edge queries DynamoDB for dynamic logic
  • Pattern: User request → CloudFront → Lambda@Edge → DynamoDB → Origin
  • Performance: Use DynamoDB global tables for multi-region low latency

AWS Organizations & AWS Control Tower:

  • Use case: Multi-account governance, centralized security policies
  • Integration: Service Control Policies (SCPs) to enforce CloudFront security standards
  • Pattern: Organization → OU → Member accounts with CloudFront distributions
  • Best practice: Centralized logging to security account, enforce HTTPS via SCP

Architectural Patterns

Pattern 1: Static Website with S3 + CloudFront + Route 53

Route 53 (DNS)
    ↓
CloudFront Distribution
    ↓
S3 Bucket (origin with OAC)
    ↓
Website content (HTML, CSS, JS, images)
Enter fullscreen mode Exit fullscreen mode

Use case: Marketing sites, documentation, SPAs (React/Angular/Vue)

Pattern 2: Dynamic Web Application

Route 53
    ↓
CloudFront Distribution
    ↓
Application Load Balancer
    ↓
EC2 Auto Scaling Group / ECS Fargate
    ↓
RDS Database
Enter fullscreen mode Exit fullscreen mode

Use case: E-commerce, SaaS applications, content management systems

Pattern 3: API Acceleration

Route 53
    ↓
CloudFront Distribution
    ↓
API Gateway
    ↓
Lambda Functions
    ↓
DynamoDB / RDS
Enter fullscreen mode Exit fullscreen mode

Use case: Mobile app backends, microservices APIs, GraphQL APIs

Pattern 4: Video Streaming (OTT Platform)

Video Encoder
    ↓
S3 Bucket (HLS/DASH segments)
    ↓
CloudFront Distribution (with signed URLs)
    ↓
Video players (web, mobile, TV)
Enter fullscreen mode Exit fullscreen mode

Use case: Netflix-style streaming, live sports, webinars

Pattern 5: Multi-Region Active-Active

Route 53 (latency-based routing)
    ↓
CloudFront Distribution (Origin Groups)
    ↓
Origin Group: Primary (us-east-1) + Secondary (eu-west-1)
    ↓
Regional ALB + EC2/ECS
Enter fullscreen mode Exit fullscreen mode

Use case: Global SaaS applications, disaster recovery, low latency requirements

Pattern 6: Serverless Single Page Application

Route 53
    ↓
CloudFront Distribution
    ↓
Origins:
  - S3 (static assets: /assets/*)
  - API Gateway (API calls: /api/*)
    ↓
Lambda Functions
Enter fullscreen mode Exit fullscreen mode

Use case: Modern web applications with separate frontend and backend

Cross-Account Patterns

Pattern: Centralized CDN Account

Account A (CDN Account)
└── CloudFront Distribution
    ↓
Account B (Content Account)
└── S3 Bucket (cross-account OAC)
    or
Account C (Application Account)
└── ALB (security group allows CloudFront)
Enter fullscreen mode Exit fullscreen mode

Cross-Account S3 Access Configuration:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowCrossAccountCloudFront",
    "Effect": "Allow",
    "Principal": {
      "Service": "cloudfront.amazonaws.com"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::account-b-bucket/*",
    "Condition": {
      "StringEquals": {
        "AWS:SourceArn": "arn:aws:cloudfront::111111111111:distribution/E1234EXAMPLE"
      }
    }
  }]
}
Enter fullscreen mode Exit fullscreen mode

Multi-Region Usage

Pattern: Multi-Region Origin with Failover


CloudFront Distribution
↓
Origin Group:
Primary Origin: ALB in us-east-1
Secondary Origin: ALB in eu-west-1
↓
Automatic failover on 5xx errors or timeout

Enter fullscreen mode Exit fullscreen mode

Terraform Configuration for Origin Failover:

resource "aws_cloudfront_distribution" "multi_region" {
  enabled = true

  origin_group {
    origin_id = "multi-region-group"

    failover_criteria {
      status_codes = [403, 404, 500, 502, 503, 504]
    }

    member {
      origin_id = "primary-us-east-1"
    }

    member {
      origin_id = "secondary-eu-west-1"
    }
  }

  origin {
    origin_id   = "primary-us-east-1"
    domain_name = "primary.us-east-1.elb.amazonaws.com"

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }

    custom_header {
      name  = "X-Custom-Header"
      value = "CloudFrontOrigin"
    }
  }

  origin {
    origin_id   = "secondary-eu-west-1"
    domain_name = "secondary.eu-west-1.elb.amazonaws.com"

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }

    custom_header {
      name  = "X-Custom-Header"
      value = "CloudFrontOrigin"
    }
  }

  default_cache_behavior {
    target_origin_id       = "multi-region-group"
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods         = ["GET", "HEAD"]
    compress               = true

    cache_policy_id          = "658327ea-f89d-4fab-a63d-7e88639e58f6"
    origin_request_policy_id = "216adef6-5c7f-47e4-b989-5492eafa07d3"
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}
Enter fullscreen mode Exit fullscreen mode

Use Cases for Multi-Region:

  • Disaster recovery with automatic failover
  • Compliance requirements for data residency
  • Reduced latency by serving from closest AWS region
  • Blue-green deployments across regions

13. Interview Questions & Answers

Beginner Level

Q1: What is Amazon CloudFront and what problem does it solve?

A: Amazon CloudFront is a Content Delivery Network (CDN) that delivers content to users from edge locations closest to them. It solves latency problems by caching content at Hundreds of global edge locations, reducing the physical distance data travels. This improves website performance, reduces load on origin servers, and provides built-in DDoS protection.

Q2: What is the difference between an origin and an edge location in CloudFront?

A: An origin is the source server where CloudFront fetches original content - typically S3 buckets, EC2 instances, or custom HTTP servers. An edge location is a physical data center where CloudFront caches and serves content to end users. When a user requests content, CloudFront checks the nearest edge location first; if not cached (cache miss), it fetches from the origin.

Q3: What are the two types of CloudFront distributions?

A: CloudFront primarily uses Web Distributions for HTTP/HTTPS content delivery including websites, APIs, and streaming media. RTMP distributions previously existed for Adobe Flash Media streaming but have been deprecated. Modern implementations use only web distributions for all content types.

Q4: How does CloudFront pricing work?

A: CloudFront uses pay-as-you-go pricing based on data transfer out (per GB), HTTP/HTTPS requests (per 10,000), and optional features. Pricing varies by geographic region - US/Europe traffic is cheaper than Asia/South America. Additional charges apply for invalidations beyond 1,000 paths/month, Lambda@Edge executions, and real-time logging.

Q5: What is TTL (Time to Live) in CloudFront?

A: TTL defines how long CloudFront caches an object at edge locations before checking the origin for updates. It can be set via Cache-Control headers from the origin or configured in CloudFront cache behaviors. Longer TTLs improve cache hit ratio and reduce origin load, while shorter TTLs ensure fresher content but increase origin requests.

Intermediate Level

Q1: Explain the difference between Origin Access Identity (OAI) and Origin Access Control (OAC).

A: Origin Access Control (OAC) is the newer, recommended method for securing S3 origins that supports all S3 buckets, SSE-KMS encryption, and uses IAM service principals. OAI is the legacy approach with limited S3 region support and no SSE-KMS compatibility. OAC uses the format "Service": "cloudfront.amazonaws.com" with SourceArn conditions, providing better security through AWS Signature Version 4 authentication.

Q2: How would you optimize cache hit ratio for a dynamic website?

A:

  • Normalize cache keys by forwarding only necessary headers, cookies, and query strings
  • Use cache policies to define consistent caching rules
  • Implement query string whitelisting for parameters that affect content
  • Avoid forwarding session cookies for static assets
  • Use separate cache behaviors for static (/assets/) vs dynamic (/api/) content
  • Set appropriate TTLs based on content change frequency
  • Use CloudFront Functions for URL normalization (lowercase, parameter ordering)
  • Monitor CacheHitRate metric and analyze access logs for cache miss patterns

Q3: What is Lambda@Edge and when would you use it versus CloudFront Functions?

A: Lambda@Edge execute Node.js functions at edge locations for viewer/origin request and response manipulation for complex request/response manipulation like authentication, image optimization, or A/B testing. CloudFront Functions use lightweight JavaScript for sub-millisecond operations like URL rewrites or header manipulation. Use CloudFront Functions for simple transformations (10x cheaper, < 1ms latency), and Lambda@Edge for complex logic requiring external API calls, larger code packages, or longer execution times (up to 30 seconds).

Q4: How do you implement signed URLs for private content in CloudFront?

A:

  1. Create CloudFront key pair in AWS account (root user required)
  2. Configure trusted key groups or trusted signers in distribution
  3. Generate signed URL programmatically with expiration time, policy statement
  4. Include signature, key-pair-id, and expiration in URL parameters
  5. CloudFront validates signature before serving content
  6. Best practices: Use short expiration times (hours), IP restrictions, and rotate keys regularly

Example Policy:

{
  "Statement": [{
    "Resource": "https://d123.cloudfront.net/premium/*",
    "Condition": {
      "DateLessThan": {"AWS:EpochTime": 1735214400},
      "IpAddress": {"AWS:SourceIp": "203.0.113.0/24"}
    }
  }]
}
Enter fullscreen mode Exit fullscreen mode

Q5: How does CloudFront integrate with AWS WAF for security?

A: CloudFront integrates with AWS WAF by attaching Web ACLs (Access Control Lists) to distributions. WAF evaluates requests at edge locations before reaching the origin, blocking threats like SQL injection, XSS, and bot traffic. Rules can implement rate limiting, geo-blocking, IP whitelisting/blacklisting, and custom pattern matching. AWS Managed Rules provide pre-configured protection for OWASP Top 10 vulnerabilities, while custom rules allow application-specific security logic.

Advanced / Scenario-Based

Q1: Your CloudFront distribution has a cache hit ratio of 45%. How would you diagnose and fix this?

A:

Diagnosis:

  1. Analyze CloudWatch metrics to identify trends (time-based, geographic)
  2. Export access logs and analyze unique URLs causing cache misses
  3. Check forwarded headers, cookies, query strings in cache behaviors
  4. Review origin Cache-Control headers
  5. Identify user-agent or device-specific variations

Solutions:

  • Reduce header forwarding - only forward headers that affect content (Host, Authorization)
  • Implement query string whitelisting - cache only relevant parameters (productId, not sessionId)
  • Normalize URLs with CloudFront Functions (case-insensitive, parameter ordering)
  • Create separate cache behaviors for dynamic content vs static assets
  • Increase TTL for static content (3600s minimum for images/CSS/JS)
  • Use versioned URLs instead of query string timestamps
  • Check for session cookies being forwarded for all content
  • Enable origin shield to consolidate origin requests

Expected outcome: Cache hit ratio should improve to 85%+ after optimizations.

Q2: Design a multi-region, highly available architecture for a global SaaS application using CloudFront.

A:

Architecture Components:

Route 53 (Geolocation/Latency routing)
    ↓
CloudFront Distribution (Global)
    ↓
Origin Groups (Automatic Failover)
├── Primary Origin Group
│   ├── ALB (us-east-1) + Auto Scaling
│   └── Failover: ALB (us-west-2)
└── Secondary Origin Group
    └── ALB (eu-west-1) + Auto Scaling
    ↓
Multi-Region Database
├── Aurora Global Database (Primary: us-east-1)
└── Read Replicas (us-west-2, eu-west-1)
Enter fullscreen mode Exit fullscreen mode

Configuration Details:

  • CloudFront:
    • Multiple cache behaviors for API (/api/) vs static assets (/assets/)
    • Lambda@Edge for JWT validation at viewer-request
    • Origin custom headers for authentication
    • WAF with rate limiting and geo-restrictions
  • Origin Groups:
    • Failover criteria: 500, 502, 503, 504 status codes
    • Health checks every 30 seconds
    • Origin shield in primary region
  • Security:
    • ALB security groups allow only CloudFront managed prefix list
    • Custom header validation at ALB to prevent direct access
    • AWS Shield Advanced for DDoS protection
    • Field-level encryption for sensitive data
  • Monitoring:
    • CloudWatch alarms: 5xx rate > 1%, cache hit ratio < 80%
    • Real-time logs to Kinesis for security monitoring
    • X-Ray tracing for end-to-end latency analysis

Q3: You notice CloudFront data transfer costs increased 300% month-over-month. How would you investigate and optimize?

A:

Investigation Steps:

  1. Use Cost Explorer to identify cost breakdown by region and distribution
  2. Analyze CloudWatch BytesDownloaded metric by distribution
  3. Review access logs for traffic patterns, user agents, geographic distribution
  4. Check cache hit ratio - low ratio means expensive origin fetches
  5. Identify top requested files/URLs by size and frequency
  6. Look for bot traffic or DDoS attempts
  7. Verify compression is enabled for text content

Optimization Strategies:

Immediate Actions:

  • Enable Gzip/Brotli compression (70-80% reduction for text)
  • Restrict price class to exclude expensive regions if traffic is low
  • Block malicious IPs/user-agents via WAF
  • Implement rate limiting to prevent abuse

Medium-term:

  • Increase TTL for static content to improve cache hit ratio
  • Use versioned file names instead of frequent invalidations
  • Optimize images (WebP format, responsive sizing via Lambda@Edge)
  • Move video content to adaptive bitrate streaming

Long-term:

  • Implement CloudFront Functions for request validation at edge
  • Use S3 Intelligent-Tiering for origin content
  • Consider CloudFront Security Bundle for volume discounts
  • Analyze and eliminate unnecessary large asset downloads

Cost Tracking:

  • Set billing alarms at 20% thresholds
  • Tag distributions by project/environment for cost allocation
  • Monitor daily spending trends in Cost Explorer
  • Calculate cost per GB and cost per user metrics

Q4: Explain how you would implement a blue-green deployment strategy using CloudFront.

A:

Strategy 1: Weighted Origin Groups (Zero-Downtime)

resource "aws_cloudfront_distribution" "blue_green" {
  # Blue Environment (Current Production)
  origin {
    origin_id   = "blue-origin"
    domain_name = "blue.example.com"

    custom_origin_config {
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }

    custom_header {
      name  = "X-Environment"
      value = "blue"
    }
  }

  # Green Environment (New Version)
  origin {
    origin_id   = "green-origin"
    domain_name = "green.example.com"

    custom_origin_config {
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }

    custom_header {
      name  = "X-Environment"
      value = "green"
    }
  }

  # Default behavior uses blue initially
  default_cache_behavior {
    target_origin_id = "blue-origin"
    # ... cache configuration
  }
}
Enter fullscreen mode Exit fullscreen mode

Deployment Process:

  1. Preparation:
    • Deploy green environment alongside blue
    • Test green environment directly (bypass CloudFront)
    • Validate health checks, monitoring, database migrations
  2. Gradual Traffic Shift:
    • Use Lambda@Edge to route 10% traffic to green based on cookie/header
    • Monitor error rates, latency, business metrics
    • Increase to 25%, 50%, 100% over hours/days
  3. Cutover:
    • Update default_cache_behavior to point to green-origin
    • Invalidate cache for changed content paths
    • Wait 2-5 minutes for configuration propagation
  4. Rollback Plan:
    • Keep blue environment running for 24 hours
    • Quick rollback: revert target_origin_id to blue
    • Emergency: Update Route 53 to bypass CloudFront

Strategy 2: Lambda@Edge Routing (A/B Testing Style)

exports.handler = async (event) => {
    const request = event.Records.cf.request;
    const headers = request.headers;

    // Check for environment override cookie
    const cookies = headers.cookie || [];
    const envCookie = cookies.find(c => 
        c.value.includes('environment=green'));

    // Route 20% to green, 80% to blue
    const random = Math.random();
    if (envCookie || random < 0.2) {
        request.origin = {
            custom: {
                domainName: 'green.example.com',
                port: 443,
                protocol: 'https',
                path: '',
                sslProtocols: ['TLSv1.2'],
                readTimeout: 30,
                keepaliveTimeout: 5
            }
        };
        request.headers['x-environment'] = [{
            key: 'X-Environment',
            value: 'green'
        }];
    }

    return request;
};
Enter fullscreen mode Exit fullscreen mode

Monitoring During Deployment:

  • Compare error rates between blue and green origins
  • Track response time P50, P95, P99 percentiles
  • Monitor business metrics (conversions, signups)
  • Set automated rollback triggers on threshold breaches

Q5: How would you troubleshoot intermittent 504 errors from CloudFront affecting 2% of requests?

A:

Diagnosis Approach:

1. Identify Pattern:

# Analyze access logs for 504 errors
aws s3 sync s3://logs-bucket/cloudfront/ ./logs/
zgrep " 504 " logs/*.gz | awk '{print $1, $5, $11, $15}' > 504_analysis.txt

# Analyze patterns:
# - Time of day (traffic spikes?)
# - Geographic distribution (specific edge locations?)
# - Specific URLs/paths
# - User agents (mobile vs desktop?)
Enter fullscreen mode Exit fullscreen mode

2. Check CloudWatch Metrics:

  • OriginLatency metric - identify slow origin responses
  • Compare 504 rate by edge location (geographic issue?)
  • Check concurrent request count to origin
  • Review origin connection timeout settings

3. Origin Investigation:

# Test origin directly from edge location regions
curl -w "@curl-format.txt" -o /dev/null -s \
  -H "Host: origin.example.com" \
  -H "X-Custom-Header: test" \
  https://origin.example.com/api/slow-endpoint

# Check origin server logs for:
# - Connection pool exhaustion
# - Database query timeouts
# - Memory/CPU spikes
# - Upstream service failures
Enter fullscreen mode Exit fullscreen mode

Root Causes & Solutions:

Cause Solution
Origin timeout too low Increase CloudFront origin response timeout from 30s to 60s
Origin connection limits Increase origin server connection pool, enable keep-alive
Database query timeouts Optimize slow queries, add database read replicas
Specific edge location issues Report to AWS Support with edge location identifiers
Origin security group rules Verify all CloudFront IP ranges allowed (use managed prefix list)
Cold start issues (Lambda) Increase Lambda provisioned concurrency
Geographic latency Implement multi-region origins with origin groups
DDoS or bot traffic Enable AWS WAF rate limiting, implement bot detection

Implementation Example:

resource "aws_cloudfront_distribution" "fixed" {
  origin {
    domain_name = "origin.example.com"
    origin_id   = "primary"

    custom_origin_config {
      origin_protocol_policy   = "https-only"
      origin_read_timeout      = 60  # Increased from 30
      origin_keepalive_timeout = 60  # Increased from 5
    }
  }

  # Add origin shield to reduce concurrent requests
  origin_shield {
    enabled              = true
    origin_shield_region = "us-east-1"
  }
}
Enter fullscreen mode Exit fullscreen mode

Monitoring Setup:

# Create CloudWatch alarm for 504 errors
aws cloudwatch put-metric-alarm \
  --alarm-name "cloudfront-504-errors" \
  --alarm-description "Alert on 504 error rate > 1%" \
  --metric-name 5xxErrorRate \
  --namespace AWS/CloudFront \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 1 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=DistributionId,Value=E1234EXAMPLE
Enter fullscreen mode Exit fullscreen mode

Long-term Prevention:

  • Implement comprehensive health checks at origin
  • Use origin groups with automatic failover
  • Add origin shield to consolidate requests
  • Optimize origin application performance
  • Consider caching dynamic content with shorter TTLs
  • Implement circuit breakers at application layer

14. Real-World Scenarios & Case Studies

Scenario 1: E-Commerce Platform - Black Friday Traffic

Challenge:

  • E-commerce site expects 50x normal traffic on Black Friday
  • Current infrastructure: Single region EC2 Auto Scaling + RDS
  • Concerns: Origin overload, slow page loads, potential downtime

Solution Architecture:

Before CloudFront:

  • Traffic: Direct to ALB → EC2 instances → RDS
  • Bottleneck: Database queries for product images, CSS, JS on every request
  • Cost: High EC2 egress charges for static assets

After CloudFront Implementation:

CloudFront (Global)
    ↓
Cache Behaviors:
├── /api/* → ALB (TTL: 0, dynamic)
├── /images/* → S3 bucket (TTL: 2592000s / 30 days)
└── /assets/* → S3 bucket (TTL: 86400s / 24 hours)
    ↓
Origin Groups:
├── Primary: ALB us-east-1
└── Secondary: ALB us-west-2 (failover)
Enter fullscreen mode Exit fullscreen mode

Results:

  • 94% cache hit ratio for static assets
  • Origin load reduced by 80% (only API calls hit origin)
  • Page load time improved from 3.2s to 0.8s globally
  • AWS egress costs reduced by 60% (CloudFront cheaper than EC2)
  • Successfully handled 50x traffic with minimal origin scaling

Key Configurations:

  • Aggressive TTLs for product images (30 days)
  • Versioned asset URLs (style.v123.css) to avoid invalidations
  • Lambda@Edge for cart session management
  • WAF rules to block scraper bots (20% of traffic)
  • Origin shield enabled to consolidate database queries

Cost Impact:

  • CloudFront cost: $4,200/month (5TB data transfer)
  • Savings: $8,500/month (reduced EC2 instances + egress)
  • Net savings: $4,300/month (51% reduction)

Scenario 2: Media Streaming Platform - Global Expansion

Challenge:

  • Video streaming service expanding from US to Europe and Asia
  • Users experiencing buffering and high latency
  • Storage costs increasing with regional S3 bucket replication

Solution Architecture:

Video Upload Pipeline:
Encoder → S3 (us-east-1) → HLS/DASH transcoding
    ↓
CloudFront Distribution (Global)
├── Origin: S3 bucket (single region)
├── Regional Edge Caches (automatic)
└── Signed URLs (6-hour expiration)
    ↓
End Users (150+ countries)
Enter fullscreen mode Exit fullscreen mode

Implementation Details:

1. Content Preparation:

  • Adaptive bitrate encoding (240p to 4K)
  • Segment size: 6 seconds for low latency
  • Storage: S3 Standard-IA for older content, Intelligent-Tiering for new

2. CloudFront Configuration:

resource "aws_cloudfront_distribution" "streaming" {
  enabled         = true
  price_class     = "PriceClass_All"  # Global coverage needed
  http_version    = "http2and3"
  is_ipv6_enabled = true

  origin {
    domain_name = "video-content.s3.us-east-1.amazonaws.com"
    origin_id   = "S3-streaming"
    origin_access_control_id = aws_cloudfront_origin_access_control.streaming.id

    origin_shield {
      enabled              = true
      origin_shield_region = "us-east-1"
    }
  }

  default_cache_behavior {
    target_origin_id = "S3-streaming"
    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
    cached_methods   = ["GET", "HEAD"]

    # Long TTL for video segments (immutable)
    min_ttl     = 31536000  # 1 year
    default_ttl = 31536000
    max_ttl     = 31536000

    trusted_key_groups = [aws_cloudfront_key_group.streaming.id]

    compress = false  # Video already compressed
  }

  # Separate behavior for playlist files (shorter TTL)
  ordered_cache_behavior {
    path_pattern     = "*.m3u8"
    target_origin_id = "S3-streaming"

    min_ttl     = 0
    default_ttl = 10  # 10 seconds for playlist updates
    max_ttl     = 60
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Security Implementation:

  • Signed URLs generated by backend API with user authentication
  • Token expiration: 6 hours (full movie length)
  • Device fingerprinting to prevent URL sharing
  • WAF rules to block VPN/proxy services for geo-licensing

Results:

  • Global average latency: Reduced from 2.5s to 0.3s time-to-first-byte
  • Buffering events: Reduced by 92%
  • Storage cost: Saved 65% by eliminating regional S3 replication
  • Origin bandwidth: Reduced by 95% through regional edge caching
  • User satisfaction: Increased NPS score from 6.2 to 8.7

Cost Analysis (Monthly):

  • CloudFront: $18,000 (25TB data transfer)
  • S3 storage: $2,300 (single region vs $7,000 multi-region)
  • Origin requests: $150 (minimal with 98% cache hit ratio)
  • Lambda@Edge: $400 (signed URL validation)
  • Total: $20,850 vs previous $34,500 (40% reduction)

Scenario 3: SaaS Application - API Acceleration

Challenge:

  • B2B SaaS dashboard with global customers
  • API response times >2 seconds from Asia/Europe
  • Mobile app experiencing timeouts
  • Origin EC2 instances only in us-east-1

Solution Architecture:

Mobile/Web Clients
    ↓
CloudFront Distribution
    ↓
Cache Behaviors:
├── /api/v2/dashboard → API Gateway (TTL: 60s)
├── /api/v2/reports → API Gateway (TTL: 300s)
└── /static/* → S3 (TTL: 7 days)
    ↓
Lambda@Edge (viewer-request)
├── JWT validation
└── A/B test routing
    ↓
API Gateway → Lambda Functions → DynamoDB Global Tables
Enter fullscreen mode Exit fullscreen mode

Key Optimizations:

1. API Caching Strategy:

// Cache-Control headers from API
{
  "GET /api/v2/dashboard": "public, max-age=60, s-maxage=60",
  "GET /api/v2/reports": "public, max-age=300, s-maxage=300",
  "POST /api/v2/actions": "no-cache, no-store"
}
Enter fullscreen mode Exit fullscreen mode

2. Lambda@Edge for JWT Validation:

// Validates JWT at edge, avoiding origin trip for unauthorized requests
exports.handler = async (event) => {
    const request = event.Records.cf.request;
    const headers = request.headers;

    const authHeader = headers.authorization?.?.value;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
        return {
            status: '401',
            statusDescription: 'Unauthorized',
            headers: {
                'content-type': [{key: 'Content-Type', value: 'application/json'}]
            },
            body: JSON.stringify({error: 'Missing or invalid token'})
        };
    }

    try {
        // Validate JWT signature (cached public key)
        const token = authHeader.substring(7);
        const decoded = await validateJWT(token);

        // Add user context to origin request
        request.headers['x-user-id'] = [{key: 'X-User-ID', value: decoded.sub}];
        request.headers['x-tenant-id'] = [{key: 'X-Tenant-ID', value: decoded.tenant}];

        return request;
    } catch (error) {
        return {
            status: '403',
            statusDescription: 'Forbidden',
            body: JSON.stringify({error: 'Invalid token'})
        };
    }
};
Enter fullscreen mode Exit fullscreen mode

3. Cache Policy Configuration:

resource "aws_cloudfront_cache_policy" "api_cache" {
  name        = "API-Cache-Policy"
  min_ttl     = 0
  default_ttl = 60
  max_ttl     = 300

  parameters_in_cache_key_and_forwarded_to_origin {
    cookies_config {
      cookie_behavior = "none"
    }

    headers_config {
      header_behavior = "whitelist"
      headers {
        items = ["Authorization", "Accept-Language", "X-Api-Version"]
      }
    }

    query_strings_config {
      query_string_behavior = "whitelist"
      query_strings {
        items = ["filter", "sort", "page"]
      }
    }

    enable_accept_encoding_gzip   = true
    enable_accept_encoding_brotli = true
  }
}
Enter fullscreen mode Exit fullscreen mode

Results:

  • API response time (Asia): 2.3s → 0.4s (83% improvement)
  • API response time (Europe): 1.8s → 0.3s (83% improvement)
  • Mobile app timeout errors: Reduced by 96%
  • Origin API Gateway requests: Reduced by 65% through caching
  • Infrastructure cost: No need for multi-region API deployments

Performance Breakdown:

Metric Before After Improvement
TTFB (US) 180ms 45ms 75%
TTFB (EU) 1800ms 280ms 84%
TTFB (Asia) 2300ms 380ms 83%
Cache Hit Ratio N/A 67% -
Monthly Cost $3,200 $2,100 34%

Scenario 4: WordPress Site - DDoS Attack Mitigation

Challenge:

  • WordPress blog experiencing Layer 7 DDoS attack
  • 50,000 requests/second overwhelming origin servers
  • Legitimate users unable to access site
  • Emergency response needed within hours

Immediate Response Architecture:

Attackers + Legitimate Users
    ↓
Route 53 (update DNS to CloudFront)
    ↓
CloudFront Distribution
    ↓
AWS WAF (aggressive filtering)
├── Rate limiting: 100 req/5min per IP
├── Geographic blocking: Known attack sources
├── Bot detection: Challenge suspect clients
└── SQL injection/XSS protection
    ↓
ALB + EC2 Auto Scaling (WordPress)
    ↓
RDS Aurora
Enter fullscreen mode Exit fullscreen mode

Implementation Steps (Emergency Procedure):

1. Deploy CloudFront (T+0 minutes):

# Quick CloudFront deployment via CLI
aws cloudfront create-distribution \
  --origin-domain-name origin.example.com \
  --default-root-object index.php \
  --enabled \
  --web-acl-id arn:aws:wafv2:us-east-1:123456789012:global/webacl/emergency/abc123

# Update Route 53 to point to CloudFront (5 minute TTL)
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://change-batch.json
Enter fullscreen mode Exit fullscreen mode

2. Configure AWS WAF (T+10 minutes):

resource "aws_wafv2_web_acl" "emergency_ddos" {
  name  = "emergency-ddos-protection"
  scope = "CLOUDFRONT"

  default_action {
    allow {}
  }

  # Rule 1: Rate limiting
  rule {
    name     = "rate-limit-per-ip"
    priority = 1

    action {
      block {
        custom_response {
          response_code = 429
        }
      }
    }

    statement {
      rate_based_statement {
        limit              = 100
        aggregate_key_type = "IP"
      }
    }

    visibility_config {
      sampled_requests_enabled   = true
      cloudwatch_metrics_enabled = true
      metric_name                = "RateLimitRule"
    }
  }

  # Rule 2: Block known malicious IPs
  rule {
    name     = "block-attack-ips"
    priority = 2

    action {
      block {}
    }

    statement {
      ip_set_reference_statement {
        arn = aws_wafv2_ip_set.attack_ips.arn
      }
    }

    visibility_config {
      sampled_requests_enabled   = true
      cloudwatch_metrics_enabled = true
      metric_name                = "AttackIPBlocks"
    }
  }

  # Rule 3: Geographic blocking
  rule {
    name     = "geo-block-attack-regions"
    priority = 3

    action {
      block {}
    }

    statement {
      geo_match_statement {
        country_codes = ["CN", "RU", "KP"]  # Identified attack sources
      }
    }

    visibility_config {
      sampled_requests_enabled   = true
      cloudwatch_metrics_enabled = true
      metric_name                = "GeoBlocks"
    }
  }

  # Rule 4: AWS Managed Rules - Bot Control
  rule {
    name     = "aws-bot-control"
    priority = 4

    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesBotControlRuleSet"
      }
    }

    visibility_config {
      sampled_requests_enabled   = true
      cloudwatch_metrics_enabled = true
      metric_name                = "BotControl"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Origin Protection (T+20 minutes):

# Update ALB security group to only allow CloudFront
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --ip-permissions \
    IpProtocol=tcp,FromPort=443,ToPort=443,PrefixListIds=pl-3b927c52  # CloudFront prefix list

# Remove public internet access
aws ec2 revoke-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,CidrIp=0.0.0.0/0
Enter fullscreen mode Exit fullscreen mode

Results:

  • Attack traffic blocked: 99.8% (49,900 req/s blocked by WAF)
  • Legitimate traffic served: 100 req/s reached origin
  • Origin CPU utilization: 98% → 12%
  • Site availability: Restored within 15 minutes
  • False positive rate: <0.1% (minor geo-blocking impact)

Cost Impact (During Attack):

  • CloudFront: $240/day (300GB blocked traffic still charged)
  • AWS WAF: $85/day (Web ACL + rules + requests)
  • EC2 Auto Scaling: Reduced from $450/day to $80/day
  • Total daily cost during attack: $405 vs $2,800 without mitigation

Long-term Improvements:

  • Keep CloudFront + WAF permanently (ongoing protection)
  • Implement CAPTCHA challenges for suspect traffic
  • Add CloudFront Functions for custom bot detection
  • Enable AWS Shield Advanced for 24/7 DDoS Response Team
  • Set up automated IP set updates from threat intelligence feeds

Scenario 5: Mobile App Backend - Multi-Region Disaster Recovery

Challenge:

  • Mobile banking app with 5 million users
  • RTO (Recovery Time Objective): 5 minutes
  • RPO (Recovery Point Objective): 0 seconds
  • Compliance requirement: Multi-region redundancy

Solution Architecture:

Mobile Apps (iOS/Android)
    ↓
Route 53 Health Checks
    ↓
CloudFront Distribution (Global)
    ↓
Origin Groups (Automatic Failover)
├── Primary: ALB us-east-1
│   └── ECS Fargate + Aurora Global Database (primary)
└── Secondary: ALB eu-west-1
    └── ECS Fargate + Aurora Global Database (replica)
    ↓
DynamoDB Global Tables (sessions)
ElastiCache Global Datastore (Redis)
Enter fullscreen mode Exit fullscreen mode

Failover Configuration:

resource "aws_cloudfront_origin_request_policy" "banking_api" {
  name = "banking-api-policy"

  cookies_config {
    cookie_behavior = "all"
  }

  headers_config {
    header_behavior = "whitelist"
    headers {
      items = [
        "Authorization",
        "X-Device-ID",
        "X-App-Version",
        "X-Request-ID"
      ]
    }
  }

  query_strings_config {
    query_string_behavior = "all"
  }
}

resource "aws_cloudfront_distribution" "banking_app" {
  enabled = true

  origin_group {
    origin_id = "banking-api-group"

    failover_criteria {
      status_codes = [500, 502, 503, 504]
    }

    member {
      origin_id = "primary-us-east-1"
    }

    member {
      origin_id = "secondary-eu-west-1"
    }
  }

  origin {
    origin_id   = "primary-us-east-1"
    domain_name = "api-us-east-1.banking.internal"

    custom_origin_config {
      http_port                = 80
      https_port               = 443
      origin_protocol_policy   = "https-only"
      origin_ssl_protocols     = ["TLSv1.2"]
      origin_read_timeout      = 60
      origin_keepalive_timeout = 60
    }

    custom_header {
      name  = "X-Origin-Verify"
      value = random_password.origin_secret.result
    }
  }

  origin {
    origin_id   = "secondary-eu-west-1"
    domain_name = "api-eu-west-1.banking.internal"

    custom_origin_config {
      http_port                = 80
      https_port               = 443
      origin_protocol_policy   = "https-only"
      origin_ssl_protocols     = ["TLSv1.2"]
      origin_read_timeout      = 60
      origin_keepalive_timeout = 60
    }

    custom_header {
      name  = "X-Origin-Verify"
      value = random_password.origin_secret.result
    }
  }

  default_cache_behavior {
    target_origin_id         = "banking-api-group"
    viewer_protocol_policy   = "https-only"
    allowed_methods          = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods           = ["GET", "HEAD"]
    compress                 = true

    # No caching for sensitive banking data
    cache_policy_id          = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"  # CachingDisabled
    origin_request_policy_id = aws_cloudfront_origin_request_policy.banking_api.id
  }

  restrictions {
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["US", "CA", "GB", "DE", "FR"]  # Licensed regions
    }
  }

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate.banking.arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }

  # Enable Shield Advanced and WAF
  web_acl_id = aws_wafv2_web_acl.banking.arn
}
Enter fullscreen mode Exit fullscreen mode

Disaster Recovery Testing Results:

Test Scenario RTO Achieved RPO Achieved User Impact
Primary region failure 3.2 minutes 0 seconds 0.02% failed requests during failover
Partial AZ outage 45 seconds 0 seconds No user impact (automatic)
Database failover 1.8 minutes 0 seconds 0.01% 500 errors
Complete us-east-1 down 4.5 minutes 0 seconds 0.05% requests failed

Cost Analysis:

  • Active-active cost: $28,000/month (both regions running)
  • Insurance value: Prevents estimated $500K/hour downtime cost
  • ROI: Pays for itself if prevents >1 hour outage annually

15. Summary Cheat Sheet

Key Takeaways

What is CloudFront:

  • Global CDN with Hundreds of edge locations across 90+ cities
  • Caches content closer to users, reducing latency by 60-90%
  • Integrated with AWS services (S3, EC2, API Gateway, Lambda@Edge)
  • Pay-as-you-go pricing starting at $0.085/GB in US/Europe

When to Use:

  • Static website hosting with global audience
  • API acceleration for mobile/web applications
  • Video streaming (live and on-demand)
  • Software distribution and large file downloads
  • DDoS protection and security hardening

When NOT to Use:

  • Internal-only applications (single office/data center)
  • Websocket-heavy real-time applications
  • Very low traffic sites (<1GB/month)
  • Content changing every second (sub-1s TTL)

Do's and Don'ts

✅ DO:

  • Use Origin Access Control (OAC) for S3 origins, not OAI
  • Enforce HTTPS with "redirect-to-https" viewer protocol policy
  • Enable automatic compression (Gzip/Brotli) for text content
  • Use versioned URLs (app.v123.js) instead of frequent invalidations
  • Implement proper cache policies with whitelist approach
  • Monitor cache hit ratio (target >85%) and optimize continuously
  • Use CloudFront Functions for simple logic, Lambda@Edge for complex
  • Set appropriate TTLs: static (days/weeks), dynamic (minutes/hours)
  • Enable access logging for security auditing and debugging
  • Use AWS WAF for public-facing distributions
  • Implement origin groups for automatic failover
  • Tag distributions for cost allocation
  • Use managed cache policies when possible
  • Test configuration changes in non-production first

❌ DON'T:

  • Forward all headers/cookies/query strings (kills caching)
  • Use public S3 buckets with website endpoints
  • Allow HTTP traffic for sensitive applications
  • Use dedicated IP SSL ($600/month) when SNI works
  • Invalidate entire distribution daily (use versioned URLs)
  • Forget to set default root object (causes 403 errors)
  • Enable real-time logs without understanding cost implications
  • Use "All Edge Locations" price class without analyzing traffic
  • Expose origin servers to public internet (restrict to CloudFront IPs)
  • Ignore CloudWatch metrics and alarms
  • Deploy to production without testing cache behavior
  • Use Lambda@Edge for simple transformations (use CloudFront Functions)
  • Forward session cookies for static assets
  • Set TTL to 0 for all content (defeats purpose of CDN)

Quick Reference Commands

# Create distribution
aws cloudfront create-distribution --distribution-config file://config.json

# List distributions
aws cloudfront list-distributions --query 'DistributionList.Items[*].[Id,DomainName,Status]' --output table

# Invalidate cache
aws cloudfront create-invalidation --distribution-id E123 --paths "/*"

# Get cache hit ratio
aws cloudwatch get-metric-statistics --namespace AWS/CloudFront --metric-name CacheHitRate \
  --dimensions Name=DistributionId,Value=E123 --start-time 2025-12-26T00:00:00Z \
  --end-time 2025-12-26T23:59:59Z --period 3600 --statistics Average

# Check distribution status
aws cloudfront get-distribution --id E123 --query 'Distribution.Status'

# Download access logs
aws s3 sync s3://my-logs/cloudfront/ ./logs/ --exclude "*" --include "E123*"
Enter fullscreen mode Exit fullscreen mode

Common Metrics to Monitor

Metric Good Warning Critical
Cache Hit Ratio >85% 70-85% <70%
4xx Error Rate <2% 2-5% >5%
5xx Error Rate <0.5% 0.5-1% >1%
Origin Latency <500ms 500-2000ms >2000ms
Data Transfer Growth Expected +20% MoM +50% MoM

Security Checklist

  • [ ] HTTPS enforced (redirect-to-https or https-only)
  • [ ] TLS 1.2+ minimum protocol version
  • [ ] Origin Access Control (OAC) configured for S3
  • [ ] AWS WAF attached with OWASP Top 10 rules
  • [ ] Security headers added (HSTS, CSP, X-Frame-Options)
  • [ ] Access logging enabled to S3
  • [ ] CloudTrail logging enabled for API calls
  • [ ] Origin servers restricted to CloudFront IPs only
  • [ ] Custom origin header validation implemented
  • [ ] Signed URLs/cookies for private content
  • [ ] Geo-restriction configured if required
  • [ ] Field-level encryption for sensitive data
  • [ ] AWS Shield Standard included (Advanced if needed)
  • [ ] Regular security group and WAF rule reviews
  • [ ] Certificate expiration monitoring

Cost Optimization Checklist

  • [ ] Compression enabled (Gzip/Brotli)
  • [ ] Appropriate price class selected
  • [ ] Cache hit ratio >85%
  • [ ] Versioned URLs instead of invalidations
  • [ ] SNI used for SSL (not dedicated IP)
  • [ ] CloudFront Functions used instead of Lambda@Edge where possible
  • [ ] Proper TTLs set (days for static, minutes for dynamic)
  • [ ] Origin in same region as regional edge cache
  • [ ] Billing alarms configured
  • [ ] Cost allocation tags applied
  • [ ] Monthly cost review and optimization

One-Page Memory Refresher

CloudFront Flow: User → Route 53 → Edge Location → (cache miss) → Regional Edge Cache → (cache miss) → Origin

Key Limits: 200 distributions/account, 25 origins/distribution, 100 CNAMEs/distribution, 3000 paths/invalidation

Pricing: $0.085/GB (US), $0.140/GB (Asia), $0.0075 per 10K HTTP requests, First 1000 invalidation paths free

Security: OAC (new) > OAI (legacy), Always use HTTPS, WAF for L7 protection, Shield for L3/L4 DDoS

Performance: Target 85%+ cache hit ratio, Use compression, Optimize cache keys, Set appropriate TTLs

Integration: S3 (OAC), EC2/ALB (custom origin), Lambda@Edge (compute), WAF (security), Route 53 (DNS), ACM (certificates)

Troubleshooting: 403 = S3 permissions, 504 = origin timeout, Low cache = bad cache policy, High cost = compression + price class

This comprehensive deep dive covers Amazon CloudFront from fundamentals through advanced enterprise scenarios, validated against official AWS documentation.

Top comments (0)