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:
- Trigger: Push to
masterbranch or manual dispatch - Build: Multi-stage Docker build (Node build → nginx production)
- Tag: Image tagged with
$GITHUB_SHAfor traceability - Push: Upload to Google Container Registry
- Deploy: Update Cloud Run service with new image
- 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)
| Component | Cost | Notes |
|---|---|---|
| Global Load Balancer | ~$18 | Fixed cost, always running |
| Cloud Run Compute | $0-5 | Variable, scales to zero |
| Container Registry | <$1 | Image storage |
| Certificate Manager | Free | Included with GCP |
| Cloudflare DNS | Free | On existing plan |
| Total | ~$19-24 | Per 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:
- Copy Infrastructure:
cp -r dev/ dev-{service} - Update Configuration: Change service name, domain, resources in
terraform.tfvars - Create Dockerfile: Add to service repository
- Setup CI/CD: Copy GitHub Actions workflow from pivot-docs
- Deploy:
terraform apply
Time to Deploy: ~30 minutes for new service (after first one)
Environment Strategy
Environment Characteristics
| Environment | GCP Project | Domain Pattern | Auto-Deploy | Purpose |
|---|---|---|---|---|
| Development | pivot-dev-59310 | *.pivotdev.ca | Yes (on push) | Daily development, testing |
| Staging | pivot-staging | staging.*.pivotdev.ca | Manual | Pre-production validation |
| Production | pivot-inc | *.pivotapp.ca | Manual approval | Customer-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 planbeforeapply - Document any manual steps (rare, but necessary for bootstrapping)
- Use
lifecycle.ignore_changesfor 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