Serverless Containers: Deploying to Cloud Run
Scenario
You have a stateless web application packaged as a Docker container. You don't want to deal with Kubernetes. Cloud Run is Google's Knative-based serverless container service. It scales HTTP containers from zero-to-N based on traffic. You need to deploy a public-facing Cloud Run service using a sample public image.
- Create a google_cloud_run_v2_service named hello-run.
- Point the container image to Google's public sample: us-docker.pkg.dev/cloudrun/container/hello.
- Set the container port to 8080.
- Create a google_cloud_run_service_iam_member (or binding) that grants roles/run.invoker to allUsers so the service is publicly routable on the internet.
- Output the HTTPS URI of the service.
Additional Context
Cloud Run v1 vs v2: Terraform has two resources: `google_cloud_run_service` (the original Knative API) and `google_cloud_run_v2_service` (the newer Google-native API). The V2 resource is cleaner, fully supported, and gives better integration with features like VPC connectors and volume mounts. It is the recommended resource.
Port 8080: By default, Cloud Run passes requests to port 8080 inside the container. If your application listens on port 3000, you must explicitly declare the port within the `containers { ports { container_port = 3000 }}` block in Terraform.
variables.tf
variable "project_id" { type = string }
variable "gcp_region" { type = string; default = "us-central1" }main.tf
provider "google" {
project = var.project_id
region = var.gcp_region
}
# The Serverless Container Service
resource "google_cloud_run_v2_service" "hello" {
name = "hello-run"
location = var.gcp_region
ingress = "INGRESS_TRAFFIC_ALL"
template {
containers {
# Use a Google-provided public test image
image = "us-docker.pkg.dev/cloudrun/container/hello"
ports {
container_port = 8080
}
resources {
limits = {
cpu = "1"
memory = "256Mi"
}
}
}
}
}
# Give public internet access to invoke this specific service
# NOTE: Uses the V1 IAM API since V2 IAM API merges back to the same backend
resource "google_cloud_run_service_iam_member" "public_access" {
location = google_cloud_run_v2_service.hello.location
project = google_cloud_run_v2_service.hello.project
service = google_cloud_run_v2_service.hello.name
role = "roles/run.invoker"
member = "allUsers"
}outputs.tf
output "service_url" {
value = google_cloud_run_v2_service.hello.uri
description = "The auto-generated HTTPS URL of the Cloud Run service"
}Workflow Commands
terraform init
terraform apply -var="project_id=my-gcp-project-123"
# Curl the HTTPS endpoint given by output
curl $(terraform output -raw service_url)
terraform destroy -var="project_id=my-gcp-project-123"Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: service_url = "https://hello-run-abcde123-uc.a.run.app"

