Terraform to provision GCP CDN for GCS backend
2023-02-20
TerraformGCPGoogle Cloud offers CDN(content delivery/distributed network) that can be backed by Cloud Storage, a.k.a GCS. Terraform supports provisioning CDN in GCP as always.
As well as the previous post, in Terraform, variables should be declared in variables.tf but use locals
here instead for simplicity a.
locals {
gcp_project = "awesome-project"
region = "asia-northeast1"
user_emails = ["hoge@example.com"]
base_domain = "example.com"
cdn_bucket_name = "hogehoge"
cdn_bucket_cors_origins = [
"http://localhost:3000",
]
}
Use google_storage_bucket
resource to create a GCS bucket.
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket
resource "google_storage_bucket" "cdn_bucket" {
name = local.cdn_bucket_name
project = local.gcp_project
location = local.region
uniform_bucket_level_access = false
cors {
origin = local.cdn_bucket_cors_origins
method = ["GET", "HEAD", "POST"]
response_header = ["*"]
max_age_seconds = 3600
}
}
From the viewpoint of security, as using IAM in GCP is basically recommended, giving uniform_bucket_level_access = true
would be a good practice.
See the document for details.
https://cloud.google.com/storage/docs/uniform-bucket-level-access
Then, for being able to use the created bucket as a backend of CDN, use google_compute_backend_bucket
with enable_cdn = true
.
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_bucket
resource "google_compute_backend_bucket" "app_cdn" {
name = "app-cdn-backend"
description = "backend for app-cdn bucket"
bucket_name = local.cdn_bucket_name
enable_cdn = true
}
As the last step, provisioning a load balancer to point to the backend.
Picking up google_compute_url_map
resource to provision load balancer for the google_compute_backend_bucket
backend.
resource "google_compute_url_map" "api_url_map" {
name = "api-urlmap"
default_service = xxx // whatever you want
host_rule {
hosts = ["cdn.${local.base_domain}"]
path_matcher = "cdn"
}
path_matcher {
name = "cdn"
default_service = google_compute_backend_bucket.app_cdn.id
}
}
It seems that having one load balancer in one google project that being backed by multiple services like GAE, Run, etc. is a good practice for the sake of maintainability and cost.
There should be more resources including google_compute_target_https_proxy
, google_compute_managed_ssl_certificate
, and others to provision the load balancer completely, but let me skip them since it's not the main topic of this post.