DevOps help for Cloud Platform Engineers
  • Welcome!
  • Quick Start Guide
  • About Me
  • CV
  • Contribute
  • 🧠DevOps & SRE Foundations
    • DevOps Overview
      • Engineering Fundamentals
      • Implementing DevOps Strategy
      • DevOps Readiness Assessment
      • Lifecycle Management
      • The 12 Factor App
      • Design for Self Healing
      • Incident Management Best Practices (2025)
    • SRE Fundamentals
      • Toil Reduction
      • System Simplicity
      • Real-world Scenarios
        • AWS VM Log Monitoring API
    • Agile Development
      • Team Agreements
        • Definition of Done
        • Definition of Ready
        • Team Manifesto
        • Working Agreement
    • Industry Scenarios
      • Finance and Banking
      • Public Sector (UK/EU)
      • Energy Sector Edge Computing
  • DevOps Practices
    • Platform Engineering
    • FinOps
    • Observability
      • Modern Practices
  • 🚀Modern DevOps Practices
    • Infrastructure Testing
    • Modern Development
    • Database DevOps
  • 🛠️Infrastructure as Code (IaC)
    • Terraform
      • Cloud Integrations - Provider-specific implementations
        • Azure Scenarios
          • Azure Authetication
            • Service Principal
            • Service Principal in block
            • Service Principal in env
        • AWS Scenarios
          • AWS Authentication
        • GCP Scenarios
          • GCP Authentication
      • Testing and Validation
        • Unit Testing
        • Integration Testing
        • End-to-End Testing
        • Terratest Guide
      • Best Practices
        • State Management
        • Security
        • Code Organization
        • Performance
      • Tools & Utilities - Enhancing the Terraform workflow
        • Terraform Docs
        • TFLint
        • Checkov
        • Terrascan
      • CI/CD Integration - Automating infrastructure deployment
        • GitHub Actions
        • Azure Pipelines
        • GitLab CI
    • Bicep
      • Getting Started - First steps with Bicep [BEGINNER]
      • Template Specs
      • Best Practices - Guidelines for effective Bicep implementations
      • Modules - Building reusable components [INTERMEDIATE]
      • Examples - Sample implementations for common scenarios
      • Advanced Features
      • CI/CD Integration - Automating Bicep deployments
        • GitHub Actions
        • Azure Pipelines
  • 💰Cost Management & FinOps
    • Cloud Cost Optimization
  • 🐳Containers & Orchestration
    • Containerization Overview
      • Docker
        • Dockerfile Best Practices
        • Docker Compose
      • Kubernetes
        • CLI Tools - Essential command-line utilities
          • Kubectl
          • Kubens
          • Kubectx
        • Core Concepts
        • Components
        • Best Practices
          • Pod Security
          • Security Monitoring
          • Resource Limits
        • Advanced Features - Beyond the basics [ADVANCED]
          • Service Mesh
            • Istio
            • Linkerd
          • Ingress Controllers
            • NGINX
            • Traefik
            • Kong
            • Gloo Edge
            • Contour
        • Tips
          • Status in Pods
          • Resource handling
          • Pod Troubleshooting Commands
        • Enterprise Architecture
        • Health Management
        • Security & Compliance
        • Virtual Clusters
      • OpenShift
  • Service Mesh & Networking
    • Service Mesh Implementation
  • Architecture Patterns
    • Data Mesh
    • Multi-Cloud Networking
    • Disaster Recovery
    • Chaos Engineering
  • Edge Computing
    • Implementation Guide
      • Serverless Edge
      • IoT Edge Patterns
      • Real-Time Processing
      • Edge AI/ML
      • Security Hardening
      • Observability Patterns
      • Network Optimization
      • Storage Patterns
  • 🔄CI/CD & GitOps
    • CI/CD Overview
      • Continuous Integration
      • Continuous Delivery
        • Deployment Strategies
        • Secrets Management
        • Blue-Green Deployments
        • Deployment Metrics
        • Progressive Delivery
        • Release Management for DevOps/SRE (2025)
      • CI/CD Platforms - Tool selection and implementation
        • Azure DevOps
          • Pipelines
            • Stages
            • Jobs
            • Steps
            • Templates - Reusable pipeline components
            • Extends
            • Service Connections - External service authentication
            • Best Practices for 2025
            • Agents and Runners
            • Third-Party Integrations
            • Azure DevOps CLI
          • Boards & Work Items
        • GitHub Actions
        • GitLab
          • GitLab Runner
          • Real-life scenarios
          • Installation guides
          • Pros and Cons
          • Comparison with alternatives
      • GitOps
        • Modern GitOps Practices
        • GitOps Patterns for Multi-Cloud (2025)
        • Flux
          • Overview
          • Progressive Delivery
          • Use GitOps with Flux, GitHub and AKS
  • Source Control
    • Source Control Overview
      • Git Branching Strategies
      • Component Versioning
      • Kubernetes Manifest Versioning
      • GitLab
      • Creating a Fork
      • Naming Branches
      • Pull Requests
      • Integrating LLMs into Source Control Workflows
  • ☁️Cloud Platforms
    • Cloud Strategy
      • AWS to Azure
      • Azure to AWS
      • GCP to Azure
      • AWS to GCP
      • GCP to AWS
    • Azure
      • Best Practices
        • Azure Best Practices Overview
        • Azure Architecture Best Practices
        • Azure Naming Standards
        • Azure Tags
        • Azure Security Best Practices
      • Landing Zones
      • Services
        • Azure Active Directory (AAD)
        • Azure Monitor
        • Azure Key Vault
        • Azure Service Bus
        • Azure DNS
        • Azure App Service
        • Azure Batch
        • Azure Machine Learning
        • Azure OpenAI Service
        • Azure Cognitive Services
        • Azure Kubernetes Service (AKS)
        • Azure Databricks
        • Azure SQL Database
      • Monitoring
      • Administration Tools - Platform management interfaces
        • Azure PowerShell
        • Azure CLI
      • Tips & Tricks
    • AWS
      • Authentication
      • Best Practices
      • Tips & Tricks
      • Services
        • AWS IAM (Identity and Access Management)
        • Amazon CloudWatch
        • Amazon SNS (Simple Notification Service)
        • Amazon SQS (Simple Queue Service)
        • Amazon Route 53
        • AWS Elastic Beanstalk
        • AWS Batch
        • Amazon SageMaker
        • Amazon Bedrock
        • Amazon Comprehend
    • Google Cloud
      • Services
        • Cloud CDN
        • Cloud DNS
        • Cloud Load Balancing
        • Google Kubernetes Engine (GKE)
        • Cloud Run
        • Artifact Registry
        • Compute Engine
        • Cloud Functions
        • App Engine
        • Cloud Storage
        • Persistent Disk
        • Filestore
        • Cloud SQL
        • Cloud Spanner
        • Firestore
        • Bigtable
        • BigQuery
        • VPC (Virtual Private Cloud)
  • 🔐Security & Compliance
    • DevSecOps Overview
      • DevSecOps Pipeline Security
      • DevSecOps
        • Real-life Examples
        • Scanning & Protection - Automated security tooling
          • Dependency Scanning
          • Credential Scanning
          • Container Security Scanning
          • Static Code Analysis
            • Best Practices
            • Tool Integration Guide
            • Pipeline Configuration
        • CI/CD Security
        • Secrets Rotation
      • Supply Chain Security
        • SLSA Framework
        • Binary Authorization
        • Artifact Signing
      • Security Best Practices
        • Threat Modeling
        • Kubernetes Security
      • SecOps
      • Zero Trust Model
      • Cloud Compliance
        • ISO/IEC 27001:2022
        • ISO 22301:2019
        • PCI DSS
        • CSA STAR
      • Security Frameworks
      • SIEM and SOAR
  • Security Architecture
    • Zero Trust Implementation
      • Identity Management
      • Network Security
      • Access Control
  • 🔍Observability & Monitoring
    • Observability Fundamentals
      • Logging
      • Metrics
      • Tracing
      • Dashboards
      • SLOs and SLAs
      • Observability as Code
      • Pipeline Observability
  • 🧪Testing Strategies
    • Testing Overview
      • Modern Testing Approaches
      • End-to-End Testing
      • Unit Testing
      • Performance Testing
        • Load Testing
      • Fault Injection Testing
      • Integration Testing
      • Smoke Testing
  • 🤖AI Integration
    • AIops Overview
      • Workflow Automation
      • Predictive Analytics
      • Code Quality
  • 🧠AI & LLM Integration
    • Overview
      • Claude
        • Installation Guide
        • Project Guides
        • MCP Server Setup
        • LLM Comparison
      • Ollama
        • Installation Guide
        • Configuration
        • Models and Fine-tuning
        • DevOps Usage
        • Docker Setup
        • GPU Setup
        • Open WebUI
      • Copilot
        • Installation Guide
        • VS Code Integration
        • CLI Usage
      • Gemini
        • Installation Guides - Platform-specific setup
          • Linux Installation
          • WSL Installation
          • NixOS Installation
        • Gemini 2.5 Features
        • Roles and Agents
        • NotebookML Guide
        • Cloud Infrastructure Deployment
        • Summary
  • 💻Development Environment
    • DevOps Tools
      • Operating Systems - Development platforms
        • NixOS
          • Install NixOS: PC, Mac, WSL
          • Nix Language Deep Dive
          • Nix Language Fundamentals
            • Nix Functions and Techniques
            • Building Packages with Nix
            • NixOS Configuration Patterns
            • Flakes: The Future of Nix
          • NixOS Generators: Azure & QEMU
        • WSL2
          • Distributions
          • Terminal Setup
      • Editor Environments
      • CLI Tools
        • Azure CLI
        • PowerShell
        • Linux Commands
          • SSH - Secure Shell)
            • SSH Config
            • SSH Port Forwarding
        • Linux Fundametals
        • Cloud init
          • Cloud init examples
        • YAML Tools
          • How to create a k8s yaml file - How to create YAML config
          • YQ the tool
  • 📚Programming Languages
    • Python
    • Go
    • JavaScript/TypeScript
    • Java
    • Rust
  • Platform Engineering
    • Implementation Guide
  • FinOps
    • Implementation Guide
  • AIOps
    • LLMOps Guide
  • Should Learn
    • Should Learn
    • Linux
      • Commands
      • OS
      • Services
    • Terraform
    • Getting Started - Installation and initial setup [BEGINNER]
    • Cloud Integrations
    • Testing and Validation - Ensuring infrastructure quality
      • Unit Testing
      • Integration Testing
      • End-to-End Testing
      • Terratest Guide
    • Best Practices - Production-ready implementation strategies
      • State Management
      • Security
      • Code Organization
      • Performance
    • Tools & Utilities
    • CI/CD Integration
    • Bicep
    • Kubernetes
      • kubectl
    • Ansible
    • Puppet
    • Java
    • Rust
    • Azure CLI
  • 📖Documentation Best Practices
    • Documentation Strategy
      • Project Documentation
      • Release Notes
      • Static Sites
      • Documentation Templates
      • Real-World Examples
  • 📋Reference Materials
    • Glossary
    • Tool Comparison
    • Tool Decision Guides
    • Recommended Reading
    • Troubleshooting Guide
    • Development Setup
