Managing Cloud Run with Terraform

Learn how to deploy and manage serverless containers on Google Cloud Run using Terraform

In this guide, we’ll explore how to manage Google Cloud Run using Terraform.

Video Tutorial

View Source Code

Prerequisites

  • Google Cloud SDK installed and configured
  • Terraform installed (version 1.0.0 or later)
  • A GCP project with billing enabled
  • Docker installed (for container image building)

Project Structure

.
├── main.tf                   # Main Terraform configuration file
├── variables.tf              # Variable definitions
├── outputs.tf               # Output definitions
├── terraform.tfvars         # Variable values
└── modules/
    └── cloudrun/
        ├── main.tf          # Cloud Run specific configurations
        ├── variables.tf      # Module variables
        ├── services.tf      # Service configurations
        └── outputs.tf       # Module outputs

Provider Configuration

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

Variables

variable "project_id" {
  description = "The ID of the GCP project"
  type        = string
}

variable "region" {
  description = "The region to deploy resources to"
  type        = string
  default     = "us-central1"
}

variable "service_name" {
  description = "Name of the Cloud Run service"
  type        = string
}

variable "container_image" {
  description = "Container image to deploy"
  type        = string
}

variable "container_port" {
  description = "Port the container listens on"
  type        = number
  default     = 8080
}

Service Account Configuration

resource "google_service_account" "cloudrun_service_account" {
  account_id   = "${var.service_name}-sa"
  display_name = "Service Account for Cloud Run ${var.service_name}"
}

resource "google_project_iam_member" "cloudrun_invoker" {
  project = var.project_id
  role    = "roles/run.invoker"
  member  = "serviceAccount:${google_service_account.cloudrun_service_account.email}"
}

Cloud Run Service

resource "google_cloud_run_service" "service" {
  name     = var.service_name
  location = var.region

  template {
    spec {
      containers {
        image = var.container_image
        ports {
          container_port = var.container_port
        }

        resources {
          limits = {
            cpu    = "1000m"
            memory = "256Mi"
          }
        }

        env {
          name  = "ENVIRONMENT"
          value = "production"
        }
      }

      service_account_name = google_service_account.cloudrun_service_account.email
    }

    metadata {
      annotations = {
        "autoscaling.knative.dev/maxScale"      = "10"
        "autoscaling.knative.dev/minScale"      = "1"
        "run.googleapis.com/client-name"         = "terraform"
        "run.googleapis.com/vpc-access-egress"   = "all"
        "run.googleapis.com/vpc-access-connector" = null
      }
    }
  }

  traffic {
    percent         = 100
    latest_revision = true
  }

  autogenerate_revision_name = true
}

IAM Configuration

resource "google_cloud_run_service_iam_binding" "public_access" {
  location = google_cloud_run_service.service.location
  service  = google_cloud_run_service.service.name
  role     = "roles/run.invoker"
  members  = ["allUsers"]  # Be cautious with public access
}

Outputs

output "service_url" {
  value       = google_cloud_run_service.service.status[0].url
  description = "The URL of the deployed service"
}

output "latest_revision_name" {
  value       = google_cloud_run_service.service.status[0].latest_ready_revision_name
  description = "The name of the latest ready revision"
}

output "service_identity" {
  value       = google_cloud_run_service.service.template[0].spec[0].service_account_name
  description = "The service account used by the service"
}

Best Practices

  1. Security:

    • Use dedicated service accounts
    • Implement proper IAM roles
    • Secure environment variables
    • Use secret manager for sensitive data
  2. Performance:

    • Configure appropriate resources
    • Set autoscaling parameters
    • Monitor cold starts
    • Optimize container size
  3. Cost Optimization:

    • Use appropriate instance sizes
    • Configure concurrency
    • Monitor usage patterns
    • Implement proper scaling
  4. Monitoring:

    • Set up logging
    • Configure monitoring
    • Implement tracing
    • Set up alerts

Common Operations

Deploying Service

terraform init
terraform plan
terraform apply

Updating Service

# Update container image or configuration
terraform apply

Destroying Service

terraform destroy

Best Practices and Tips

  1. Container Management:

    • Use minimal base images
    • Implement health checks
    • Cache dependencies
    • Follow security best practices
  2. Deployment:

    • Use traffic splitting for updates
    • Implement blue/green deployments
    • Test locally before deployment
    • Monitor deployment health
  3. Operations:

    • Regular security updates
    • Monitor performance metrics
    • Implement proper logging
    • Set up alerting

Conclusion

You’ve learned how to set up and manage Google Cloud Run using Terraform. This setup provides:

  • Automated serverless deployments
  • Scalable container infrastructure
  • Secure service configuration
  • Best practices implementation