GCP for DevOps — Cloud CDN

2 minute read

Cloud CDN

Cloud CDN (Content Delivery Network) caches HTTP(S) content at Google’s globally distributed edge points of presence, reducing latency and offloading origin servers. It integrates with Cloud Load Balancing.

How Cloud CDN Works

Cloud CDN:
┌──────────┐    ┌──────────────┐    ┌──────────────┐
│ User       │───▶│ Edge PoP      │───▶│ Origin        │
│ (Sydney)   │    │ (Sydney)      │    │ (us-central1) │
│            │    │               │    │               │
│            │    │ Cache HIT  ◀──│    │ Backend       │
│            │◀───│ (fast!)       │    │ Service       │
│            │    │               │    │               │
│            │    │ Cache MISS ───│───▶│ Fetch origin  │
│            │◀───│ Cache + serve │◀───│ Return data   │
└──────────┘    └──────────────┘    └──────────────┘

Google has 180+ edge PoPs worldwide

Enable Cloud CDN

Cloud CDN requires a Global HTTP(S) Load Balancer:

# Enable CDN on a backend service
$ gcloud compute backend-services update my-backend \
    --enable-cdn \
    --global

# Enable CDN on a backend bucket (static content)
$ gcloud compute backend-buckets update my-bucket-backend \
    --enable-cdn

Cache Policies

# Set cache policy on backend service
$ gcloud compute backend-services update my-backend \
    --global \
    --enable-cdn \
    --cache-mode=CACHE_ALL_STATIC \
    --default-ttl=3600 \
    --max-ttl=86400 \
    --client-ttl=3600

# Cache modes:
# USE_ORIGIN_HEADERS  — Respect Cache-Control headers from origin
# CACHE_ALL_STATIC    — Cache common static types (images, CSS, JS)
# FORCE_CACHE_ALL     — Cache everything regardless of headers

Cache Key Configuration

# Customize cache key (include query string parameters)
$ gcloud compute backend-services update my-backend \
    --global \
    --enable-cdn \
    --cache-key-include-query-string \
    --cache-key-query-string-whitelist=page,sort

# Exclude host from cache key (multi-domain CDN)
$ gcloud compute backend-services update my-backend \
    --global \
    --enable-cdn \
    --no-cache-key-include-host

Signed URLs and Cookies

Restrict access to CDN content:

# Generate a key for signed URLs
$ head -c 16 /dev/urandom | base64 | tr +/ -_ > cdn-key.txt

# Add the key to a backend service
$ gcloud compute backend-services add-signed-url-key my-backend \
    --global \
    --key-name=my-cdn-key \
    --key-file=cdn-key.txt

# Generate a signed URL (valid for 1 hour)
$ gcloud compute sign-url \
    "https://cdn.example.com/premium/video.mp4" \
    --key-name=my-cdn-key \
    --key-file=cdn-key.txt \
    --expires-in=1h

Cache Invalidation

# Invalidate a specific path
$ gcloud compute url-maps invalidate-cdn-cache my-lb \
    --path="/images/logo.png"

# Invalidate all content under a prefix
$ gcloud compute url-maps invalidate-cdn-cache my-lb \
    --path="/static/*"

# Invalidate everything
$ gcloud compute url-maps invalidate-cdn-cache my-lb \
    --path="/*"

Origin Headers for CDN

Set cache headers in your application:

from flask import Flask, make_response

app = Flask(__name__)

@app.route("/api/data")
def api_data():
    response = make_response({"data": "cached response"})
    response.headers["Cache-Control"] = "public, max-age=3600"
    return response

@app.route("/api/user")
def api_user():
    response = make_response({"user": "dynamic"})
    response.headers["Cache-Control"] = "private, no-store"
    return response

Monitoring CDN

# Check CDN hit ratio
$ gcloud logging read \
    'resource.type="http_load_balancer" AND jsonPayload.cacheHit:*' \
    --limit=20 \
    --format="table(jsonPayload.cacheHit, httpRequest.requestUrl)"

Common Mistakes

Mistake Why It’s Wrong Fix
No Cache-Control headers CDN can’t cache content Set explicit cache headers
Caching authenticated content Serves other users’ data Use private, no-store
Not invalidating on deploy Stale content after update Invalidate or use cache-busting
Too long TTL for dynamic Users see stale data Use short TTL or no-cache
No signed URLs for premium Content freely accessible Use signed URLs/cookies

Quick Reference

Command Description
gcloud compute backend-services update --enable-cdn Enable CDN
gcloud compute url-maps invalidate-cdn-cache Invalidate cache
gcloud compute sign-url Generate signed URL
gcloud compute backend-services add-signed-url-key Add signing key

Next → Cloud Armor

Updated: