LAB18_GCP_Serverless Containers: Deploying to Cloud Run

Serverless Containers: Deploying to Cloud Run

☁ GCP 🟢 Beginner Cloud Run Serverless Containers

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.

Your Objectives
  • 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"
✓ Expected Output After Apply
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

service_url = "https://hello-run-abcde123-uc.a.run.app"