TerraformPilot

Terraform

GCP Cloud Run with Terraform - Deploy Serverless Containers

Deploy Google Cloud Run services with Terraform. Container deployment, custom domains, traffic splitting, IAM, and VPC connector configuration.

LLuca Berton1 min read

Quick Answer

#
resource "google_cloud_run_v2_service" "api" {
  name     = "my-api"
  location = "us-central1"
  template {
    containers {
      image = "gcr.io/my-project/my-api:latest"
      ports { container_port = 8080 }
    }
  }
}

Full Cloud Run Service

#
resource "google_cloud_run_v2_service" "api" {
  name     = "${var.project}-api"
  location = var.region
  ingress  = "INGRESS_TRAFFIC_ALL"
 
  template {
    scaling {
      min_instance_count = 0
      max_instance_count = 10
    }
 
    containers {
      image = "${var.region}-docker.pkg.dev/${var.gcp_project}/${var.project}/api:${var.image_tag}"
 
      ports {
        container_port = 8080
      }
 
      resources {
        limits = {
          cpu    = "1"
          memory = "512Mi"
        }
        cpu_idle          = true   # Scale to zero
        startup_cpu_boost = true
      }
 
      env {
        name  = "ENVIRONMENT"
        value = var.environment
      }
 
      env {
        name = "DB_PASSWORD"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.db_password.secret_id
            version = "latest"
          }
        }
      }
 
      startup_probe {
        http_get { path = "/health" }
        initial_delay_seconds = 5
        period_seconds        = 3
      }
 
      liveness_probe {
        http_get { path = "/health" }
        period_seconds = 30
      }
    }
 
    service_account = google_service_account.cloud_run.email
  }
 
  traffic {
    type    = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
    percent = 100
  }
}

Public Access (No Auth)

#
resource "google_cloud_run_v2_service_iam_member" "public" {
  project  = google_cloud_run_v2_service.api.project
  location = google_cloud_run_v2_service.api.location
  name     = google_cloud_run_v2_service.api.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}
 
output "service_url" {
  value = google_cloud_run_v2_service.api.uri
}

Custom Domain

#
resource "google_cloud_run_domain_mapping" "main" {
  name     = "api.${var.domain_name}"
  location = var.region
 
  metadata {
    namespace = var.gcp_project
  }
 
  spec {
    route_name = google_cloud_run_v2_service.api.name
  }
}

VPC Connector (Private Access)

#
resource "google_vpc_access_connector" "main" {
  name          = "${var.project}-connector"
  region        = var.region
  ip_cidr_range = "10.8.0.0/28"
  network       = google_compute_network.main.name
}
 
resource "google_cloud_run_v2_service" "private" {
  name     = "${var.project}-private"
  location = var.region
 
  template {
    vpc_access {
      connector = google_vpc_access_connector.main.id
      egress    = "ALL_TRAFFIC"
    }
    containers {
      image = "..."
    }
  }
}

Traffic Splitting (Canary)

#
resource "google_cloud_run_v2_service" "api" {
  # ...
  traffic {
    type     = "TRAFFIC_TARGET_ALLOCATION_TYPE_REVISION"
    revision = "api-v1"
    percent  = 90
  }
  traffic {
    type    = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
    percent = 10
  }
}
#

Conclusion

#

Cloud Run is the fastest way to deploy containers on GCP. Use v2 API resources (google_cloud_run_v2_service), set cpu_idle = true for scale-to-zero, use Secret Manager for secrets, and VPC connectors for private database access. Traffic splitting enables canary deployments.

#Terraform#GCP#Cloud Run#Serverless#Infrastructure as Code

Share this article