Powered by GitBook
On this page
  • Key Features
  • Deploying Cloud Run with Terraform
  • Basic Service Deployment
  • Cloud Run Service with VPC Access
  • Cloud Run Service with Traffic Splitting
  • Cloud Run with Custom Domain Mapping
  • Deploying Cloud Run with gcloud CLI
  • Building and Deploying a Container
  • Updating an Existing Service
  • Creating a Private Service
  • Configure VPC Connector
  • Configure Environment Variables and Secrets
  • Real-World Example: Microservices Application
  • Step 1: Infrastructure Setup with Terraform
  • Step 2: Example Authentication Service Code
  • Step 3: Example Product Service Code
  • Step 4: Example of Frontend Integration
  • Best Practices
  • Common Issues and Troubleshooting
  • Container Startup Problems
  • Connection Issues
  • Performance Problems
  • Deployment Failures
  • Further Reading
Edit on GitHub
  1. Cloud Platforms
  2. Google Cloud
  3. Services

Cloud Run

Deploying and managing Google Cloud Run for containerized applications

Google Cloud Run is a fully managed compute platform that allows you to run stateless containers directly on top of Google's scalable infrastructure. It abstracts away infrastructure management so you can focus on developing applications in the language of your choice.

Key Features

  • Fully managed: No infrastructure to provision or manage

  • Serverless: Pay only for the resources you use

  • Scale to zero: No charges when your service isn't running

  • Autoscaling: Automatically scales based on traffic

  • Multiple languages: Supports any language using a Docker container

  • Custom domains: Connect your own domain names

  • Private services: Restrict access to authorized users or internal services

  • Traffic splitting: Gradually roll out new versions with percentage-based traffic splitting

  • VPC connectivity: Connect to VPC resources

  • Cloud SQL connection: Direct connection to Cloud SQL databases

  • Concurrency: Process multiple requests per container instance

  • WebSockets: Support for WebSockets and HTTP/2

Deploying Cloud Run with Terraform

Basic Service Deployment

# Create a service account for Cloud Run
resource "google_service_account" "cloud_run_sa" {
  account_id   = "cloud-run-sa"
  display_name = "Cloud Run Service Account"
}

