CloudFront CDN

Amazon Web Services · Practical · 14 min

A CDN cuts latency and origin load and is the standard way to serve static sites and assets from S3.

CloudFront caches and serves content from hundreds of edge locations. A distribution has one or more origins (an S3 bucket, an ALB, API Gateway, any HTTP server) and cache behaviors that map path patterns (/static/*, /api/*, default *) to an origin with its own settings.

Caching is controlled by cache policies (TTLs and which headers, cookies and query strings form the cache key) and origin request policies (what to forward to the origin without affecting the key). Keep the cache key small; every extra header or cookie fragments the cache. For dynamic APIs use the managed CachingDisabled policy and still benefit from TLS termination and AWS's backbone network.

For a private S3 bucket, use Origin Access Control (OAC): CloudFront signs requests to S3, and the bucket policy allows the cloudfront.amazonaws.com service principal only for your distribution's ARN. The bucket stays private with Block Public Access on. OAC replaces the older Origin Access Identity.

Other essentials:

  • Custom domains need an ACM certificate created in us-east-1, and an alias record in Route 53.
  • Invalidations remove cached objects but are slow-ish and billed beyond a free allowance; prefer versioned file names (app.3f9c.js) with long TTLs.
  • Signed URLs or cookies restrict private content; AWS WAF attaches to block attacks.
  • CloudFront Functions (lightweight JavaScript at the edge, for header rewrites and redirects) and Lambda@Edge (heavier logic) customise requests.

Example

# Bucket policy: only this CloudFront distribution may read objects (OAC)
cat > oac-policy.json <<'EOF'
{"Version": "2012-10-17",
 "Statement": [{
   "Sid": "AllowCloudFrontOAC",
   "Effect": "Allow",
   "Principal": {"Service": "cloudfront.amazonaws.com"},
   "Action": "s3:GetObject",
   "Resource": "arn:aws:s3:::acme-site/*",
   "Condition": {"StringEquals": {
     "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E1ABCDEF2GHIJ"}}}]}
EOF
aws s3api put-bucket-policy --bucket acme-site --policy file://oac-policy.json

# Deploy: hashed assets cache for a year, index.html briefly
aws s3 sync ./dist/assets s3://acme-site/assets --cache-control "public,max-age=31536000,immutable"
aws s3 cp ./dist/index.html s3://acme-site/index.html --cache-control "max-age=60"
aws cloudfront create-invalidation --distribution-id E1ABCDEF2GHIJ --paths "/index.html"

Remember

  • Distribution = origins + cache behaviors by path
  • Keep the cache key minimal; use origin request policies for extra forwarding
  • OAC keeps S3 origins private; ACM certs for CloudFront live in us-east-1
  • Prefer versioned file names over invalidations

Watch out for

  • Making the S3 bucket public for CloudFront instead of using Origin Access Control.

Check yourself

  1. Your ACM certificate is in eu-west-1 and CloudFront won't let you select it. Why?
  2. Adding the User-Agent header to the cache key causes what?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html