petitviolet blog

    Terraform to provision GCP CDN for GCS backend



    Google 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 but use locals here instead for simplicity a.

    GCP IAP protected Cloud Run Application by Terraform Terraform to build a Cloud Run Application protected by GCP Identity-Aware Proxy Google Cloud(GCP) has Identity-Aware Proxy that uses ID and contexts to protect applications and VMs from unexpected access. Thanks to IAP, it's a way easy to protect an application running on Cloud Run by requiring Google login within the organization, for example.

    locals {
        gcp_project    = "awesome-project"
        region         = "asia-northeast1"
        user_emails    = [""]
        base_domain    = ""
        cdn_bucket_name = "hogehoge"
        cdn_bucket_cors_origins = [

    Use google_storage_bucket resource to create a GCS 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.

    Then, for being able to use the created bucket as a backend of CDN, use google_compute_backend_bucket with enable_cdn = true.

    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 =

    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.