# Grant permissions to the service account
resource "google_project_iam_member" "cloud_run_permissions" {
  project = var.project_id
  role    = "roles/logging.logWriter"
  member  = "serviceAccount:${google_service_account.cloud_run_sa.email}"
}

# Deploy the Cloud Run service
resource "google_cloud_run_service" "service" {
  name     = "my-service"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/my-image:latest"
        
        # Resource limits
        resources {
          limits = {
            cpu    = "1000m"
            memory = "512Mi"
          }
        }
        
        # Environment variables
        env {
          name  = "ENV_VAR_NAME"
          value = "env_var_value"
        }
        
        # Secret environment variables
        env {
          name = "SECRET_ENV_VAR"
          value_from {
            secret_key_ref {
              name = google_secret_manager_secret.my_secret.secret_id
              key  = "latest"
            }
          }
        }
        
        # Container ports
        ports {
          container_port = 8080
        }
      }
      
      # Service account
      service_account_name = google_service_account.cloud_run_sa.email
      
      # Concurrency settings
      container_concurrency = 80
      
      # Timeout
      timeout_seconds = 300
    }
    
    metadata {
      annotations = {
        "autoscaling.knative.dev/maxScale" = "100"
        "autoscaling.knative.dev/minScale" = "1"
        "run.googleapis.com/client-name"   = "terraform"
      }
    }
  }
  
  traffic {
    percent         = 100
    latest_revision = true
  }
  
  # Auto-generate revision name
  autogenerate_revision_name = true
}

# Allow public access to the service
resource "google_cloud_run_service_iam_member" "public_access" {
  location = google_cloud_run_service.service.location
  service  = google_cloud_run_service.service.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}

# Create a secret for the service
resource "google_secret_manager_secret" "my_secret" {
  secret_id = "my-service-secret"
  
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "my_secret_version" {
  secret      = google_secret_manager_secret.my_secret.id
  secret_data = "my-secret-value"
}

# Grant access to secret
resource "google_secret_manager_secret_iam_member" "secret_access" {
  secret_id = google_secret_manager_secret.my_secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.cloud_run_sa.email}"
}

# Output the service URL
output "service_url" {
  value = google_cloud_run_service.service.status[0].url
}

Cloud Run Service with VPC Access

# Create a VPC
resource "google_compute_network" "vpc" {
  name                    = "cloudrun-vpc"
  auto_create_subnetworks = false
}

# Create a subnet
resource "google_compute_subnetwork" "subnet" {
  name          = "cloudrun-subnet"
  ip_cidr_range = "10.0.0.0/24"
  region        = var.region
  network       = google_compute_network.vpc.id
}

# Create a VPC connector for Cloud Run
resource "google_vpc_access_connector" "connector" {
  name          = "vpc-connector"
  region        = var.region
  ip_cidr_range = "10.8.0.0/28"
  network       = google_compute_network.vpc.name
}

# Deploy Cloud Run service with VPC connector
resource "google_cloud_run_service" "vpc_service" {
  name     = "vpc-service"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/my-vpc-app:latest"
        
        # Environment variables
        env {
          name  = "INTERNAL_SERVICE_URL"
          value = "http://internal-service.private.run:8080"
        }
      }
      
      # Service account
      service_account_name = google_service_account.cloud_run_sa.email
    }
    
    metadata {
      annotations = {
        "run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.id
        "run.googleapis.com/vpc-access-egress"    = "private-ranges-only"
      }
    }
  }
}

Cloud Run Service with Traffic Splitting

# Deploy Cloud Run service with multiple revisions
resource "google_cloud_run_service" "multi_revision_service" {
  name     = "multi-revision-service"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/my-image:v2"
      }
    }
    
    metadata {
      name = "multi-revision-service-green"
      annotations = {
        "run.googleapis.com/client-name" = "terraform"
      }
    }
  }
  
  # Traffic splitting between revisions
  traffic {
    percent       = 80
    revision_name = "multi-revision-service-green"
  }
  
  traffic {
    percent       = 20
    revision_name = "multi-revision-service-blue"
    # This revision needs to exist before applying this configuration
  }
}

Cloud Run with Custom Domain Mapping

# Create a Cloud Run service
resource "google_cloud_run_service" "website" {
  name     = "website"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/website:latest"
      }
    }
  }
}

# Create a domain mapping
resource "google_cloud_run_domain_mapping" "domain_mapping" {
  location = var.region
  name     = "example.com"
  
  metadata {
    namespace = var.project_id
  }
  
  spec {
    route_name = google_cloud_run_service.website.name
  }
}

# Output the resource records that should be added to DNS
output "dns_records" {
  value = [for record in google_cloud_run_domain_mapping.domain_mapping.status[0].resource_records : {
    name  = record.name
    type  = record.type
    rrdatas = record.rrdatas
  }]
}

Deploying Cloud Run with gcloud CLI

Building and Deploying a Container

# Navigate to your app directory
cd ~/my-app

# Create a Dockerfile
cat > Dockerfile << EOF
FROM node:16-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "index.js" ]
EOF

# Build and push the container image
gcloud builds submit --tag gcr.io/$(gcloud config get-value project)/my-app:v1

# Deploy to Cloud Run
gcloud run deploy my-app \
  --image gcr.io/$(gcloud config get-value project)/my-app:v1 \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated

Updating an Existing Service

# Deploy a new revision
gcloud run deploy my-app \
  --image gcr.io/$(gcloud config get-value project)/my-app:v2 \
  --platform managed \
  --region us-central1
  
# Split traffic between revisions
gcloud run services update-traffic my-app \
  --platform managed \
  --region us-central1 \
  --to-revisions my-app-00001-abc=80,my-app-00002-def=20

Creating a Private Service

# Deploy a private Cloud Run service
gcloud run deploy private-service \
  --image gcr.io/$(gcloud config get-value project)/private-service:v1 \
  --platform managed \
  --region us-central1 \
  --no-allow-unauthenticated
  
# Grant access to a specific user
gcloud run services add-iam-policy-binding private-service \
  --platform managed \
  --region us-central1 \
  --member="user:user@example.com" \
  --role="roles/run.invoker"

# Grant access to another service account
gcloud run services add-iam-policy-binding private-service \
  --platform managed \
  --region us-central1 \
  --member="serviceAccount:my-sa@$(gcloud config get-value project).iam.gserviceaccount.com" \
  --role="roles/run.invoker"

Configure VPC Connector

# Create a VPC connector
gcloud compute networks vpc-access connectors create my-connector \
  --network default \
  --region us-central1 \
  --range 10.8.0.0/28

# Deploy with VPC connector
gcloud run deploy vpc-app \
  --image gcr.io/$(gcloud config get-value project)/vpc-app:v1 \
  --platform managed \
  --region us-central1 \
  --vpc-connector my-connector \
  --vpc-egress private-ranges-only

Configure Environment Variables and Secrets

# Create a secret in Secret Manager
echo -n "my-secret-value" | gcloud secrets create my-secret \
  --replication-policy="automatic" \
  --data-file=-

# Grant access to the secret
gcloud secrets add-iam-policy-binding my-secret \
  --member="serviceAccount:$(gcloud iam service-accounts list --filter="EMAIL:cloud-run-sa*" --format="value(EMAIL)")" \
  --role="roles/secretmanager.secretAccessor"

# Deploy with environment variables and secret
gcloud run deploy env-app \
  --image gcr.io/$(gcloud config get-value project)/env-app:v1 \
  --platform managed \
  --region us-central1 \
  --set-env-vars "KEY1=VALUE1,KEY2=VALUE2" \
  --update-secrets="SECRET1=my-secret:latest"

Real-World Example: Microservices Application

This example demonstrates a complete microservices architecture using Cloud Run:

Step 1: Infrastructure Setup with Terraform

# Set up the infrastructure for a microservices application
provider "google" {
  project = var.project_id
  region  = var.region
}

# Create VPC for services
resource "google_compute_network" "vpc" {
  name                    = "microservices-vpc"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnet" {
  name          = "microservices-subnet"
  ip_cidr_range = "10.0.0.0/20"
  region        = var.region
  network       = google_compute_network.vpc.id
}

# Create a VPC connector
resource "google_vpc_access_connector" "connector" {
  name          = "microservices-vpc-connector"
  region        = var.region
  ip_cidr_range = "10.8.0.0/28"
  network       = google_compute_network.vpc.name
}

# Create Cloud SQL instance for databases
resource "google_sql_database_instance" "postgres" {
  name             = "microservices-postgres"
  database_version = "POSTGRES_13"
  region           = var.region
  
  settings {
    tier = "db-f1-micro"
    
    ip_configuration {
      ipv4_enabled    = false
      private_network = google_compute_network.vpc.id
      
      authorized_networks {
        name  = "office"
        value = var.office_ip_range
      }
    }
    
    backup_configuration {
      enabled            = true
      start_time         = "02:00"
      binary_log_enabled = false
    }
  }
  
  deletion_protection = true
}

# Create databases for each service
resource "google_sql_database" "auth_db" {
  name     = "auth-service-db"
  instance = google_sql_database_instance.postgres.name
}

resource "google_sql_database" "product_db" {
  name     = "product-service-db"
  instance = google_sql_database_instance.postgres.name
}

resource "google_sql_database" "order_db" {
  name     = "order-service-db"
  instance = google_sql_database_instance.postgres.name
}

# Create database users
resource "random_password" "auth_db_password" {
  length  = 16
  special = true
}

resource "random_password" "product_db_password" {
  length  = 16
  special = true
}

resource "random_password" "order_db_password" {
  length  = 16
  special = true
}

resource "google_sql_user" "auth_db_user" {
  name     = "auth-service"
  instance = google_sql_database_instance.postgres.name
  password = random_password.auth_db_password.result
}

resource "google_sql_user" "product_db_user" {
  name     = "product-service"
  instance = google_sql_database_instance.postgres.name
  password = random_password.product_db_password.result
}

resource "google_sql_user" "order_db_user" {
  name     = "order-service"
  instance = google_sql_database_instance.postgres.name
  password = random_password.order_db_password.result
}

# Create Redis instance for caching
resource "google_redis_instance" "cache" {
  name           = "microservices-cache"
  tier           = "BASIC"
  memory_size_gb = 1
  
  region                  = var.region
  authorized_network      = google_compute_network.vpc.id
  connect_mode            = "PRIVATE_SERVICE_ACCESS"
  redis_version           = "REDIS_6_X"
  display_name            = "Microservices Cache"
  reserved_ip_range       = "10.9.0.0/28"
  maintenance_policy {
    weekly_maintenance_window {
      day = "SUNDAY"
      start_time {
        hours   = 2
        minutes = 0
      }
    }
  }
}

# Store database credentials in Secret Manager
resource "google_secret_manager_secret" "auth_db_secret" {
  secret_id = "auth-db-credentials"
  
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "auth_db_secret_version" {
  secret = google_secret_manager_secret.auth_db_secret.id
  
  secret_data = jsonencode({
    username = google_sql_user.auth_db_user.name
    password = google_sql_user.auth_db_user.password
    database = google_sql_database.auth_db.name
    instance = google_sql_database_instance.postgres.connection_name
  })
}

resource "google_secret_manager_secret" "product_db_secret" {
  secret_id = "product-db-credentials"
  
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "product_db_secret_version" {
  secret = google_secret_manager_secret.product_db_secret.id
  
  secret_data = jsonencode({
    username = google_sql_user.product_db_user.name
    password = google_sql_user.product_db_user.password
    database = google_sql_database.product_db.name
    instance = google_sql_database_instance.postgres.connection_name
  })
}

resource "google_secret_manager_secret" "order_db_secret" {
  secret_id = "order-db-credentials"
  
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "order_db_secret_version" {
  secret = google_secret_manager_secret.order_db_secret.id
  
  secret_data = jsonencode({
    username = google_sql_user.order_db_user.name
    password = google_sql_user.order_db_user.password
    database = google_sql_database.order_db.name
    instance = google_sql_database_instance.postgres.connection_name
  })
}

# Create JWT secret for authentication
resource "random_password" "jwt_secret" {
  length  = 32
  special = true
}

resource "google_secret_manager_secret" "jwt_secret" {
  secret_id = "jwt-secret"
  
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "jwt_secret_version" {
  secret = google_secret_manager_secret.jwt_secret.id
  
  secret_data = random_password.jwt_secret.result
}

# Create service accounts for each service
resource "google_service_account" "auth_service_sa" {
  account_id   = "auth-service-sa"
  display_name = "Authentication Service"
}

resource "google_service_account" "product_service_sa" {
  account_id   = "product-service-sa"
  display_name = "Product Service"
}

resource "google_service_account" "order_service_sa" {
  account_id   = "order-service-sa"
  display_name = "Order Service"
}

resource "google_service_account" "frontend_sa" {
  account_id   = "frontend-sa"
  display_name = "Frontend Application"
}

# Grant permissions to service accounts
resource "google_project_iam_member" "auth_service_permissions" {
  for_each = toset([
    "roles/logging.logWriter",
    "roles/cloudtrace.agent",
    "roles/cloudsql.client"
  ])
  
  project = var.project_id
  role    = each.value
  member  = "serviceAccount:${google_service_account.auth_service_sa.email}"
}

resource "google_project_iam_member" "product_service_permissions" {
  for_each = toset([
    "roles/logging.logWriter",
    "roles/cloudtrace.agent",
    "roles/cloudsql.client"
  ])
  
  project = var.project_id
  role    = each.value
  member  = "serviceAccount:${google_service_account.product_service_sa.email}"
}

resource "google_project_iam_member" "order_service_permissions" {
  for_each = toset([
    "roles/logging.logWriter",
    "roles/cloudtrace.agent",
    "roles/cloudsql.client",
    "roles/pubsub.publisher"
  ])
  
  project = var.project_id
  role    = each.value
  member  = "serviceAccount:${google_service_account.order_service_sa.email}"
}

resource "google_project_iam_member" "frontend_permissions" {
  for_each = toset([
    "roles/logging.logWriter",
    "roles/cloudtrace.agent"
  ])
  
  project = var.project_id
  role    = each.value
  member  = "serviceAccount:${google_service_account.frontend_sa.email}"
}

# Grant access to secrets
resource "google_secret_manager_secret_iam_member" "auth_db_secret_access" {
  secret_id = google_secret_manager_secret.auth_db_secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.auth_service_sa.email}"
}

resource "google_secret_manager_secret_iam_member" "product_db_secret_access" {
  secret_id = google_secret_manager_secret.product_db_secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.product_service_sa.email}"
}

resource "google_secret_manager_secret_iam_member" "order_db_secret_access" {
  secret_id = google_secret_manager_secret.order_db_secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.order_service_sa.email}"
}

resource "google_secret_manager_secret_iam_member" "jwt_secret_access" {
  secret_id = google_secret_manager_secret.jwt_secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.auth_service_sa.email}"
}

