AWS for DevOps — CloudFront

2 minute read

12.2 — CloudFront

CloudFront is AWS’s CDN (Content Delivery Network). It caches your content at 400+ edge locations worldwide, reducing latency for users everywhere.

Real-World Analogy

CloudFront is like a chain of local bookstores. Instead of every customer ordering from the main warehouse (your origin server), each city has a local store (edge location) with copies of popular books. If the local store doesn’t have the book, it orders from the warehouse once and stocks it for future customers.

How CloudFront Works

  User (Mumbai)                    User (London)
       │                                │
       ▼                                ▼
  ┌──────────────┐              ┌──────────────┐
  │ Edge Location│              │ Edge Location│
  │   Mumbai     │              │   London     │
  │  (cached)    │              │  (cached)    │
  └──────┬───────┘              └──────┬───────┘
         │ cache miss                  │ cache miss
         └──────────┬──────────────────┘
                    ▼
              ┌──────────┐
              │  Origin  │
              │ (S3/ALB) │
              └──────────┘

Creating a Distribution

# Create a CloudFront distribution with an S3 origin
$ aws cloudfront create-distribution \
    --distribution-config '{
      "CallerReference": "my-dist-2026",
      "Origins": {
        "Quantity": 1,
        "Items": [{
          "Id": "S3-my-website",
          "DomainName": "my-website-bucket.s3.amazonaws.com",
          "S3OriginConfig": {
            "OriginAccessIdentity": "origin-access-identity/cloudfront/E1234567890"
          }
        }]
      },
      "DefaultCacheBehavior": {
        "TargetOriginId": "S3-my-website",
        "ViewerProtocolPolicy": "redirect-to-https",
        "AllowedMethods": {
          "Quantity": 2,
          "Items": ["HEAD", "GET"]
        },
        "ForwardedValues": {
          "QueryString": false,
          "Cookies": {"Forward": "none"}
        },
        "MinTTL": 0,
        "DefaultTTL": 86400,
        "MaxTTL": 31536000
      },
      "Enabled": true,
      "Comment": "My website CDN"
    }'

CloudFront with ALB Origin

For API backends, put CloudFront in front of your ALB:

# Distribution with ALB origin
# Origins.Items[0]:
{
  "Id": "ALB-api",
  "DomainName": "my-alb-123.ap-south-1.elb.amazonaws.com",
  "CustomOriginConfig": {
    "HTTPPort": 80,
    "HTTPSPort": 443,
    "OriginProtocolPolicy": "https-only"
  }
}

Origin Types

Origin Use Case Example
S3 Bucket Static websites, assets CSS, JS, images
ALB Dynamic API content REST API, GraphQL
EC2 Legacy applications Custom origin
MediaStore Video streaming Live/on-demand video
Custom origin Any HTTP server On-premises server

Cache Invalidation

When you deploy new content, invalidate the cache:

# Invalidate specific paths
$ aws cloudfront create-invalidation \
    --distribution-id E1234567890 \
    --paths '/index.html' '/css/*' '/js/*'
{
    "Invalidation": {
        "Id": "I1234567890",
        "Status": "InProgress"
    }
}

# Invalidate everything (use sparingly)
$ aws cloudfront create-invalidation \
    --distribution-id E1234567890 \
    --paths '/*'

Cache Behaviors

Route different paths to different origins:

Path Pattern Origin TTL Use Case
/api/* ALB 0 (no cache) Dynamic API
/static/* S3 86400 (1 day) CSS, JS, images
/images/* S3 604800 (7 days) User uploads
Default (*) S3 3600 (1 hour) HTML pages

Common Mistakes

Mistake Why It Hurts Fix
Caching API responses Users see stale data Set TTL=0 for /api/* paths
Not invalidating after deploy Users see old version Invalidate or use versioned filenames (app.v2.js)
No custom error pages Users see XML errors from S3 Configure custom error responses (403 → /index.html)
HTTP origin (not HTTPS) Data in transit not encrypted Set OriginProtocolPolicy: https-only

Quick Reference

Task Command
Create distribution aws cloudfront create-distribution --distribution-config '...'
List distributions aws cloudfront list-distributions
Invalidate cache aws cloudfront create-invalidation --distribution-id ID --paths '/path'
Get distribution aws cloudfront get-distribution --id ID
Disable distribution Update config with Enabled: false, then delete

Next → ALB vs NLB

Updated: