Skip to main content

Cloud Run Infrastructure Architecture

Overview

Pivot uses a standardized Cloud Run infrastructure pattern for deploying microservices. This architecture provides global availability, automatic scaling, managed SSL certificates, and infrastructure-as-code management through Terraform.

Key Benefits:

  • Serverless: Scale to zero when not in use, pay only for requests
  • Global: HTTPS load balancer with Google's global network
  • Secure: Managed SSL certificates with automatic renewal
  • Automated: CI/CD pipeline deploys on every push
  • Cost-Effective: ~$20-25/month per service for low-traffic environments

Architecture Pattern

All Pivot services deployed to Cloud Run follow this three-tier architecture:

Components Explained

Tier 1: Global Edge Layer

Purpose: Handle incoming traffic globally, terminate SSL, route to backend

  • Cloudflare DNS: Maps domain (docs.pivotdev.ca) to load balancer IP
  • Global HTTPS Load Balancer: Google's anycast network, routes traffic to nearest region
  • Certificate Manager: Automatically provisions and renews SSL certificates via DNS validation
  • HTTP → HTTPS Redirect: All HTTP traffic (port 80) redirects to HTTPS (port 443)

Tier 2: Regional Compute Layer

Purpose: Run the containerized application with automatic scaling

  • Cloud Run Service: Serverless container platform, scales 0-5 instances based on traffic
  • Network Endpoint Group (NEG): Connects Cloud Run to the load balancer
  • Backend Service: Routes requests from load balancer to Cloud Run instances

Tier 3: Container Registry

Purpose: Store and version Docker images

  • Google Container Registry (GCR): Private Docker registry for application images
  • Image Versioning: Each deployment tagged with Git commit SHA
  • Multi-stage Builds: Optimize image size and security

Request Flow

Request Timing:

  • Warm request: 50-200ms (instance already running)
  • Cold start: 1-3 seconds (first request after idle)
  • SSL termination: Handled at load balancer (no overhead to Cloud Run)

CI/CD Pipeline

Pipeline Steps:

  1. Trigger: Push to master branch or manual dispatch
  2. Build: Multi-stage Docker build (Node build → nginx production)
  3. Tag: Image tagged with $GITHUB_SHA for traceability
  4. Push: Upload to Google Container Registry
  5. Deploy: Update Cloud Run service with new image
  6. Rolling Update: Zero-downtime deployment

Deployment Time: ~2-3 minutes from push to live

Service Configuration

Resource Limits

Memory: 512Mi      # Adjustable per service needs
CPU: 1 # 1 vCPU
Instances:
Min: 0 # Scale to zero when idle
Max: 5 # Prevent runaway costs
Concurrency: 80 # Requests per instance

Auto-Scaling Behavior

Scaling Triggers:

  • Scale Up: When concurrency > 80 requests/instance
  • Scale Down: When traffic decreases
  • Scale to Zero: After 15 minutes of no requests

Infrastructure as Code

All infrastructure is managed via Terraform:

pivot-devops/infrastructure/
├── dev/ # Development environment
│ ├── main.tf # All infrastructure resources
│ ├── variables.tf # Configuration variables
│ ├── terraform.tfvars # Environment-specific values
│ └── backend.tf # State management (GCS)
├── staging/ # Staging environment (future)
└── production/ # Production environment (future)

Key Benefits:

  • Version Control: All infrastructure changes tracked in Git
  • Reproducible: Can recreate entire environment from code
  • Environment Parity: Dev/staging/production use same pattern
  • Audit Trail: Every change documented in Terraform state

Security Architecture

Security Features:

  • Transport Security: All traffic encrypted with TLS
  • Certificate Management: Google-managed, auto-renewing certificates
  • Least Privilege: Service accounts with minimal required permissions
  • Container Security: Alpine Linux base images, multi-stage builds
  • Secrets Management: Sensitive values in GitHub Secrets, never in code
  • Audit Logging: All deployments logged in Cloud Run

Cost Model

Monthly Cost Breakdown (Dev Environment)

ComponentCostNotes
Global Load Balancer~$18Fixed cost, always running
Cloud Run Compute$0-5Variable, scales to zero
Container Registry<$1Image storage
Certificate ManagerFreeIncluded with GCP
Cloudflare DNSFreeOn existing plan
Total~$19-24Per service, dev environment

Cost Scaling:

  • Low Traffic: Minimal cost (~$20/month) as Cloud Run scales to zero
  • High Traffic: Pay for actual compute time, no idle costs
  • Load Balancer: Fixed cost regardless of traffic (biggest cost component)

Cost Optimization:

  • Share load balancer across multiple services using path-based routing
  • Use staging environment only when needed (destroy when not in use)
  • Monitor and set budget alerts

Applying This Pattern to New Services

This architecture pattern is reusable for any Pivot microservice:

Current Services

  • pivot-docs: Documentation site (Docusaurus)
    • Domain: docs.pivotdev.ca
    • Resources: 512Mi / 1 CPU
    • Status: ✅ Live in dev

Future Services

Following the same pattern:

  • pivot-api: Main REST API

    • Domain: api.pivotdev.ca
    • Resources: 1Gi / 2 CPU (higher load)
  • pivot-webhooks: Webhook handlers (POS integrations, payment providers)

    • Domain: webhooks.pivotdev.ca
    • Resources: 512Mi / 1 CPU
  • pivot-admin: Admin dashboard

    • Domain: admin.pivotdev.ca
    • Resources: 512Mi / 1 CPU
  • pivot-integrations: Third-party integrations (Stripe, Square, etc.)

    • Domain: integrations.pivotdev.ca
    • Resources: 512Mi / 1 CPU

Replication Process

To deploy a new service:

  1. Copy Infrastructure: cp -r dev/ dev-{service}
  2. Update Configuration: Change service name, domain, resources in terraform.tfvars
  3. Create Dockerfile: Add to service repository
  4. Setup CI/CD: Copy GitHub Actions workflow from pivot-docs
  5. Deploy: terraform apply

Time to Deploy: ~30 minutes for new service (after first one)

Environment Strategy

Environment Characteristics

EnvironmentGCP ProjectDomain PatternAuto-DeployPurpose
Developmentpivot-dev-59310*.pivotdev.caYes (on push)Daily development, testing
Stagingpivot-stagingstaging.*.pivotdev.caManualPre-production validation
Productionpivot-inc*.pivotapp.caManual approvalCustomer-facing services

Monitoring & Observability

Built-in Metrics:

  • Request count, latency, error rate
  • Instance count, CPU, memory usage
  • Cold start frequency and duration
  • Certificate expiration (automatic alerts)

Logging:

  • All requests logged to Cloud Logging
  • Application logs streamed from containers
  • 100% sampling enabled on load balancer

Recommended Alerts:

  • Error rate > 5%
  • P95 latency > 2 seconds
  • Cost exceeds budget threshold
  • Certificate nearing expiration (auto-renewed, but monitored)

Best Practices

Development

  • Test locally with Docker before pushing
  • Use feature branches, merge to master when ready
  • Monitor first deployment to new environment

Infrastructure

  • Always run terraform plan before apply
  • Document any manual steps (rare, but necessary for bootstrapping)
  • Use lifecycle.ignore_changes for resources managed by CI/CD

Security

  • Never commit secrets to Git
  • Use GitHub Secrets for sensitive values
  • Rotate service account keys annually
  • Enable audit logging in production

Cost Management

  • Monitor costs weekly in Cloud Console
  • Set up budget alerts
  • Scale to zero in dev when not in use
  • Consider shared load balancers for multiple services

References

Implementation Guide: See /pivot-devops/infrastructure/COMPLETE-IMPLEMENTATION-PLAN.md for step-by-step deployment instructions.

Terraform Modules: All infrastructure code in /pivot-devops/infrastructure/{environment}/

Example Service: pivot-docs serves as the reference implementation.


Last Updated: November 2025 Architecture Version: 1.0