# Create Pub/Sub topic for order events
resource "google_pubsub_topic" "order_events" {
  name = "order-events"
}

# Deploy the Authentication Service
resource "google_cloud_run_service" "auth_service" {
  name     = "auth-service"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/auth-service:latest"
        
        resources {
          limits = {
            cpu    = "1000m"
            memory = "512Mi"
          }
        }
        
        env {
          name  = "PORT"
          value = "8080"
        }
        
        env {
          name  = "NODE_ENV"
          value = "production"
        }
        
        env {
          name = "DB_CREDENTIALS"
          value_from {
            secret_key_ref {
              name = google_secret_manager_secret.auth_db_secret.secret_id
              key  = "latest"
            }
          }
        }
        
        env {
          name = "JWT_SECRET"
          value_from {
            secret_key_ref {
              name = google_secret_manager_secret.jwt_secret.secret_id
              key  = "latest"
            }
          }
        }
      }
      
      service_account_name = google_service_account.auth_service_sa.email
      
      # Add Cloud SQL proxy
      containers {
        image = "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.0"
        args = [
          "--structured-logs",
          "--port=5432",
          "${google_sql_database_instance.postgres.connection_name}"
        ]
      }
    }
    
    metadata {
      annotations = {
        "run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.id
        "run.googleapis.com/vpc-access-egress"    = "private-ranges-only"
        "run.googleapis.com/cloudsql-instances"   = google_sql_database_instance.postgres.connection_name
        "autoscaling.knative.dev/minScale"        = "1"
        "autoscaling.knative.dev/maxScale"        = "10"
      }
    }
  }
  
  traffic {
    percent         = 100
    latest_revision = true
  }
  
  autogenerate_revision_name = true
}

# Deploy Product Service
resource "google_cloud_run_service" "product_service" {
  name     = "product-service"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/product-service:latest"
        
        resources {
          limits = {
            cpu    = "1000m"
            memory = "512Mi"
          }
        }
        
        env {
          name  = "PORT"
          value = "8080"
        }
        
        env {
          name  = "NODE_ENV"
          value = "production"
        }
        
        env {
          name = "DB_CREDENTIALS"
          value_from {
            secret_key_ref {
              name = google_secret_manager_secret.product_db_secret.secret_id
              key  = "latest"
            }
          }
        }
        
        env {
          name  = "REDIS_HOST"
          value = google_redis_instance.cache.host
        }
        
        env {
          name  = "REDIS_PORT"
          value = google_redis_instance.cache.port
        }
      }
      
      service_account_name = google_service_account.product_service_sa.email
      
      # Add Cloud SQL proxy
      containers {
        image = "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.0"
        args = [
          "--structured-logs",
          "--port=5432",
          "${google_sql_database_instance.postgres.connection_name}"
        ]
      }
    }
    
    metadata {
      annotations = {
        "run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.id
        "run.googleapis.com/vpc-access-egress"    = "private-ranges-only"
        "run.googleapis.com/cloudsql-instances"   = google_sql_database_instance.postgres.connection_name
        "autoscaling.knative.dev/minScale"        = "1"
        "autoscaling.knative.dev/maxScale"        = "10"
      }
    }
  }
  
  traffic {
    percent         = 100
    latest_revision = true
  }
  
  autogenerate_revision_name = true
}

# Deploy Order Service
resource "google_cloud_run_service" "order_service" {
  name     = "order-service"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/order-service:latest"
        
        resources {
          limits = {
            cpu    = "1000m"
            memory = "512Mi"
          }
        }
        
        env {
          name  = "PORT"
          value = "8080"
        }
        
        env {
          name  = "NODE_ENV"
          value = "production"
        }
        
        env {
          name = "DB_CREDENTIALS"
          value_from {
            secret_key_ref {
              name = google_secret_manager_secret.order_db_secret.secret_id
              key  = "latest"
            }
          }
        }
        
        env {
          name  = "PRODUCT_SERVICE_URL"
          value = google_cloud_run_service.product_service.status[0].url
        }
        
        env {
          name  = "PUBSUB_TOPIC"
          value = google_pubsub_topic.order_events.id
        }
      }
      
      service_account_name = google_service_account.order_service_sa.email
      
      # Add Cloud SQL proxy
      containers {
        image = "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.1.0"
        args = [
          "--structured-logs",
          "--port=5432",
          "${google_sql_database_instance.postgres.connection_name}"
        ]
      }
    }
    
    metadata {
      annotations = {
        "run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.id
        "run.googleapis.com/vpc-access-egress"    = "private-ranges-only"
        "run.googleapis.com/cloudsql-instances"   = google_sql_database_instance.postgres.connection_name
        "autoscaling.knative.dev/minScale"        = "1"
        "autoscaling.knative.dev/maxScale"        = "10"
      }
    }
  }
  
  traffic {
    percent         = 100
    latest_revision = true
  }
  
  autogenerate_revision_name = true
}

# Deploy Frontend Application
resource "google_cloud_run_service" "frontend" {
  name     = "frontend"
  location = var.region
  
  template {
    spec {
      containers {
        image = "gcr.io/${var.project_id}/frontend:latest"
        
        resources {
          limits = {
            cpu    = "1000m"
            memory = "512Mi"
          }
        }
        
        env {
          name  = "PORT"
          value = "8080"
        }
        
        env {
          name  = "NODE_ENV"
          value = "production"
        }
        
        env {
          name  = "AUTH_SERVICE_URL"
          value = google_cloud_run_service.auth_service.status[0].url
        }
        
        env {
          name  = "PRODUCT_SERVICE_URL"
          value = google_cloud_run_service.product_service.status[0].url
        }
        
        env {
          name  = "ORDER_SERVICE_URL"
          value = google_cloud_run_service.order_service.status[0].url
        }
      }
      
      service_account_name = google_service_account.frontend_sa.email
    }
    
    metadata {
      annotations = {
        "autoscaling.knative.dev/minScale" = "1"
        "autoscaling.knative.dev/maxScale" = "10"
      }
    }
  }
  
  traffic {
    percent         = 100
    latest_revision = true
  }
  
  autogenerate_revision_name = true
}

# Make the frontend public
resource "google_cloud_run_service_iam_member" "frontend_public" {
  location = google_cloud_run_service.frontend.location
  service  = google_cloud_run_service.frontend.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}

# Set up service-to-service authentication
resource "google_cloud_run_service_iam_member" "product_service_auth" {
  location = google_cloud_run_service.product_service.location
  service  = google_cloud_run_service.product_service.name
  role     = "roles/run.invoker"
  member   = "serviceAccount:${google_service_account.order_service_sa.email}"
}

resource "google_cloud_run_service_iam_member" "auth_service_frontend_auth" {
  location = google_cloud_run_service.auth_service.location
  service  = google_cloud_run_service.auth_service.name
  role     = "roles/run.invoker"
  member   = "serviceAccount:${google_service_account.frontend_sa.email}"
}

resource "google_cloud_run_service_iam_member" "product_service_frontend_auth" {
  location = google_cloud_run_service.product_service.location
  service  = google_cloud_run_service.product_service.name
  role     = "roles/run.invoker"
  member   = "serviceAccount:${google_service_account.frontend_sa.email}"
}

resource "google_cloud_run_service_iam_member" "order_service_frontend_auth" {
  location = google_cloud_run_service.order_service.location
  service  = google_cloud_run_service.order_service.name
  role     = "roles/run.invoker"
  member   = "serviceAccount:${google_service_account.frontend_sa.email}"
}

# Output service URLs
output "frontend_url" {
  value = google_cloud_run_service.frontend.status[0].url
}

output "auth_service_url" {
  value = google_cloud_run_service.auth_service.status[0].url
}

output "product_service_url" {
  value = google_cloud_run_service.product_service.status[0].url
}

output "order_service_url" {
  value = google_cloud_run_service.order_service.status[0].url
}

Step 2: Example Authentication Service Code

// auth-service/server.js
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const { Pool } = require('pg');
const app = express();
const port = process.env.PORT || 8080;

// Parse credentials from Secret Manager
const dbCredentials = JSON.parse(process.env.DB_CREDENTIALS || '{}');
const jwtSecret = process.env.JWT_SECRET || 'default-secret';

// Set up database connection
const pool = new Pool({
  host: 'localhost', // Cloud SQL Proxy sidecar
  port: 5432,
  user: dbCredentials.username,
  password: dbCredentials.password,
  database: dbCredentials.database,
});

app.use(express.json());

// Middleware for logging and tracing
app.use((req, res, next) => {
  const traceHeader = req.header('X-Cloud-Trace-Context');
  console.log(`Request received: ${req.method} ${req.path} - Trace: ${traceHeader || 'none'}`);
  next();
});

