Managing Cloud CDN with Terraform

Learn how to set up and manage Google Cloud CDN using Terraform

In this guide, we’ll explore how to manage Google Cloud CDN using Terraform.

Video Tutorial

Learn more about managing Google Cloud CDN with Terraform in this comprehensive video tutorial:

Prerequisites

  • Google Cloud SDK installed and configured
  • Terraform installed (version 1.0.0 or later)
  • A GCP project with billing enabled

Project Structure

.
├── main.tf                   # Main Terraform configuration file
├── variables.tf              # Variable definitions
├── outputs.tf               # Output definitions
├── terraform.tfvars         # Variable values
└── modules/
    └── cdn/
        ├── main.tf          # Cloud CDN specific configurations
        ├── variables.tf      # Module variables
        ├── backends.tf      # Backend configurations
        └── outputs.tf       # Module outputs

Provider Configuration

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

Variables

variable "project_id" {
  description = "The ID of the GCP project"
  type        = string
}

variable "region" {
  description = "The region to deploy resources to"
  type        = string
  default     = "us-central1"
}

variable "domain_name" {
  description = "Domain name for the CDN"
  type        = string
}

Backend Bucket Configuration

resource "google_storage_bucket" "static_content" {
  name          = "${var.project_id}-static-content"
  location      = var.region
  force_destroy = true

  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }

  cors {
    origin          = ["*"]
    method          = ["GET", "HEAD", "OPTIONS"]
    response_header = ["*"]
    max_age_seconds = 3600
  }
}

resource "google_compute_backend_bucket" "cdn_backend" {
  name        = "cdn-backend-bucket"
  bucket_name = google_storage_bucket.static_content.name
  enable_cdn  = true

  cdn_policy {
    cache_mode        = "CACHE_ALL_STATIC"
    client_ttl        = 3600
    default_ttl       = 3600
    max_ttl          = 86400
    negative_caching = true
    
    negative_caching_policy {
      code = 404
      ttl  = 300
    }
  }
}

URL Map Configuration

resource "google_compute_url_map" "cdn_url_map" {
  name            = "cdn-url-map"
  default_service = google_compute_backend_bucket.cdn_backend.id

  host_rule {
    hosts        = [var.domain_name]
    path_matcher = "main"
  }

  path_matcher {
    name            = "main"
    default_service = google_compute_backend_bucket.cdn_backend.id

    path_rule {
      paths   = ["/static/*"]
      service = google_compute_backend_bucket.cdn_backend.id
    }
  }
}

SSL Certificate Configuration

resource "google_compute_managed_ssl_certificate" "cdn_cert" {
  name = "cdn-certificate"

  managed {
    domains = [var.domain_name]
  }
}

HTTPS Proxy Configuration

resource "google_compute_target_https_proxy" "cdn_proxy" {
  name             = "cdn-https-proxy"
  url_map          = google_compute_url_map.cdn_url_map.id
  ssl_certificates = [google_compute_managed_ssl_certificate.cdn_cert.id]
}

Global Forwarding Rule

resource "google_compute_global_forwarding_rule" "cdn_forwarding_rule" {
  name                  = "cdn-forwarding-rule"
  target                = google_compute_target_https_proxy.cdn_proxy.id
  port_range            = "443"
  load_balancing_scheme = "EXTERNAL"
  ip_protocol           = "TCP"
}

Cache Invalidation Configuration

resource "google_compute_backend_bucket_signed_url_key" "cdn_key" {
  name           = "cdn-signed-url-key"
  key_value      = "your-secret-key"
  backend_bucket = google_compute_backend_bucket.cdn_backend.name
}

Outputs

output "cdn_ip_address" {
  value       = google_compute_global_forwarding_rule.cdn_forwarding_rule.ip_address
  description = "The IP address of the CDN endpoint"
}

output "bucket_name" {
  value       = google_storage_bucket.static_content.name
  description = "The name of the storage bucket"
}

output "cdn_url" {
  value       = "https://${var.domain_name}"
  description = "The URL of the CDN endpoint"
}

Best Practices

  1. CDN Configuration:

    • Set appropriate cache TTLs
    • Configure CORS properly
    • Use SSL certificates
    • Enable compression
  2. Security:

    • Use HTTPS only
    • Configure proper IAM
    • Implement signed URLs
    • Regular security review
  3. Performance:

    • Optimize cache settings
    • Monitor cache hit ratio
    • Configure proper regions
    • Regular optimization
  4. Cost Optimization:

    • Monitor bandwidth usage
    • Optimize cache settings
    • Clean up unused resources
    • Regular review

Common Operations

Creating Resources

terraform init
terraform plan
terraform apply

Uploading Content

gsutil cp -r ./static/* gs://${BUCKET_NAME}/

Cache Invalidation

gcloud compute url-maps invalidate-cdn-cache cdn-url-map \
    --path "/static/*"

Best Practices and Tips

  1. Content Management:

    • Organize content properly
    • Use proper file names
    • Implement versioning
    • Regular cleanup
  2. Cache Management:

    • Set proper TTLs
    • Monitor hit rates
    • Regular invalidation
    • Track performance
  3. Operations:

    • Monitor costs
    • Track usage
    • Set up alerts
    • Regular maintenance

Conclusion

You’ve learned how to set up and manage Google Cloud CDN using Terraform. This setup provides:

  • Fast content delivery
  • Secure SSL/TLS
  • Cache optimization
  • Best practices implementation