Skip to content

Latest commit

 

History

History
351 lines (261 loc) · 10.4 KB

File metadata and controls

351 lines (261 loc) · 10.4 KB

CloudFront & Route 53

CloudFront — Content Delivery Network

What Is It?

CloudFront is AWS's CDN — it caches content at edge locations (300+ globally) close to users. Instead of every user hitting your S3 bucket in us-east-1, they hit the nearest edge location.

Real-World: Your app serves a React SPA from S3 + a REST API from Lambda. Without CloudFront: Australian users hit US servers, 200ms latency minimum. With CloudFront: static assets cached in Sydney edge, API calls still go to US but cached responses served from Sydney.


Core Concepts

User (Sydney) → CloudFront Edge (Sydney)
                    ↓ Cache miss → Origin (S3 in us-east-1)
                    ↓ Cache hit → Return from edge (< 10ms)

Origins

Origin Type Use for
S3 Bucket Static websites, file downloads
EC2 / ALB Dynamic content, APIs
Lambda Function URL Serverless APIs
Custom HTTP origin Any HTTP server

Origin Access Control (OAC)

For S3 origins — S3 bucket should NOT be public. Only CloudFront can access it:

// S3 Bucket Policy with OAC
{
  "Effect": "Allow",
  "Principal": {"Service": "cloudfront.amazonaws.com"},
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-bucket/*",
  "Condition": {
    "StringEquals": {
      "AWS:SourceArn": "arn:aws:cloudfront::123:distribution/ABC123"
    }
  }
}

OAC replaces OAI (Origin Access Identity) — use OAC for new distributions.


Caching Behavior

Cache Keys

By default, CloudFront caches per URL path. Customize to include:

  • Query strings: ?version=2 → different cache entry
  • Headers: Accept-Language → different response per language
  • Cookies: session-based content

Minimize cache key for better cache hit ratio. More cache key variables = more cache misses.

TTL and Cache Control

Origin response headers:
Cache-Control: max-age=86400  → CloudFront respects this
Cache-Control: no-cache       → CloudFront still caches unless you configure otherwise

CloudFront distribution settings:
Minimum TTL: 0
Default TTL: 86400 (24 hours)
Maximum TTL: 31536000 (1 year)

Cache Invalidation

When you update content in S3, CloudFront might still serve old cached version.

# Invalidate specific path
aws cloudfront create-invalidation \
  --distribution-id ABCDEFG123456 \
  --paths "/index.html" "/static/app.js"

# Invalidate everything (expensive — counts against free tier)
aws cloudfront create-invalidation \
  --distribution-id ABCDEFG123456 \
  --paths "/*"

Better approach: Use versioned file names. app.v2.js instead of app.js. Cache-bust by changing filename.


Viewer Protocol Policy

Setting What it means
HTTP and HTTPS Allow both (not recommended)
Redirect HTTP to HTTPS Force HTTPS
HTTPS Only Block HTTP requests

Always use "Redirect HTTP to HTTPS" for production.


Lambda@Edge and CloudFront Functions

Run code at CloudFront edge locations to customize behavior:

Feature Lambda@Edge CloudFront Functions
Runtime Node.js, Python JavaScript only
Trigger points Viewer request/response, Origin request/response Viewer request/response only
Timeout 5s (viewer), 30s (origin) 1ms
Memory Up to 10GB 2MB
Network access Yes No
Cost Higher 1/6th the cost
Use for Dynamic manipulation, auth, A/B testing URL rewrites, header manipulation

Lambda@Edge — Common Use Cases

A/B Testing:

// Lambda@Edge: Viewer Request
exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const userAgent = request.headers['user-agent'][0].value;
  
  // 50% go to variant B
  if (Math.random() < 0.5) {
    request.uri = '/variant-b' + request.uri;
  }
  callback(null, request);
};

JWT Validation at Edge:

// Validate token before hitting origin
exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const token = request.headers['authorization']?.[0]?.value;
  
  if (!validateJWT(token)) {
    callback(null, {
      status: '401',
      body: 'Unauthorized'
    });
    return;
  }
  callback(null, request);
};

CloudFront Functions — Use Cases

URL Normalization (remove trailing slash, lowercase):

function handler(event) {
  const request = event.request;
  const uri = request.uri;
  
  // Redirect /about/ to /about
  if (uri.endsWith('/') && uri !== '/') {
    return {
      statusCode: 301,
      headers: { location: { value: uri.slice(0, -1) } }
    };
  }
  
  // Default to index.html for SPA
  if (!uri.includes('.')) {
    request.uri = '/index.html';
  }
  
  return request;
}

Signed URLs and Signed Cookies

For paid content or private downloads:

Signed URL: Access to a single file.

from botocore.signers import CloudFrontSigner
import rsa, datetime

def generate_signed_url(url, key_id, private_key_pem):
    signer = CloudFrontSigner(key_id, rsa_signer)
    signed_url = signer.generate_presigned_url(
        url,
        date_less_than=datetime.datetime.now() + datetime.timedelta(hours=1)
    )
    return signed_url

Signed Cookie: Access to multiple files (e.g., all content in /premium/).

Feature Signed URL Signed Cookie
Access Single object Multiple objects with pattern
Use for One video download Netflix-style subscription

Geo Restriction

Block or allow access by country:

Allowlist: Only allow US, CA, GB
Blocklist: Block CN, RU

Based on IP → country mapping (MaxMind database).


CloudFront Security

HTTPS (SSL/TLS)

  • Upload custom certificate to ACM (us-east-1 only)
  • SNI (Server Name Indication) — free
  • Dedicated IP (for old HTTPS clients) — expensive

AWS WAF Integration

Internet → WAF (DDoS, SQL injection, XSS rules) → CloudFront → Origin

Block requests before they hit your origin. Define rate limits, IP blacklists, geo blocks, custom rules.


Route 53

What Is It?

Route 53 is AWS's managed DNS service. It resolves domain names to IP addresses and enables health-checked routing.


Record Types

Record Purpose Example
A Domain → IPv4 example.com → 1.2.3.4
AAAA Domain → IPv6 example.com → 2001:db8::1
CNAME Domain → another domain www → example.com
Alias AWS resource → AWS resource example.com → ALB
MX Mail server example.com → mail.example.com 10
TXT Arbitrary text Domain verification
NS Name servers Delegated zones

Alias vs CNAME

Feature CNAME Alias
Works on zone apex (example.com)? No Yes
Points to Any domain AWS resources only
TTL Configurable Set by AWS
Cost Free Free

Always use Alias for AWS resources (ALB, CloudFront, S3 website, etc.)


Routing Policies

Policy How it works Use for
Simple One or more IPs, random selection Single resource
Weighted % of traffic to each resource A/B testing, gradual migration
Latency Route to lowest-latency region Global apps
Failover Primary/secondary with health check DR
Geolocation Route based on user's country/continent Content localization
Geoproximity Route based on distance (with bias) Traffic shifting
Multi-Value Multiple healthy IPs (not load balancer) Client-side load balancing
IP-based Route based on client IP range CIDR-based routing

Weighted Routing Example

Route 53 Record: api.example.com
  → ALB-us-east-1   Weight: 90 (90% traffic)
  → ALB-us-west-2   Weight: 10 (10% traffic — canary)

Failover Routing

Primary: ALB in us-east-1 (health check active)
Secondary: ALB in eu-west-1

If primary fails health check → traffic goes to secondary automatically

Health Checks

Route 53 health checks are separate from EC2 health checks:

  • HTTP/HTTPS/TCP health check from 15+ global locations
  • Calculate Health: combine multiple health checks (AND/OR)
  • CloudWatch alarm: if alarm in ALARM state → treat endpoint as unhealthy

Real-World: Your API returns 200 but serves errors. Route 53 health check can evaluate the HTTP response body for a specific string — if not found, endpoint marked unhealthy.


Good Practices

Practice Reason
Use Alias records for AWS resources No extra DNS lookup, works at zone apex
Use versioned assets with CloudFront Avoid cache invalidation costs
Set appropriate TTLs Lower TTL = faster failover, but more DNS queries
Use OAC for S3 origins S3 not publicly accessible
Enable Access Logs on CloudFront Troubleshoot and analyze traffic patterns
WAF on CloudFront Block attacks before reaching origin

Exam Tips

  1. CloudFront signed URLs vs S3 presigned URLs: Different! CloudFront signed URL serves via CloudFront (faster, can be restricted). S3 presigned = direct S3 access.
  2. ACM certificate for CloudFront: must be in us-east-1 regardless of where CloudFront distribution is used.
  3. Route 53 is global — not regional.
  4. TTL too high: DNS cache stale during failover. For failover scenarios, lower TTL.
  5. Geolocation vs Latency: Geolocation = user's country. Latency = which endpoint responds fastest.
  6. CloudFront can handle HTTPS end-to-end: Viewer (HTTPS) → CloudFront → Origin (HTTPS).
  7. CloudFront origin failover: Primary origin fails → automatically routes to secondary origin.

Common Exam Scenarios

Q: S3 static website with custom domain and HTTPS? → S3 → CloudFront (OAC) → Route 53 Alias → CloudFront distribution. ACM cert in us-east-1.

Q: Route 10% of traffic to new API version for testing? → Route 53 Weighted Routing (or API Gateway canary, or Lambda alias weighted routing).

Q: Users in EU should be served from EU region? → Route 53 Geolocation routing policy (country → specific ALB).

Q: Automatically failover to backup region when primary is down? → Route 53 Failover routing with health checks on primary endpoint.

Q: Serve static content globally with low latency?CloudFront with S3 origin and edge caching.