// Initialize database tables if needed
async function initializeDatabase() {
  try {
    await pool.query(`
      CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        email VARCHAR(255) UNIQUE NOT NULL,
        password VARCHAR(255) NOT NULL,
        name VARCHAR(255) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
    console.log('Database tables initialized');
  } catch (error) {
    console.error('Error initializing database:', error);
  }
}

// Initialize the database when the service starts
initializeDatabase();

// Health check endpoint
app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok' });
});

// User registration
app.post('/register', async (req, res) => {
  try {
    const { email, password, name } = req.body;
    
    // Validate input
    if (!email || !password || !name) {
      return res.status(400).json({ error: 'Missing required fields' });
    }
    
    // Check if user already exists
    const existingUser = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
    
    if (existingUser.rows.length > 0) {
      return res.status(409).json({ error: 'User with this email already exists' });
    }
    
    // Hash the password
    const hashedPassword = await bcrypt.hash(password, 10);
    
    // Create the user
    const result = await pool.query(
      'INSERT INTO users (email, password, name) VALUES ($1, $2, $3) RETURNING id, email, name, created_at',
      [email, hashedPassword, name]
    );
    
    res.status(201).json(result.rows[0]);
  } catch (error) {
    console.error('Error in /register:', error);
    res.status(500).json({ error: 'An error occurred during registration' });
  }
});

// User login
app.post('/login', async (req, res) => {
  try {
    const { email, password } = req.body;
    
    // Validate input
    if (!email || !password) {
      return res.status(400).json({ error: 'Missing email or password' });
    }
    
    // Find the user
    const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
    
    if (result.rows.length === 0) {
      return res.status(401).json({ error: 'Invalid email or password' });
    }
    
    const user = result.rows[0];
    
    // Verify the password
    const validPassword = await bcrypt.compare(password, user.password);
    
    if (!validPassword) {
      return res.status(401).json({ error: 'Invalid email or password' });
    }
    
    // Generate a JWT token
    const token = jwt.sign(
      { userId: user.id, email: user.email },
      jwtSecret,
      { expiresIn: '24h' }
    );
    
    res.json({
      userId: user.id,
      email: user.email,
      name: user.name,
      token
    });
  } catch (error) {
    console.error('Error in /login:', error);
    res.status(500).json({ error: 'An error occurred during login' });
  }
});

// Verify token endpoint for other services
app.post('/verify', (req, res) => {
  try {
    const token = req.headers.authorization?.split(' ')[1];
    
    if (!token) {
      return res.status(401).json({ error: 'No token provided' });
    }
    
    jwt.verify(token, jwtSecret, (err, decoded) => {
      if (err) {
        return res.status(401).json({ error: 'Invalid or expired token' });
      }
      
      res.json({ valid: true, user: decoded });
    });
  } catch (error) {
    console.error('Error in /verify:', error);
    res.status(500).json({ error: 'An error occurred during token verification' });
  }
});

// Get user profile
app.get('/profile/:id', async (req, res) => {
  try {
    const token = req.headers.authorization?.split(' ')[1];
    
    if (!token) {
      return res.status(401).json({ error: 'No token provided' });
    }
    
    jwt.verify(token, jwtSecret, async (err, decoded) => {
      if (err) {
        return res.status(401).json({ error: 'Invalid or expired token' });
      }
      
      const userId = req.params.id;
      
      // Check if the user is requesting their own profile
      if (decoded.userId != userId) {
        return res.status(403).json({ error: 'Access denied' });
      }
      
      const result = await pool.query(
        'SELECT id, email, name, created_at FROM users WHERE id = $1',
        [userId]
      );
      
      if (result.rows.length === 0) {
        return res.status(404).json({ error: 'User not found' });
      }
      
      res.json(result.rows[0]);
    });
  } catch (error) {
    console.error('Error in /profile:', error);
    res.status(500).json({ error: 'An error occurred while fetching the profile' });
  }
});

// Start the server
app.listen(port, () => {
  console.log(`Auth service listening on port ${port}`);
});

Step 3: Example Product Service Code

// product-service/server.js
const express = require('express');
const { Pool } = require('pg');
const Redis = require('ioredis');
const app = express();
const port = process.env.PORT || 8080;

// Parse credentials from Secret Manager
const dbCredentials = JSON.parse(process.env.DB_CREDENTIALS || '{}');

// Set up database connection
const pool = new Pool({
  host: 'localhost', // Cloud SQL Proxy sidecar
  port: 5432,
  user: dbCredentials.username,
  password: dbCredentials.password,
  database: dbCredentials.database,
});

// Set up Redis connection
const redisClient = new Redis({
  host: process.env.REDIS_HOST,
  port: process.env.REDIS_PORT,
});

app.use(express.json());

// Middleware for logging and tracing
app.use((req, res, next) => {
  const traceHeader = req.header('X-Cloud-Trace-Context');
  console.log(`Request received: ${req.method} ${req.path} - Trace: ${traceHeader || 'none'}`);
  next();
});

// Initialize database tables if needed
async function initializeDatabase() {
  try {
    await pool.query(`
      CREATE TABLE IF NOT EXISTS categories (
        id SERIAL PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        description TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
    
    await pool.query(`
      CREATE TABLE IF NOT EXISTS products (
        id SERIAL PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        description TEXT,
        category_id INTEGER REFERENCES categories(id),
        price DECIMAL(10, 2) NOT NULL,
        stock INTEGER NOT NULL DEFAULT 0,
        image_url TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
    
    console.log('Product database tables initialized');
    
    // Add some sample data if tables are empty
    const categoryCount = await pool.query('SELECT COUNT(*) FROM categories');
    
    if (parseInt(categoryCount.rows[0].count) === 0) {
      await pool.query(`
        INSERT INTO categories (name, description) VALUES
        ('Electronics', 'Electronic gadgets and devices'),
        ('Books', 'Physical and digital books'),
        ('Clothing', 'Apparel and accessories')
      `);
      
      await pool.query(`
        INSERT INTO products (name, description, category_id, price, stock, image_url) VALUES
        ('Smartphone', 'Latest smartphone with advanced features', 1, 599.99, 50, 'https://example.com/smartphone.jpg'),
        ('Laptop', 'Powerful laptop for professionals', 1, 1299.99, 25, 'https://example.com/laptop.jpg'),
        ('Headphones', 'Noise-cancelling wireless headphones', 1, 199.99, 100, 'https://example.com/headphones.jpg'),
        ('Programming Book', 'Learn to code with this comprehensive guide', 2, 49.99, 30, 'https://example.com/programming-book.jpg'),
        ('T-Shirt', 'Comfortable cotton t-shirt', 3, 19.99, 200, 'https://example.com/tshirt.jpg')
      `);
      
      console.log('Added sample product data');
    }
  } catch (error) {
    console.error('Error initializing database:', error);
  }
}

// Initialize the database when the service starts
initializeDatabase();

// Health check endpoint
app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok' });
});

// Get all products with caching
app.get('/products', async (req, res) => {
  try {
    const cacheKey = 'products:all';
    
    // Try to get from cache first
    const cachedProducts = await redisClient.get(cacheKey);
    
    if (cachedProducts) {
      console.log('Cache hit for all products');
      return res.json(JSON.parse(cachedProducts));
    }
    
    console.log('Cache miss for all products, querying database');
    
    // Query database if not in cache
    const result = await pool.query(`
      SELECT p.*, c.name as category_name 
      FROM products p 
      JOIN categories c ON p.category_id = c.id
      ORDER BY p.name
    `);
    
    // Store in cache for 5 minutes
    await redisClient.set(cacheKey, JSON.stringify(result.rows), 'EX', 300);
    
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching products:', error);
    res.status(500).json({ error: 'Error fetching products' });
  }
});

// Get a single product by ID with caching
app.get('/products/:id', async (req, res) => {
  try {
    const productId = req.params.id;
    const cacheKey = `product:${productId}`;
    
    // Try to get from cache first
    const cachedProduct = await redisClient.get(cacheKey);
    
    if (cachedProduct) {
      console.log(`Cache hit for product ${productId}`);
      return res.json(JSON.parse(cachedProduct));
    }
    
    console.log(`Cache miss for product ${productId}, querying database`);
    
    // Query database if not in cache
    const result = await pool.query(`
      SELECT p.*, c.name as category_name 
      FROM products p 
      JOIN categories c ON p.category_id = c.id 
      WHERE p.id = $1
    `, [productId]);
    
    if (result.rows.length === 0) {
      return res.status(404).json({ error: 'Product not found' });
    }
    
    // Store in cache for 5 minutes
    await redisClient.set(cacheKey, JSON.stringify(result.rows[0]), 'EX', 300);
    
    res.json(result.rows[0]);
  } catch (error) {
    console.error(`Error fetching product ${req.params.id}:`, error);
    res.status(500).json({ error: 'Error fetching product' });
  }
});

// Get products by category with caching
app.get('/categories/:id/products', async (req, res) => {
  try {
    const categoryId = req.params.id;
    const cacheKey = `category:${categoryId}:products`;
    
    // Try to get from cache first
    const cachedProducts = await redisClient.get(cacheKey);
    
    if (cachedProducts) {
      console.log(`Cache hit for category ${categoryId} products`);
      return res.json(JSON.parse(cachedProducts));
    }
    
    console.log(`Cache miss for category ${categoryId} products, querying database`);
    
    // Query database if not in cache
    const result = await pool.query(`
      SELECT p.*, c.name as category_name 
      FROM products p 
      JOIN categories c ON p.category_id = c.id 
      WHERE c.id = $1
      ORDER BY p.name
    `, [categoryId]);
    
    // Store in cache for 5 minutes
    await redisClient.set(cacheKey, JSON.stringify(result.rows), 'EX', 300);
    
    res.json(result.rows);
  } catch (error) {
    console.error(`Error fetching products for category ${req.params.id}:`, error);
    res.status(500).json({ error: 'Error fetching products' });
  }
});

// Check product stock
app.get('/products/:id/stock', async (req, res) => {
  try {
    const productId = req.params.id;
    
    const result = await pool.query(
      'SELECT id, name, stock FROM products WHERE id = $1',
      [productId]
    );
    
    if (result.rows.length === 0) {
      return res.status(404).json({ error: 'Product not found' });
    }
    
    res.json(result.rows[0]);
  } catch (error) {
    console.error(`Error checking stock for product ${req.params.id}:`, error);
    res.status(500).json({ error: 'Error checking product stock' });
  }
});

// Update product stock (for internal service use)
app.post('/products/:id/stock', async (req, res) => {
  try {
    const productId = req.params.id;
    const { quantity } = req.body;
    
    if (quantity === undefined) {
      return res.status(400).json({ error: 'Quantity is required' });
    }
    
    // Begin transaction
    const client = await pool.connect();
    
    try {
      await client.query('BEGIN');
      
      // Check current stock
      const stockResult = await client.query(
        'SELECT stock FROM products WHERE id = $1 FOR UPDATE',
        [productId]
      );
      
      if (stockResult.rows.length === 0) {
        await client.query('ROLLBACK');
        return res.status(404).json({ error: 'Product not found' });
      }
      
      const currentStock = stockResult.rows[0].stock;
      const newStock = currentStock - quantity;
      
      if (newStock < 0) {
        await client.query('ROLLBACK');
        return res.status(400).json({ 
          error: 'Insufficient stock', 
          requested: quantity, 
          available: currentStock 
        });
      }
      
      // Update the stock
      await client.query(
        'UPDATE products SET stock = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
        [newStock, productId]
      );
      
      await client.query('COMMIT');
      
      // Invalidate cache
      await redisClient.del(`product:${productId}`);
      
      res.json({ 
        productId: parseInt(productId), 
        previousStock: currentStock, 
        newStock, 
        deducted: quantity 
      });
    } catch (e) {
      await client.query('ROLLBACK');
      throw e;
    } finally {
      client.release();
    }
  } catch (error) {
    console.error(`Error updating stock for product ${req.params.id}:`, error);
    res.status(500).json({ error: 'Error updating product stock' });
  }
});

// Start the server
app.listen(port, () => {
  console.log(`Product service listening on port ${port}`);
});

Step 4: Example of Frontend Integration

// frontend/src/api/services.js
import axios from 'axios';

// Service URLs from environment variables
const AUTH_SERVICE_URL = process.env.AUTH_SERVICE_URL;
const PRODUCT_SERVICE_URL = process.env.PRODUCT_SERVICE_URL;
const ORDER_SERVICE_URL = process.env.ORDER_SERVICE_URL;

// Create axios instances for each service
export const authApi = axios.create({
  baseURL: AUTH_SERVICE_URL,
});

export const productApi = axios.create({
  baseURL: PRODUCT_SERVICE_URL,
});

export const orderApi = axios.create({
  baseURL: ORDER_SERVICE_URL,
});

// Add authentication interceptor
const addAuthToken = (config) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
};

// Add interceptors to APIs that need authentication
productApi.interceptors.request.use(addAuthToken);
orderApi.interceptors.request.use(addAuthToken);

// Auth service methods
export const authService = {
  login: async (email, password) => {
    const response = await authApi.post('/login', { email, password });
    if (response.data.token) {
      localStorage.setItem('token', response.data.token);
      localStorage.setItem('user', JSON.stringify(response.data));
    }
    return response.data;
  },
  
  register: async (userData) => {
    return await authApi.post('/register', userData);
  },
  
  logout: () => {
    localStorage.removeItem('token');
    localStorage.removeItem('user');
  },
  
  getProfile: async (userId) => {
    return await authApi.get(`/profile/${userId}`);
  }
};

// Product service methods
export const productService = {
  getAllProducts: async () => {
    return await productApi.get('/products');
  },
  
  getProduct: async (id) => {
    return await productApi.get(`/products/${id}`);
  },
  
  getProductsByCategory: async (categoryId) => {
    return await productApi.get(`/categories/${categoryId}/products`);
  }
};

// Order service methods
export const orderService = {
  createOrder: async (orderData) => {
    return await orderApi.post('/orders', orderData);
  },
  
  getOrders: async () => {
    return await orderApi.get('/orders');
  },
  
  getOrder: async (id) => {
    return await orderApi.get(`/orders/${id}`);
  }
};

Best Practices

  1. Container Design

    • Use distroless or minimal base images

    • Follow the single responsibility principle

    • Optimize Dockerfile for layer caching

    • Implement proper health checks

    • Handle graceful shutdowns (SIGTERM)

    • Keep container images small

  2. Performance Optimization

    • Configure appropriate memory and CPU limits

    • Minimize container startup time

    • Implement connection pooling for databases

    • Use caching when appropriate

    • Scale container instances based on actual load

    • Use concurrency settings effectively

  3. Security

    • Use dedicated service accounts with minimal permissions

    • Store secrets in Secret Manager

    • Enable binary authorization if needed

    • Implement proper authentication and authorization

    • Scan container images for vulnerabilities

    • Follow the principle of least privilege

  4. Cost Optimization

    • Use CPU throttling for background services

    • Scale to zero when possible

    • Use min instances only for critical services

    • Monitor and set budget alerts

    • Optimize container image size

    • Use instance concurrency to handle multiple requests

  5. Networking and Connectivity

    • Use VPC Service Controls for additional security

    • Use VPC connectors for private services

    • Implement proper service-to-service authentication

    • Configure appropriate connection timeouts

    • Implement retry logic for network failures

    • Use Cloud CDN for static content

Common Issues and Troubleshooting

Container Startup Problems

  • Check container logs in Cloud Logging

  • Verify correct environment variables

  • Ensure the container listens on the correct port (defaults to 8080)

  • Check for permissions issues with service accounts

  • Review memory and CPU limits

Connection Issues

  • Verify VPC connector configuration

  • Check firewall rules

  • Ensure IAM permissions are set correctly

  • Verify service accounts have appropriate permissions

  • Check Cloud SQL connection settings

Performance Problems

  • Review concurrency settings

  • Check for memory leaks

  • Monitor CPU and memory usage

  • Verify database connection pooling

  • Look for slow external API calls

  • Implement proper caching

Deployment Failures

  • Check for errors in Cloud Build logs

  • Verify container can be pulled from registry

  • Ensure build process completes successfully

  • Review resource quota limitations

  • Check for syntax errors in configuration

Further Reading

PreviousGoogle Kubernetes Engine (GKE)NextArtifact Registry

Last updated 4 days ago

☁️
Cloud Run Documentation
Cloud Run vs Cloud Functions
Terraform Google Cloud Run Resources
Best Practices for Cloud Run
Cloud Run Samples