אוטומציה של הגדרת Cloud CDN באמצעות Terraform

בדוגמאות הבאות מוסבר איך לפרוס קצה עורפי לדוגמה עם Cloud CDN מופעל.

אם אתם חדשים בשימוש ב-Terraform עבור Google Cloud, תוכלו לקרוא את המאמר תחילת העבודה עם Terraform.

שימוש בקטגוריה של Cloud Storage

הדוגמה הבאה מגדירה את Cloud CDN עם קטגוריה של Cloud Storage ציבורית. הדוגמה כוללת גם הגדרות של איזון עומסים ושל שמירת נתונים במטמון. אפשר לשנות את ההגדרות לפי הצורך.

פרטים על כל קטע בדוגמה זמינים במאמר הגדרת קטגוריית קצה עורפי.

# Cloud Storage bucket
resource "random_id" "bucket_prefix" {
  byte_length = 8
}

resource "google_storage_bucket" "default" {
  name                        = "${random_id.bucket_prefix.hex}-my-bucket"
  location                    = "us-east1"
  uniform_bucket_level_access = true
  storage_class               = "STANDARD"
  // delete bucket and contents on destroy.
  force_destroy = true
  // Assign specialty files
  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }
}


# make bucket public
resource "google_storage_bucket_iam_member" "default" {
  bucket = google_storage_bucket.default.name
  role   = "roles/storage.objectViewer"
  member = "allUsers"
}

resource "google_storage_bucket_object" "index_page" {
  name    = "index-page"
  bucket  = google_storage_bucket.default.name
  content = <<-EOT
    
    

Congratulations on setting up Google Cloud CDN with Storage backend!

EOT } resource "google_storage_bucket_object" "error_page" { name = "404-page" bucket = google_storage_bucket.default.name content = <<-EOT

404 Error: Object you are looking for is no longer available!

EOT } # image object for testing, try to access http:///test.jpg resource "google_storage_bucket_object" "test_image" { name = "test-object" # Uncomment and add valid path to an object. # source = "/path/to/an/object" # content_type = "image/jpeg" # Delete after uncommenting above source and content_type attributes content = "Data as string to be uploaded" content_type = "text/plain" bucket = google_storage_bucket.default.name } # reserve IP address resource "google_compute_global_address" "default" { name = "example-ip" } # forwarding rule resource "google_compute_global_forwarding_rule" "default" { name = "http-lb-forwarding-rule" ip_protocol = "TCP" load_balancing_scheme = "EXTERNAL" port_range = "80" target = google_compute_target_http_proxy.default.id ip_address = google_compute_global_address.default.id } # http proxy resource "google_compute_target_http_proxy" "default" { name = "http-lb-proxy" url_map = google_compute_url_map.default.id } # url map resource "google_compute_url_map" "default" { name = "http-lb" default_service = google_compute_backend_bucket.default.id } # backend bucket with CDN policy with default ttl settings resource "google_compute_backend_bucket" "default" { name = "cat-backend-bucket" description = "Contains beautiful images" bucket_name = google_storage_bucket.default.name enable_cdn = true cdn_policy { cache_mode = "CACHE_ALL_STATIC" client_ttl = 3600 default_ttl = 3600 max_ttl = 86400 negative_caching = true serve_while_stale = 86400 } }

שימוש ב-MIG ובכותרות מותאמות אישית

אפשר להשתמש במשאבי Terraform כדי להפעיל מאזן עומסים חיצוני מסוג HTTP עם שירות קצה עורפי של Cloud CDN וכותרות מותאמות אישית של בקשות ותגובות.

מידע על הגדרת איזון העומסים זמין במדריך ההגדרה הראשי.

# VPC
resource "google_compute_network" "default" {
  name                    = "l7-xlb-network"
  provider                = google-beta
  auto_create_subnetworks = false
}

# backend subnet
resource "google_compute_subnetwork" "default" {
  name          = "l7-xlb-subnet"
  provider      = google-beta
  ip_cidr_range = "10.0.1.0/24"
  region        = "us-central1"
  network       = google_compute_network.default.id
}

# reserved IP address
resource "google_compute_global_address" "default" {
  provider = google-beta
  name     = "l7-xlb-static-ip"
}

# forwarding rule
resource "google_compute_global_forwarding_rule" "default" {
  name                  = "l7-xlb-forwarding-rule"
  provider              = google-beta
  ip_protocol           = "TCP"
  load_balancing_scheme = "EXTERNAL"
  port_range            = "80"
  target                = google_compute_target_http_proxy.default.id
  ip_address            = google_compute_global_address.default.id
}

# http proxy
resource "google_compute_target_http_proxy" "default" {
  name     = "l7-xlb-target-http-proxy"
  provider = google-beta
  url_map  = google_compute_url_map.default.id
}

# url map
resource "google_compute_url_map" "default" {
  name            = "l7-xlb-url-map"
  provider        = google-beta
  default_service = google_compute_backend_service.default.id
}

# backend service with custom request and response headers
resource "google_compute_backend_service" "default" {
  name                    = "l7-xlb-backend-service"
  provider                = google-beta
  protocol                = "HTTP"
  port_name               = "my-port"
  load_balancing_scheme   = "EXTERNAL"
  timeout_sec             = 10
  enable_cdn              = true
  custom_request_headers  = ["X-Client-Geo-Location: {client_region_subdivision}, {client_city}"]
  custom_response_headers = ["X-Cache-Hit: {cdn_cache_status}"]
  health_checks           = [google_compute_health_check.default.id]
  backend {
    group           = google_compute_instance_group_manager.default.instance_group
    balancing_mode  = "UTILIZATION"
    capacity_scaler = 1.0
  }
}

# instance template
resource "google_compute_instance_template" "default" {
  name         = "l7-xlb-mig-template"
  provider     = google-beta
  machine_type = "e2-small"
  tags         = ["allow-health-check"]

  network_interface {
    network    = google_compute_network.default.id
    subnetwork = google_compute_subnetwork.default.id
    access_config {
      # add external ip to fetch packages
    }
  }
  disk {
    source_image = "debian-cloud/debian-12"
    auto_delete  = true
    boot         = true
  }

  # install nginx and serve a simple web page
  metadata = {
    startup-script = <<-EOF1
      #! /bin/bash
      set -euo pipefail

      export DEBIAN_FRONTEND=noninteractive
      apt-get update
      apt-get install -y nginx-light jq

      NAME=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/hostname")
      IP=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip")
      METADATA=$(curl -f -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=True" | jq 'del(.["startup-script"])')

      cat < /var/www/html/index.html
      
      Name: $NAME
      IP: $IP
      Metadata: $METADATA
      
EOF EOF1 } lifecycle { create_before_destroy = true } } # health check resource "google_compute_health_check" "default" { name = "l7-xlb-hc" provider = google-beta http_health_check { port_specification = "USE_SERVING_PORT" } } # MIG resource "google_compute_instance_group_manager" "default" { name = "l7-xlb-mig1" provider = google-beta zone = "us-central1-c" named_port { name = "http" port = 8080 } version { instance_template = google_compute_instance_template.default.id name = "primary" } base_instance_name = "vm" target_size = 2 } # allow access from health check ranges resource "google_compute_firewall" "default" { name = "l7-xlb-fw-allow-hc" provider = google-beta direction = "INGRESS" network = google_compute_network.default.id source_ranges = ["130.211.0.0/22", "35.191.0.0/16"] allow { protocol = "tcp" } target_tags = ["allow-health-check"] }