
Deploying On Gcp
- 61 installs
- 426 repo stars
- Updated December 11, 2025
- ancoleman/ai-design-components
deploying-on-gcp is a Claude skill that provides decision frameworks and production patterns for selecting and architecting Google Cloud Platform services.
About
This skill provides decision frameworks and implementation patterns for Google Cloud Platform services across compute, storage, databases, analytics, ML, networking, and security. A developer uses it when selecting GCP services like Cloud Run, GKE, BigQuery, or Vertex AI, or when architecting cloud-native and multi-cloud systems. It guides service selection by workload requirements and demonstrates production-ready patterns.
- Decision frameworks for picking GCP compute, storage, and database services
- GCP vs AWS vs Azure service-mapping table
- Production patterns with Terraform, Python SDKs, and gcloud CLI
Deploying On Gcp by the numbers
- 61 all-time installs (skills.sh)
- Ranked #682 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
deploying-on-gcp capabilities & compatibility
- Capabilities
- gcp architecture · cloud service selection · data pipeline design · cloud migration
- Works with
- gcp · aws · azure · terraform · kubernetes · docker
- Use cases
- devops · database · ci cd
What deploying-on-gcp says it does
This skill provides decision frameworks and implementation patterns for Google Cloud Platform (GCP) services across compute, storage, databases, data analytics, machine learning, networking, and secur
First choice:** Cloud Run (unless state or Kubernetes required)
npx skills add https://github.com/ancoleman/ai-design-components --skill deploying-on-gcpAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 61 |
|---|---|
| repo stars | ★ 426 |
| Last updated | December 11, 2025 |
| Repository | ancoleman/ai-design-components ↗ |
What it does
Selecting and architecting GCP services (compute, storage, databases, analytics, ML) for cloud-native applications.
Who is it for?
Choosing between GCP compute/storage/database services and architecting cloud-native applications on GCP.
Skip if: AWS-only or Azure-only deployments where no GCP services are involved.
When should I use this skill?
Selecting GCP compute or database services, designing data pipelines, or migrating from AWS/Azure to GCP.
What you get
A justified GCP service selection with production-ready Terraform, SDK, and gcloud implementation patterns.
- GCP service selection
- Architecture patterns
- Terraform / gcloud configurations
By the numbers
- Covers 5 compute options (Cloud Run, GKE, Cloud Functions, Compute Engine, App Engine)
- 3-cloud service mapping table (GCP/AWS/Azure)
Files
GCP Patterns
Build applications and infrastructure using Google Cloud Platform services with appropriate service selection, architecture patterns, and best practices.
Purpose
This skill provides decision frameworks and implementation patterns for Google Cloud Platform (GCP) services across compute, storage, databases, data analytics, machine learning, networking, and security. It guides service selection based on workload requirements and demonstrates production-ready patterns using Terraform, Python SDKs, and gcloud CLI.
When to Use
Use this skill when:
- Selecting GCP compute services (Cloud Run, GKE, Cloud Functions, Compute Engine, App Engine)
- Choosing storage or database services (Cloud Storage, Cloud SQL, Spanner, Firestore, Bigtable, BigQuery)
- Designing data analytics pipelines (BigQuery, Pub/Sub, Dataflow, Dataproc, Composer)
- Implementing ML workflows (Vertex AI, AutoML, pre-trained APIs)
- Architecting network infrastructure (VPC, Load Balancing, CDN, Cloud Armor)
- Setting up IAM, security, and cost optimization
- Migrating from AWS or Azure to GCP
- Building multi-cloud or GCP-first architectures
Core Concepts
GCP Service Categories
Compute Options:
- Cloud Run: Serverless containers for stateless HTTP services (auto-scale to zero)
- GKE (Google Kubernetes Engine): Managed Kubernetes for complex orchestration
- Cloud Functions: Event-driven functions for simple processing
- Compute Engine: Virtual machines for full OS control
- App Engine: Platform-as-a-Service for web applications
Storage & Databases:
- Cloud Storage: Object storage with Standard/Nearline/Coldline/Archive tiers
- Cloud SQL: Managed PostgreSQL/MySQL/SQL Server (up to 96TB)
- Cloud Spanner: Global distributed SQL with 99.999% SLA
- Firestore: NoSQL document database with real-time sync
- Bigtable: Wide-column NoSQL for time-series and IoT (petabyte scale)
- AlloyDB: PostgreSQL-compatible with 4x performance improvement
Data & Analytics:
- BigQuery: Serverless data warehouse (petabyte-scale SQL analytics)
- Pub/Sub: Global messaging and event streaming
- Dataflow: Apache Beam for stream and batch processing
- Dataproc: Managed Spark and Hadoop clusters
- Cloud Composer: Managed Apache Airflow for workflows
AI/ML Services:
- Vertex AI: Unified ML platform (training, deployment, monitoring)
- AutoML: No-code ML for standard tasks
- Pre-trained APIs: Vision, Natural Language, Speech, Translation
- TPUs: Tensor Processing Units for large model training
Decision Framework: Compute Service Selection
Need to run code in GCP?
├─ HTTP service?
│ ├─ YES → Stateless?
│ │ ├─ YES → Cloud Run (auto-scale to zero)
│ │ └─ NO → Need Kubernetes? → GKE | Compute Engine
│ └─ NO (Event-driven)
│ ├─ Simple function? → Cloud Functions
│ └─ Complex orchestration? → GKE | Cloud Run JobsSelection Guide:
- First choice: Cloud Run (unless state or Kubernetes required)
- Need Kubernetes: GKE Autopilot (managed) or Standard (full control)
- Simple events: Cloud Functions (60-min max execution)
- Full control: Compute Engine (VMs with custom configuration)
Decision Framework: Database Selection
Choose database type:
├─ Relational (SQL)
│ ├─ Multi-region required? → Cloud Spanner
│ ├─ PostgreSQL + high performance? → AlloyDB
│ └─ Standard RDBMS → Cloud SQL (PostgreSQL/MySQL/SQL Server)
│
├─ Document (NoSQL)
│ ├─ Mobile/web with offline sync? → Firestore
│ └─ Flexible schema, no offline? → MongoDB Atlas (Marketplace)
│
├─ Key-Value
│ ├─ Time-series or IoT data? → Bigtable
│ └─ Caching layer? → Memorystore (Redis/Memcached)
│
└─ Analytics
└─ Petabyte-scale SQL analytics → BigQueryDecision Framework: Storage Selection
Storage type needed?
├─ Objects/Files
│ ├─ Frequent access → Cloud Storage (Standard)
│ ├─ Monthly access → Cloud Storage (Nearline)
│ ├─ Quarterly access → Cloud Storage (Coldline)
│ └─ Yearly access → Cloud Storage (Archive)
│
├─ Block storage → Persistent Disk (SSD/Standard/Extreme)
└─ Shared filesystem → Filestore (NFS)GCP vs AWS vs Azure Service Mapping
| Category | GCP | AWS | Azure |
|---|---|---|---|
| Serverless Containers | Cloud Run | Fargate | Container Instances |
| Kubernetes | GKE | EKS | AKS |
| Functions | Cloud Functions | Lambda | Functions |
| VMs | Compute Engine | EC2 | Virtual Machines |
| Object Storage | Cloud Storage | S3 | Blob Storage |
| SQL Database | Cloud SQL | RDS | SQL Database |
| NoSQL Document | Firestore | DynamoDB | Cosmos DB |
| Data Warehouse | BigQuery | Redshift | Synapse |
| Messaging | Pub/Sub | SNS/SQS | Service Bus |
| ML Platform | Vertex AI | SageMaker | Machine Learning |
Architecture Patterns
Pattern 1: Serverless Web Application
Use Case: Stateless HTTP API with database and caching
Architecture:
Internet → Cloud Load Balancer → Cloud Run → Cloud SQL (PostgreSQL)
→ Memorystore (Redis)
→ Cloud StorageKey Services:
- Cloud Run for API service (auto-scaling containers)
- Cloud SQL for transactional data
- Memorystore for caching
- Cloud Storage for file uploads
For detailed Terraform configuration, see references/compute-services.md.
Pattern 2: Data Analytics Platform
Use Case: Real-time event processing and analytics
Architecture:
Data Sources → Pub/Sub → Dataflow → BigQuery → Looker/Tableau
↓
Cloud Storage (staging)Key Services:
- Pub/Sub for event ingestion (at-least-once delivery)
- Dataflow for stream processing (Apache Beam)
- BigQuery for analytics (partitioned tables, clustering)
- Cloud Storage for staging and backups
For BigQuery optimization patterns, see references/data-analytics.md.
Pattern 3: ML Pipeline
Use Case: End-to-end machine learning workflow
Architecture:
Training Data (GCS) → Vertex AI Training → Model Registry → Vertex AI Endpoints
↓
PredictionsKey Services:
- Vertex AI Workbench for notebook development
- Vertex AI Training for custom models (GPU/TPU support)
- Vertex AI Endpoints for model serving (auto-scaling)
- Vertex AI Pipelines for orchestration (Kubeflow)
For ML implementation examples, see references/ml-ai-services.md.
Pattern 4: GKE Microservices Platform
Use Case: Complex orchestration with multiple services
Architecture:
Internet → Cloud Load Balancer → GKE Cluster
├─ Ingress Controller
├─ Service Mesh (optional)
├─ Microservice A
├─ Microservice B
└─ Microservice CKey Features:
- GKE Autopilot (fully managed nodes) or Standard (custom configuration)
- Workload Identity for secure GCP service access
- Private cluster with Private Google Access
- Config Connector for managing GCP resources via Kubernetes
For GKE setup and best practices, see references/compute-services.md.
Best Practices
Cost Optimization
Compute:
- Use Committed Use Discounts for predictable workloads (57% off)
- Use Spot VMs for fault-tolerant workloads (60-91% off)
- Cloud Run scales to zero when idle (no charges)
- GKE Autopilot charges only for pod resources, not nodes
Storage:
- Use appropriate Cloud Storage classes (Standard/Nearline/Coldline/Archive)
- Enable Object Lifecycle Management to transition cold data
- Archive backups with Coldline or Archive (99% cheaper than Standard)
Data:
- BigQuery: Use partitioned and clustered tables
- Query only needed columns (avoid
SELECT *) - Use BI Engine for caching (up to 10TB free)
- Consider flat-rate pricing for heavy BigQuery usage
For detailed cost strategies, see references/cost-optimization.md.
Security Fundamentals
IAM Best Practices:
- Follow principle of least privilege
- Use service accounts, not user accounts for applications
- Enable Workload Identity for GKE workloads (no service account keys)
- Use Secret Manager for secrets, not environment variables
Network Security:
- Use Private Google Access (access GCP services without public IPs)
- Enable Cloud NAT for outbound internet from private instances
- Implement VPC Service Controls for data exfiltration protection
- Use Identity-Aware Proxy (IAP) for zero-trust access
Data Security:
- Enable encryption at rest (default) and in transit
- Use Customer-Managed Encryption Keys (CMEK) for sensitive data
- Implement VPC Service Controls perimeter for data protection
- Enable audit logging for all projects
For comprehensive security patterns, see references/security-iam.md.
High Availability
Multi-Region Strategy:
- Cloud Storage: Use multi-region locations (US, EU, ASIA)
- Cloud SQL: Enable Regional HA (automatic failover)
- Cloud Spanner: Use multi-region configurations (99.999% SLA)
- Global Load Balancing: Route traffic to nearest healthy backend
Backup and Disaster Recovery:
- Cloud SQL: Enable automated backups and point-in-time recovery
- Persistent Disk: Schedule snapshot backups
- Cloud Storage: Enable versioning for critical data
- BigQuery: Use table snapshots for time travel
For networking and HA patterns, see references/networking.md.
Quick Reference
Common gcloud Commands
# Project management
gcloud projects list
gcloud config set project PROJECT_ID
# Cloud Run
gcloud run deploy SERVICE_NAME --image IMAGE_URL --region REGION
gcloud run services list
# GKE
gcloud container clusters create-auto CLUSTER_NAME --region REGION
gcloud container clusters get-credentials CLUSTER_NAME --region REGION
# Cloud Storage
gsutil mb gs://BUCKET_NAME
gsutil cp FILE gs://BUCKET_NAME/
# BigQuery
bq mk DATASET_NAME
bq query --use_legacy_sql=false 'SELECT * FROM dataset.table LIMIT 10'
# Cloud SQL
gcloud sql instances create INSTANCE_NAME --database-version=POSTGRES_15 --region=REGION
gcloud sql connect INSTANCE_NAME --user=postgresFor complete command reference, see examples/gcloud/common-commands.sh.
Python SDK Quick Start
# Cloud Storage
from google.cloud import storage
client = storage.Client()
bucket = client.bucket('my-bucket')
blob = bucket.blob('file.txt')
blob.upload_from_filename('local-file.txt')
# BigQuery
from google.cloud import bigquery
client = bigquery.Client()
query = "SELECT * FROM `project.dataset.table` LIMIT 10"
results = client.query(query).result()
# Pub/Sub
from google.cloud import pubsub_v1
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path('project', 'topic-name')
future = publisher.publish(topic_path, b'message data')For complete Python examples, see examples/python/.
Terraform Quick Start
# Provider configuration
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "google" {
project = "my-project-id"
region = "us-central1"
}
# Cloud Run service
resource "google_cloud_run_service" "api" {
name = "api-service"
location = "us-central1"
template {
spec {
containers {
image = "gcr.io/project/api:latest"
}
}
}
}For complete Terraform examples, see examples/terraform/.
Service Selection Cheatsheet
| Requirement | Recommended Service | Alternative |
|---|---|---|
| Stateless HTTP API | Cloud Run | App Engine |
| Complex orchestration | GKE Autopilot | GKE Standard |
| Event processing | Cloud Functions | Cloud Run Jobs |
| Object storage | Cloud Storage | N/A |
| Relational database | Cloud SQL | AlloyDB, Spanner |
| NoSQL document | Firestore | MongoDB Atlas |
| Time-series data | Bigtable | N/A |
| Data warehouse | BigQuery | N/A |
| Message queue | Pub/Sub | N/A |
| Stream processing | Dataflow | Dataproc |
| Batch processing | Dataflow | Dataproc |
| ML training | Vertex AI | Custom on GKE |
| Caching | Memorystore Redis | N/A |
Integration with Other Skills
Related Skills:
- infrastructure-as-code: Use Terraform to provision GCP resources (see
examples/terraform/) - kubernetes-operations: Deploy and manage applications on GKE
- building-ci-pipelines: Use Cloud Build for CI/CD to Cloud Run or GKE
- secret-management: Use Secret Manager for sensitive configuration
- observability: Use Cloud Monitoring and Cloud Logging for metrics and logs
- data-architecture: Design data lakes and warehouses using BigQuery and Cloud Storage
- mlops-patterns: Implement ML pipelines using Vertex AI
- aws-patterns: Compare AWS and GCP service equivalents for multi-cloud
- azure-patterns: Compare Azure and GCP service equivalents
Progressive Disclosure
For detailed documentation:
- Compute services: See
references/compute-services.mdfor Cloud Run, GKE, Cloud Functions, Compute Engine, and App Engine patterns - Storage & databases: See
references/storage-databases.mdfor detailed service selection and configuration - Data analytics: See
references/data-analytics.mdfor BigQuery, Pub/Sub, Dataflow, and Dataproc patterns - ML/AI services: See
references/ml-ai-services.mdfor Vertex AI, AutoML, and pre-trained API usage - Networking: See
references/networking.mdfor VPC, Load Balancing, CDN, and Cloud Armor patterns - Security & IAM: See
references/security-iam.mdfor IAM patterns, Workload Identity, and Secret Manager - Cost optimization: See
references/cost-optimization.mdfor detailed cost reduction strategies
For working examples:
- Terraform configurations: See
examples/terraform/for infrastructure templates - Python SDK usage: See
examples/python/for client library examples - gcloud CLI commands: See
examples/gcloud/common-commands.shfor command reference
Key Decisions Summary
When choosing GCP:
- Data analytics workloads (BigQuery is best-in-class)
- ML/AI applications (Vertex AI, TPUs, Google Research backing)
- Kubernetes-native applications (GKE invented by Kubernetes creators)
- Serverless containers (Cloud Run is mature and cost-effective)
- Real-time streaming (Pub/Sub + Dataflow)
GCP's unique advantages:
- BigQuery: Serverless, petabyte-scale, fastest data warehouse
- Cloud Run: Most mature serverless container platform
- GKE: Most advanced managed Kubernetes (Autopilot mode)
- Vertex AI: Unified ML platform (training, deployment, monitoring)
- Per-second billing and sustained use discounts (automatic cost savings)
Multi-region recommendations:
- Production workloads: Use multi-region for 99.95%+ SLA
- Cloud Storage: Multi-region for global access
- Cloud Spanner: Multi-region for global transactions
- Global Load Balancing: Route to nearest healthy backend
#!/bin/bash
################################################################################
# GCP gcloud CLI Common Commands Reference
################################################################################
#
# Comprehensive reference for the most common gcloud CLI operations.
# Organized by service category with helpful comments and flag combinations.
#
# Usage:
# - Copy and adapt commands for your specific needs
# - Replace placeholders (PROJECT_ID, REGION, etc.) with actual values
# - All commands are non-destructive examples unless marked with [DESTRUCTIVE]
#
# Prerequisites:
# - gcloud CLI installed: https://cloud.google.com/sdk/docs/install
# - Authenticated: gcloud auth login
# - Project set: gcloud config set project PROJECT_ID
#
################################################################################
################################################################################
# 1. PROJECT AND ORGANIZATION MANAGEMENT
################################################################################
# List all projects you have access to
gcloud projects list
# Show detailed information about a project
gcloud projects describe PROJECT_ID
# Set active project (affects all subsequent commands)
gcloud config set project PROJECT_ID
# Show current configuration
gcloud config list
# Create a new project [REQUIRES ORG PERMISSIONS]
gcloud projects create PROJECT_ID \
--name="Project Display Name" \
--organization=ORGANIZATION_ID
# Link project to billing account [REQUIRES BILLING ADMIN]
gcloud billing projects link PROJECT_ID \
--billing-account=BILLING_ACCOUNT_ID
# List available billing accounts
gcloud billing accounts list
# Enable required APIs for a project
gcloud services enable compute.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable container.googleapis.com
gcloud services enable sqladmin.googleapis.com
gcloud services enable storage.googleapis.com
gcloud services enable bigquery.googleapis.com
# List enabled services in current project
gcloud services list --enabled
# Set default region and zone
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a
# View all available regions
gcloud compute regions list
# View all available zones
gcloud compute zones list
################################################################################
# 2. COMPUTE ENGINE OPERATIONS
################################################################################
# List all VM instances
gcloud compute instances list
# List instances in specific zone
gcloud compute instances list --zones=us-central1-a
# Create a standard VM instance
gcloud compute instances create INSTANCE_NAME \
--zone=us-central1-a \
--machine-type=e2-medium \
--image-family=debian-11 \
--image-project=debian-cloud \
--boot-disk-size=20GB \
--boot-disk-type=pd-standard \
--tags=http-server,https-server
# Create VM with custom startup script
gcloud compute instances create INSTANCE_NAME \
--zone=us-central1-a \
--machine-type=e2-medium \
--image-family=debian-11 \
--image-project=debian-cloud \
--metadata-from-file=startup-script=startup.sh
# Create VM with service account and scopes
gcloud compute instances create INSTANCE_NAME \
--zone=us-central1-a \
--machine-type=e2-medium \
--image-family=debian-11 \
--image-project=debian-cloud \
--service-account=SERVICE_ACCOUNT_EMAIL \
--scopes=cloud-platform
# Start a stopped instance
gcloud compute instances start INSTANCE_NAME --zone=us-central1-a
# Stop a running instance
gcloud compute instances stop INSTANCE_NAME --zone=us-central1-a
# Reset (restart) an instance
gcloud compute instances reset INSTANCE_NAME --zone=us-central1-a
# SSH into an instance
gcloud compute ssh INSTANCE_NAME --zone=us-central1-a
# SSH with specific user
gcloud compute ssh USERNAME@INSTANCE_NAME --zone=us-central1-a
# Copy files to instance
gcloud compute scp LOCAL_FILE INSTANCE_NAME:~/REMOTE_PATH --zone=us-central1-a
# Copy files from instance
gcloud compute scp INSTANCE_NAME:~/REMOTE_FILE ./LOCAL_PATH --zone=us-central1-a
# View instance details
gcloud compute instances describe INSTANCE_NAME --zone=us-central1-a
# List available machine types
gcloud compute machine-types list --filter="zone:us-central1-a"
# List available images
gcloud compute images list
# Delete an instance [DESTRUCTIVE]
gcloud compute instances delete INSTANCE_NAME --zone=us-central1-a --quiet
# Create instance template for managed instance groups
gcloud compute instance-templates create TEMPLATE_NAME \
--machine-type=e2-medium \
--image-family=debian-11 \
--image-project=debian-cloud \
--boot-disk-size=20GB
# Create managed instance group
gcloud compute instance-groups managed create GROUP_NAME \
--base-instance-name=INSTANCE_PREFIX \
--template=TEMPLATE_NAME \
--size=3 \
--zone=us-central1-a
# Set autoscaling for managed instance group
gcloud compute instance-groups managed set-autoscaling GROUP_NAME \
--zone=us-central1-a \
--min-num-replicas=2 \
--max-num-replicas=10 \
--target-cpu-utilization=0.75
################################################################################
# 3. CLOUD RUN DEPLOYMENTS
################################################################################
# Deploy a Cloud Run service from container image
gcloud run deploy SERVICE_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--platform=managed
# Deploy with specific memory and CPU limits
gcloud run deploy SERVICE_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--platform=managed \
--memory=512Mi \
--cpu=1 \
--max-instances=10 \
--min-instances=1
# Deploy with environment variables
gcloud run deploy SERVICE_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--set-env-vars=KEY1=VALUE1,KEY2=VALUE2
# Deploy with secrets from Secret Manager
gcloud run deploy SERVICE_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--set-secrets=DB_PASSWORD=db-password:latest
# Deploy with custom service account
gcloud run deploy SERVICE_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--service-account=SERVICE_ACCOUNT_EMAIL
# Deploy with VPC connector (private networking)
gcloud run deploy SERVICE_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--vpc-connector=CONNECTOR_NAME \
--vpc-egress=private-ranges-only
# Allow unauthenticated access (public)
gcloud run services add-iam-policy-binding SERVICE_NAME \
--region=us-central1 \
--member="allUsers" \
--role="roles/run.invoker"
# List all Cloud Run services
gcloud run services list
# Get service details
gcloud run services describe SERVICE_NAME --region=us-central1
# View service URL
gcloud run services describe SERVICE_NAME \
--region=us-central1 \
--format='value(status.url)'
# Update service with new image
gcloud run services update SERVICE_NAME \
--region=us-central1 \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:NEW_TAG
# Set traffic to specific revision (blue-green deployment)
gcloud run services update-traffic SERVICE_NAME \
--region=us-central1 \
--to-revisions=REVISION_1=50,REVISION_2=50
# View service logs
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=SERVICE_NAME" \
--limit=50 \
--format=json
# Delete a service [DESTRUCTIVE]
gcloud run services delete SERVICE_NAME --region=us-central1 --quiet
# Create Cloud Run Job (non-HTTP workload)
gcloud run jobs create JOB_NAME \
--image=gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region=us-central1 \
--tasks=1 \
--max-retries=3
# Execute a Cloud Run Job
gcloud run jobs execute JOB_NAME --region=us-central1
################################################################################
# 4. GKE CLUSTER MANAGEMENT
################################################################################
# Create GKE Autopilot cluster (fully managed)
gcloud container clusters create-auto CLUSTER_NAME \
--region=us-central1
# Create GKE Standard cluster (more control)
gcloud container clusters create CLUSTER_NAME \
--zone=us-central1-a \
--num-nodes=3 \
--machine-type=e2-medium \
--disk-size=50 \
--enable-autoscaling \
--min-nodes=2 \
--max-nodes=10
# Create private GKE cluster
gcloud container clusters create CLUSTER_NAME \
--zone=us-central1-a \
--enable-private-nodes \
--enable-private-endpoint \
--master-ipv4-cidr=172.16.0.0/28 \
--enable-ip-alias
# Create GKE cluster with Workload Identity
gcloud container clusters create CLUSTER_NAME \
--zone=us-central1-a \
--workload-pool=PROJECT_ID.svc.id.goog \
--enable-stackdriver-kubernetes
# List all clusters
gcloud container clusters list
# Get cluster details
gcloud container clusters describe CLUSTER_NAME --zone=us-central1-a
# Get cluster credentials (configures kubectl)
gcloud container clusters get-credentials CLUSTER_NAME \
--zone=us-central1-a
# Get credentials for regional cluster
gcloud container clusters get-credentials CLUSTER_NAME \
--region=us-central1
# Resize cluster node pool
gcloud container clusters resize CLUSTER_NAME \
--zone=us-central1-a \
--num-nodes=5
# Upgrade cluster to latest version
gcloud container clusters upgrade CLUSTER_NAME \
--zone=us-central1-a \
--master \
--cluster-version=latest
# Upgrade cluster nodes
gcloud container clusters upgrade CLUSTER_NAME \
--zone=us-central1-a \
--node-pool=default-pool
# Create additional node pool
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--zone=us-central1-a \
--machine-type=e2-standard-4 \
--num-nodes=3 \
--enable-autoscaling \
--min-nodes=2 \
--max-nodes=8
# List node pools
gcloud container node-pools list --cluster=CLUSTER_NAME --zone=us-central1-a
# Delete node pool [DESTRUCTIVE]
gcloud container node-pools delete POOL_NAME \
--cluster=CLUSTER_NAME \
--zone=us-central1-a \
--quiet
# Delete cluster [DESTRUCTIVE]
gcloud container clusters delete CLUSTER_NAME --zone=us-central1-a --quiet
################################################################################
# 5. CLOUD SQL OPERATIONS
################################################################################
# Create PostgreSQL instance
gcloud sql instances create INSTANCE_NAME \
--database-version=POSTGRES_15 \
--tier=db-f1-micro \
--region=us-central1
# Create PostgreSQL instance with high availability
gcloud sql instances create INSTANCE_NAME \
--database-version=POSTGRES_15 \
--tier=db-custom-2-7680 \
--region=us-central1 \
--availability-type=REGIONAL \
--backup-start-time=03:00
# Create MySQL instance
gcloud sql instances create INSTANCE_NAME \
--database-version=MYSQL_8_0 \
--tier=db-n1-standard-1 \
--region=us-central1
# List all Cloud SQL instances
gcloud sql instances list
# Get instance details
gcloud sql instances describe INSTANCE_NAME
# Set root password
gcloud sql users set-password root \
--host=% \
--instance=INSTANCE_NAME \
--password=PASSWORD
# Create database
gcloud sql databases create DATABASE_NAME \
--instance=INSTANCE_NAME
# List databases
gcloud sql databases list --instance=INSTANCE_NAME
# Create database user
gcloud sql users create USERNAME \
--instance=INSTANCE_NAME \
--password=PASSWORD
# List users
gcloud sql users list --instance=INSTANCE_NAME
# Connect to instance (requires Cloud SQL Proxy or whitelisted IP)
gcloud sql connect INSTANCE_NAME \
--user=postgres
# Create on-demand backup
gcloud sql backups create \
--instance=INSTANCE_NAME
# List backups
gcloud sql backups list --instance=INSTANCE_NAME
# Restore from backup
gcloud sql backups restore BACKUP_ID \
--backup-instance=SOURCE_INSTANCE \
--backup-id=BACKUP_ID
# Export database to Cloud Storage
gcloud sql export sql INSTANCE_NAME \
gs://BUCKET_NAME/backup.sql \
--database=DATABASE_NAME
# Import database from Cloud Storage
gcloud sql import sql INSTANCE_NAME \
gs://BUCKET_NAME/backup.sql \
--database=DATABASE_NAME
# Stop instance (save costs)
gcloud sql instances patch INSTANCE_NAME --activation-policy=NEVER
# Start instance
gcloud sql instances patch INSTANCE_NAME --activation-policy=ALWAYS
# Delete instance [DESTRUCTIVE]
gcloud sql instances delete INSTANCE_NAME --quiet
################################################################################
# 6. IAM AND SERVICE ACCOUNTS
################################################################################
# List IAM policy for project
gcloud projects get-iam-policy PROJECT_ID
# Grant role to user at project level
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="user:EMAIL@example.com" \
--role="roles/viewer"
# Grant role to service account
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/storage.objectViewer"
# Grant role to group
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="group:GROUP_EMAIL@example.com" \
--role="roles/editor"
# Remove role from member [DESTRUCTIVE]
gcloud projects remove-iam-policy-binding PROJECT_ID \
--member="user:EMAIL@example.com" \
--role="roles/viewer"
# Create service account
gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
--display-name="Service Account Display Name" \
--description="Service account for APPLICATION_NAME"
# List service accounts
gcloud iam service-accounts list
# Get service account details
gcloud iam service-accounts describe SERVICE_ACCOUNT_EMAIL
# Grant IAM role to service account
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/storage.admin"
# Create service account key [SECURITY RISK - use Workload Identity instead]
gcloud iam service-accounts keys create key.json \
--iam-account=SERVICE_ACCOUNT_EMAIL
# List service account keys
gcloud iam service-accounts keys list \
--iam-account=SERVICE_ACCOUNT_EMAIL
# Delete service account key [DESTRUCTIVE]
gcloud iam service-accounts keys delete KEY_ID \
--iam-account=SERVICE_ACCOUNT_EMAIL
# Enable IAM policy binding on service account (impersonation)
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
--member="user:EMAIL@example.com" \
--role="roles/iam.serviceAccountTokenCreator"
# List all available IAM roles
gcloud iam roles list
# Describe specific role
gcloud iam roles describe roles/storage.admin
# Test IAM permissions
gcloud projects test-iam-permissions PROJECT_ID \
--permissions=compute.instances.list,storage.buckets.list
# Delete service account [DESTRUCTIVE]
gcloud iam service-accounts delete SERVICE_ACCOUNT_EMAIL --quiet
################################################################################
# 7. NETWORKING (VPC, FIREWALL RULES)
################################################################################
# List VPC networks
gcloud compute networks list
# Create custom VPC network
gcloud compute networks create NETWORK_NAME \
--subnet-mode=custom
# Create subnet
gcloud compute networks subnets create SUBNET_NAME \
--network=NETWORK_NAME \
--region=us-central1 \
--range=10.0.0.0/24
# List subnets
gcloud compute networks subnets list
# List firewall rules
gcloud compute firewall-rules list
# Create firewall rule (allow HTTP)
gcloud compute firewall-rules create allow-http \
--network=NETWORK_NAME \
--allow=tcp:80 \
--source-ranges=0.0.0.0/0 \
--target-tags=http-server
# Create firewall rule (allow HTTPS)
gcloud compute firewall-rules create allow-https \
--network=NETWORK_NAME \
--allow=tcp:443 \
--source-ranges=0.0.0.0/0 \
--target-tags=https-server
# Create firewall rule (allow SSH from specific IPs)
gcloud compute firewall-rules create allow-ssh \
--network=NETWORK_NAME \
--allow=tcp:22 \
--source-ranges=203.0.113.0/24
# Create firewall rule (allow internal traffic)
gcloud compute firewall-rules create allow-internal \
--network=NETWORK_NAME \
--allow=tcp:0-65535,udp:0-65535,icmp \
--source-ranges=10.0.0.0/8
# Update firewall rule
gcloud compute firewall-rules update RULE_NAME \
--source-ranges=0.0.0.0/0
# Describe firewall rule
gcloud compute firewall-rules describe RULE_NAME
# Delete firewall rule [DESTRUCTIVE]
gcloud compute firewall-rules delete RULE_NAME --quiet
# List static external IP addresses
gcloud compute addresses list
# Reserve static external IP address
gcloud compute addresses create ADDRESS_NAME \
--region=us-central1
# Reserve global static IP (for load balancer)
gcloud compute addresses create ADDRESS_NAME --global
# Release static IP [DESTRUCTIVE]
gcloud compute addresses delete ADDRESS_NAME --region=us-central1 --quiet
# Create VPC peering
gcloud compute networks peerings create PEERING_NAME \
--network=NETWORK_NAME \
--peer-network=PEER_NETWORK_NAME
# List VPC peerings
gcloud compute networks peerings list --network=NETWORK_NAME
# Create Cloud Router (for Cloud NAT)
gcloud compute routers create ROUTER_NAME \
--network=NETWORK_NAME \
--region=us-central1
# Create Cloud NAT (for outbound internet from private instances)
gcloud compute routers nats create NAT_NAME \
--router=ROUTER_NAME \
--region=us-central1 \
--auto-allocate-nat-external-ips \
--nat-all-subnet-ip-ranges
# List Cloud Routers
gcloud compute routers list
# Create VPN tunnel
gcloud compute vpn-tunnels create TUNNEL_NAME \
--peer-address=PEER_IP \
--shared-secret=SECRET \
--target-vpn-gateway=GATEWAY_NAME \
--region=us-central1
################################################################################
# 8. CLOUD STORAGE OPERATIONS
################################################################################
# Note: Most Cloud Storage operations use 'gsutil' instead of 'gcloud'
# Create bucket
gsutil mb gs://BUCKET_NAME
# Create bucket with specific location and storage class
gsutil mb -l us-central1 -c STANDARD gs://BUCKET_NAME
# List buckets
gsutil ls
# List objects in bucket
gsutil ls gs://BUCKET_NAME
# List objects recursively
gsutil ls -r gs://BUCKET_NAME/**
# Upload file to bucket
gsutil cp LOCAL_FILE gs://BUCKET_NAME/
# Upload directory recursively
gsutil cp -r LOCAL_DIR gs://BUCKET_NAME/
# Download file from bucket
gsutil cp gs://BUCKET_NAME/OBJECT_NAME ./LOCAL_PATH
# Download directory recursively
gsutil cp -r gs://BUCKET_NAME/PREFIX ./LOCAL_PATH
# Sync local directory with bucket (like rsync)
gsutil rsync -r LOCAL_DIR gs://BUCKET_NAME/
# Move/rename object
gsutil mv gs://BUCKET_NAME/OLD_NAME gs://BUCKET_NAME/NEW_NAME
# Copy object to another bucket
gsutil cp gs://SOURCE_BUCKET/OBJECT gs://DEST_BUCKET/
# Delete object
gsutil rm gs://BUCKET_NAME/OBJECT_NAME
# Delete all objects with prefix
gsutil rm -r gs://BUCKET_NAME/PREFIX/**
# View object metadata
gsutil stat gs://BUCKET_NAME/OBJECT_NAME
# Make object publicly readable
gsutil acl ch -u AllUsers:R gs://BUCKET_NAME/OBJECT_NAME
# Make bucket publicly readable (all objects)
gsutil iam ch allUsers:objectViewer gs://BUCKET_NAME
# Set bucket lifecycle policy
gsutil lifecycle set lifecycle.json gs://BUCKET_NAME
# Example lifecycle.json for transitioning to Coldline after 90 days:
# {
# "rule": [
# {
# "action": {"type": "SetStorageClass", "storageClass": "COLDLINE"},
# "condition": {"age": 90}
# }
# ]
# }
# Enable versioning
gsutil versioning set on gs://BUCKET_NAME
# View bucket IAM policy
gsutil iam get gs://BUCKET_NAME
# Grant IAM role on bucket
gsutil iam ch serviceAccount:SERVICE_ACCOUNT_EMAIL:objectViewer gs://BUCKET_NAME
# Remove IAM role on bucket
gsutil iam ch -d serviceAccount:SERVICE_ACCOUNT_EMAIL:objectViewer gs://BUCKET_NAME
# Set CORS policy on bucket
gsutil cors set cors.json gs://BUCKET_NAME
# Example cors.json:
# [
# {
# "origin": ["https://example.com"],
# "method": ["GET", "POST"],
# "responseHeader": ["Content-Type"],
# "maxAgeSeconds": 3600
# }
# ]
# Delete bucket (must be empty) [DESTRUCTIVE]
gsutil rb gs://BUCKET_NAME
################################################################################
# 9. BIGQUERY OPERATIONS
################################################################################
# Note: BigQuery operations use 'bq' CLI tool
# List datasets
bq ls
# List datasets in specific project
bq ls --project_id=PROJECT_ID
# Create dataset
bq mk DATASET_NAME
# Create dataset with specific location
bq mk --location=US DATASET_NAME
# Create dataset with expiration (90 days)
bq mk --default_table_expiration 7776000 DATASET_NAME
# List tables in dataset
bq ls DATASET_NAME
# Show table schema
bq show DATASET_NAME.TABLE_NAME
# Show table details (schema, size, rows)
bq show --schema --format=prettyjson DATASET_NAME.TABLE_NAME
# Run query
bq query --use_legacy_sql=false 'SELECT * FROM `project.dataset.table` LIMIT 10'
# Run query and save results to table
bq query --use_legacy_sql=false --destination_table=DATASET.RESULT_TABLE \
'SELECT * FROM `project.dataset.table` WHERE column = "value"'
# Load CSV data into table
bq load --source_format=CSV DATASET.TABLE_NAME gs://BUCKET/file.csv schema.json
# Load JSON data into table
bq load --source_format=NEWLINE_DELIMITED_JSON \
DATASET.TABLE_NAME gs://BUCKET/file.json schema.json
# Load data with auto-detect schema
bq load --autodetect --source_format=CSV DATASET.TABLE_NAME gs://BUCKET/file.csv
# Export table to Cloud Storage
bq extract DATASET.TABLE_NAME gs://BUCKET/export.csv
# Export table as JSON
bq extract --destination_format=NEWLINE_DELIMITED_JSON \
DATASET.TABLE_NAME gs://BUCKET/export.json
# Copy table
bq cp DATASET.SOURCE_TABLE DATASET.DEST_TABLE
# Create table from query results
bq query --use_legacy_sql=false --destination_table=DATASET.NEW_TABLE \
'SELECT * FROM `project.dataset.table` WHERE date > "2024-01-01"'
# Create partitioned table (by date)
bq mk --table --time_partitioning_field=date \
DATASET.TABLE_NAME schema.json
# Create clustered table
bq mk --table --clustering_fields=field1,field2 \
DATASET.TABLE_NAME schema.json
# Update table schema
bq update DATASET.TABLE_NAME schema.json
# Delete table [DESTRUCTIVE]
bq rm -t DATASET.TABLE_NAME
# Delete dataset and all tables [DESTRUCTIVE]
bq rm -r -d DATASET_NAME
# Show running jobs
bq ls -j
# Cancel running job
bq cancel JOB_ID
# View job details
bq show -j JOB_ID
# Estimate query cost (dry run)
bq query --dry_run --use_legacy_sql=false \
'SELECT * FROM `project.dataset.large_table`'
################################################################################
# 10. ADDITIONAL USEFUL COMMANDS
################################################################################
# View audit logs
gcloud logging read "protoPayload.serviceName=compute.googleapis.com" \
--limit=50 \
--format=json
# View logs for specific resource
gcloud logging read "resource.type=gce_instance AND resource.labels.instance_id=INSTANCE_ID" \
--limit=50
# Create log sink (export to Cloud Storage)
gcloud logging sinks create SINK_NAME \
gs://BUCKET_NAME \
--log-filter='resource.type="gce_instance"'
# List log sinks
gcloud logging sinks list
# View Cloud Monitoring metrics
gcloud monitoring time-series list \
--filter='metric.type="compute.googleapis.com/instance/cpu/utilization"'
# Create uptime check
gcloud monitoring uptime-checks create UPTIME_CHECK_NAME \
--resource-type=uptime-url \
--host=example.com
# List Secret Manager secrets
gcloud secrets list
# Create secret
echo -n "secret-value" | gcloud secrets create SECRET_NAME --data-file=-
# Access secret value
gcloud secrets versions access latest --secret=SECRET_NAME
# Add new secret version
echo -n "new-secret-value" | gcloud secrets versions add SECRET_NAME --data-file=-
# Grant access to secret
gcloud secrets add-iam-policy-binding SECRET_NAME \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/secretmanager.secretAccessor"
# List operations (long-running tasks)
gcloud compute operations list
# View quota usage
gcloud compute project-info describe --project=PROJECT_ID
# Enable organization policies
gcloud resource-manager org-policies describe POLICY_NAME \
--project=PROJECT_ID
################################################################################
# 11. HELPFUL TIPS AND FLAG COMBINATIONS
################################################################################
# Use --format flag for custom output (json, yaml, csv, table)
gcloud compute instances list --format=json
gcloud compute instances list --format="table(name,zone,machineType,status)"
gcloud compute instances list --format="csv(name,zone,status)"
# Use --filter flag for filtering results
gcloud compute instances list --filter="zone:us-central1-a"
gcloud compute instances list --filter="status=RUNNING"
gcloud compute instances list --filter="name:prod-*"
# Combine filter and format
gcloud compute instances list \
--filter="status=RUNNING AND zone:us-central1" \
--format="table(name,zone,machineType)"
# Use --quiet or -q to skip confirmation prompts (useful for scripts)
gcloud compute instances delete INSTANCE_NAME --zone=us-central1-a --quiet
# Use --project flag to specify project (override current config)
gcloud compute instances list --project=OTHER_PROJECT_ID
# Get help for any command
gcloud compute instances create --help
gcloud run deploy --help
# Check version
gcloud version
# Update gcloud CLI
gcloud components update
# List installed components
gcloud components list
# Install additional components
gcloud components install kubectl
gcloud components install beta
gcloud components install alpha
# Use beta or alpha commands for preview features
gcloud beta compute instances create INSTANCE_NAME ...
gcloud alpha run services update SERVICE_NAME ...
# Authenticate with service account key (CI/CD pipelines)
gcloud auth activate-service-account --key-file=key.json
# Switch between configurations (useful for multiple projects/accounts)
gcloud config configurations create CONFIG_NAME
gcloud config configurations activate CONFIG_NAME
gcloud config configurations list
# Set properties in current configuration
gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a
# Unset properties
gcloud config unset project
################################################################################
# 12. COMMON WORKFLOWS
################################################################################
# Deploy containerized app to Cloud Run (complete workflow)
# 1. Build container
gcloud builds submit --tag gcr.io/PROJECT_ID/IMAGE_NAME:TAG
# 2. Deploy to Cloud Run
gcloud run deploy SERVICE_NAME \
--image gcr.io/PROJECT_ID/IMAGE_NAME:TAG \
--region us-central1 \
--platform managed \
--allow-unauthenticated
# 3. Get service URL
gcloud run services describe SERVICE_NAME \
--region=us-central1 \
--format='value(status.url)'
# Set up private GKE cluster with Cloud SQL (complete workflow)
# 1. Create VPC network
gcloud compute networks create gke-network --subnet-mode=custom
# 2. Create subnet
gcloud compute networks subnets create gke-subnet \
--network=gke-network \
--region=us-central1 \
--range=10.0.0.0/24
# 3. Create GKE cluster
gcloud container clusters create gke-cluster \
--region=us-central1 \
--network=gke-network \
--subnetwork=gke-subnet \
--enable-private-nodes \
--enable-ip-alias \
--workload-pool=PROJECT_ID.svc.id.goog
# 4. Create Cloud SQL instance
gcloud sql instances create db-instance \
--database-version=POSTGRES_15 \
--tier=db-custom-2-7680 \
--region=us-central1 \
--network=gke-network
# 5. Get credentials
gcloud container clusters get-credentials gke-cluster --region=us-central1
# Create load balanced web service (complete workflow)
# 1. Create instance template
gcloud compute instance-templates create web-template \
--machine-type=e2-medium \
--image-family=debian-11 \
--image-project=debian-cloud \
--tags=http-server \
--metadata-from-file=startup-script=startup.sh
# 2. Create managed instance group
gcloud compute instance-groups managed create web-group \
--base-instance-name=web \
--template=web-template \
--size=3 \
--region=us-central1
# 3. Set named port
gcloud compute instance-groups managed set-named-ports web-group \
--region=us-central1 \
--named-ports=http:80
# 4. Create health check
gcloud compute health-checks create http web-health-check \
--port=80 \
--request-path=/
# 5. Create backend service
gcloud compute backend-services create web-backend \
--protocol=HTTP \
--health-checks=web-health-check \
--global
# 6. Add instance group to backend
gcloud compute backend-services add-backend web-backend \
--instance-group=web-group \
--instance-group-region=us-central1 \
--global
# 7. Create URL map
gcloud compute url-maps create web-map \
--default-service=web-backend
# 8. Create target HTTP proxy
gcloud compute target-http-proxies create web-proxy \
--url-map=web-map
# 9. Create forwarding rule
gcloud compute forwarding-rules create web-forwarding-rule \
--global \
--target-http-proxy=web-proxy \
--ports=80
################################################################################
# END OF GCLOUD CLI REFERENCE
################################################################################
#
# For more information:
# - gcloud CLI reference: https://cloud.google.com/sdk/gcloud/reference
# - Best practices: https://cloud.google.com/sdk/gcloud/reference/topic/startup
# - Scripting guide: https://cloud.google.com/sdk/docs/scripting-gcloud
#
################################################################################
# Cloud Run Service with Best Practices
# This configuration demonstrates a production-ready Cloud Run deployment
# with IAM, networking, and security configurations
terraform {
required_version = ">= 1.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
# Provider configuration
provider "google" {
project = var.project_id
region = var.region
}
# Variables
variable "project_id" {
description = "GCP project ID"
type = string
}
variable "region" {
description = "GCP region for Cloud Run service"
type = string
default = "us-central1"
}
variable "service_name" {
description = "Name of the Cloud Run service"
type = string
default = "api-service"
}
variable "container_image" {
description = "Container image URL (e.g., gcr.io/project/image:tag)"
type = string
}
variable "max_instances" {
description = "Maximum number of container instances"
type = number
default = 10
}
variable "min_instances" {
description = "Minimum number of container instances (0 for scale to zero)"
type = number
default = 0
}
variable "cpu" {
description = "Number of CPUs per container (1, 2, 4, 8)"
type = string
default = "1"
}
variable "memory" {
description = "Memory allocation per container (e.g., 512Mi, 1Gi, 2Gi)"
type = string
default = "512Mi"
}
variable "allow_public_access" {
description = "Allow unauthenticated public access to the service"
type = bool
default = false
}
variable "environment_variables" {
description = "Environment variables for the container"
type = map(string)
default = {}
}
# Service Account for Cloud Run
# Following principle of least privilege - create dedicated service account
resource "google_service_account" "cloud_run_sa" {
account_id = "${var.service_name}-sa"
display_name = "Service Account for ${var.service_name} Cloud Run"
description = "Dedicated service account for Cloud Run service with minimal permissions"
}
# IAM binding to allow Cloud Run to use the service account
resource "google_service_account_iam_member" "cloud_run_sa_user" {
service_account_id = google_service_account.cloud_run_sa.name
role = "roles/iam.serviceAccountUser"
member = "serviceAccount:${var.project_id}.svc.id.goog[default/cloud-run]"
}
# Example IAM role for accessing Cloud SQL (if needed)
# Uncomment and adjust based on your requirements
# resource "google_project_iam_member" "cloud_sql_client" {
# project = var.project_id
# role = "roles/cloudsql.client"
# member = "serviceAccount:${google_service_account.cloud_run_sa.email}"
# }
# Example IAM role for accessing Cloud Storage (if needed)
# resource "google_project_iam_member" "storage_object_viewer" {
# project = var.project_id
# role = "roles/storage.objectViewer"
# member = "serviceAccount:${google_service_account.cloud_run_sa.email}"
# }
# Cloud Run Service
resource "google_cloud_run_v2_service" "main" {
name = var.service_name
location = var.region
# Use the dedicated service account
ingress = "INGRESS_TRAFFIC_ALL"
template {
# Scaling configuration
scaling {
min_instance_count = var.min_instances
max_instance_count = var.max_instances
}
# Service account for the running containers
service_account = google_service_account.cloud_run_sa.email
# VPC connector (optional - uncomment if using VPC resources)
# vpc_access {
# connector = google_vpc_access_connector.connector.id
# egress = "PRIVATE_RANGES_ONLY"
# }
# Container configuration
containers {
image = var.container_image
# Resource limits - important for cost control
resources {
limits = {
cpu = var.cpu
memory = var.memory
}
# CPU is always allocated (use true for always-on services)
cpu_idle = true
# Startup CPU boost for faster cold starts
startup_cpu_boost = true
}
# Environment variables (non-sensitive configuration)
dynamic "env" {
for_each = var.environment_variables
content {
name = env.key
value = env.value
}
}
# Example: Load secrets from Secret Manager (recommended for sensitive data)
# env {
# name = "DATABASE_PASSWORD"
# value_source {
# secret_key_ref {
# secret = google_secret_manager_secret.db_password.secret_id
# version = "latest"
# }
# }
# }
# Health check and startup probe
startup_probe {
http_get {
path = "/health"
port = 8080
}
initial_delay_seconds = 0
timeout_seconds = 1
period_seconds = 3
failure_threshold = 3
}
# Liveness probe - restart unhealthy containers
liveness_probe {
http_get {
path = "/health"
port = 8080
}
initial_delay_seconds = 10
timeout_seconds = 1
period_seconds = 10
failure_threshold = 3
}
# Container port
ports {
name = "http1"
container_port = 8080
}
}
# Timeout for request processing (max 3600 seconds)
timeout = "300s"
# Execution environment (Second generation recommended for better performance)
execution_environment = "EXECUTION_ENVIRONMENT_GEN2"
# Session affinity (optional - for stateful applications)
# session_affinity = true
}
# Traffic routing - 100% to latest revision
traffic {
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
percent = 100
}
# Lifecycle policy to prevent accidental deletion
lifecycle {
prevent_destroy = false # Set to true in production
}
# Labels for organization and cost tracking
labels = {
environment = "production"
managed_by = "terraform"
service = var.service_name
}
}
# IAM Policy for public access (if enabled)
# This allows unauthenticated invocations - use carefully!
resource "google_cloud_run_service_iam_member" "public_access" {
count = var.allow_public_access ? 1 : 0
service = google_cloud_run_v2_service.main.name
location = google_cloud_run_v2_service.main.location
role = "roles/run.invoker"
member = "allUsers"
}
# Example: Grant specific user or service account access
# resource "google_cloud_run_service_iam_member" "authorized_invoker" {
# service = google_cloud_run_v2_service.main.name
# location = google_cloud_run_v2_service.main.location
# role = "roles/run.invoker"
# member = "user:example@example.com"
# }
# Optional: VPC Connector for private networking
# Uncomment if Cloud Run needs to access resources in a VPC
# resource "google_vpc_access_connector" "connector" {
# name = "${var.service_name}-vpc-connector"
# region = var.region
# ip_cidr_range = "10.8.0.0/28"
# network = "default"
#
# # Throughput configuration
# min_throughput = 200
# max_throughput = 300
# }
# Optional: Cloud SQL Connection (if using Cloud SQL)
# Uncomment and configure based on your Cloud SQL instance
# resource "google_cloud_run_v2_service" "main_with_cloudsql" {
# # ... (same configuration as above)
#
# template {
# containers {
# # ... (container config)
# }
#
# # Cloud SQL instance connection
# cloud_sql_instances = [
# google_sql_database_instance.main.connection_name
# ]
# }
# }
# Outputs
output "service_url" {
description = "URL of the deployed Cloud Run service"
value = google_cloud_run_v2_service.main.uri
}
output "service_name" {
description = "Name of the Cloud Run service"
value = google_cloud_run_v2_service.main.name
}
output "service_account_email" {
description = "Email of the service account used by Cloud Run"
value = google_service_account.cloud_run_sa.email
}
output "latest_revision" {
description = "Latest deployed revision name"
value = google_cloud_run_v2_service.main.latest_ready_revision
}
# Example usage:
#
# 1. Initialize Terraform:
# terraform init
#
# 2. Plan the deployment:
# terraform plan -var="project_id=my-project" -var="container_image=gcr.io/my-project/api:v1"
#
# 3. Apply the configuration:
# terraform apply -var="project_id=my-project" -var="container_image=gcr.io/my-project/api:v1"
#
# 4. For public access:
# terraform apply -var="project_id=my-project" -var="container_image=gcr.io/my-project/api:v1" -var="allow_public_access=true"
#
# 5. Destroy resources:
# terraform destroy -var="project_id=my-project" -var="container_image=gcr.io/my-project/api:v1"
skill: "deploying-on-gcp"
version: "1.0"
domain: "cloud"
base_outputs:
# Core Terraform infrastructure files - ALWAYS produced
- path: "infrastructure/gcp/main.tf"
must_contain: ["terraform", "google", "provider"]
description: "Main Terraform configuration with provider setup"
- path: "infrastructure/gcp/variables.tf"
must_contain: ["variable", "project", "region"]
description: "Terraform variable definitions for GCP project and region"
- path: "infrastructure/gcp/outputs.tf"
must_contain: ["output"]
description: "Terraform outputs for resource endpoints and identifiers"
- path: "infrastructure/gcp/iam.tf"
must_contain: ["google_service_account", "google_project_iam"]
description: "IAM service accounts and role bindings"
- path: "infrastructure/gcp/networking.tf"
must_contain: ["google_compute_network", "google_compute_subnetwork"]
description: "VPC network and subnet configuration"
- path: ".gcloudignore"
must_contain: ["node_modules", ".git"]
description: "Files to ignore when deploying with gcloud"
conditional_outputs:
maturity:
starter:
# Single-region, basic setup, minimal complexity
- path: "infrastructure/gcp/backend.tf"
must_contain: ["backend", "local"]
description: "Local Terraform state backend for starter projects"
- path: "deploy.sh"
must_contain: ["gcloud", "deploy"]
description: "Simple deployment script using gcloud CLI"
- path: "README.md"
must_contain: ["Prerequisites", "gcloud auth login", "terraform init"]
description: "Setup and deployment instructions"
intermediate:
# Multi-environment, remote state, automated deployments
- path: "infrastructure/gcp/backend.tf"
must_contain: ["backend", "gcs", "bucket"]
description: "GCS backend for remote Terraform state"
- path: "infrastructure/gcp/environments/dev/terraform.tfvars"
must_contain: ["project", "region"]
description: "Development environment variables"
- path: "infrastructure/gcp/environments/staging/terraform.tfvars"
must_contain: ["project", "region"]
description: "Staging environment variables"
- path: "infrastructure/gcp/environments/prod/terraform.tfvars"
must_contain: ["project", "region"]
description: "Production environment variables"
- path: "infrastructure/gcp/monitoring.tf"
must_contain: ["google_monitoring", "google_logging"]
description: "Cloud Monitoring and Logging configuration"
- path: "scripts/deploy-environment.sh"
must_contain: ["terraform", "workspace", "apply"]
description: "Environment-aware deployment script"
advanced:
# Multi-region, HA, disaster recovery, comprehensive security
- path: "infrastructure/gcp/backend.tf"
must_contain: ["backend", "gcs", "bucket", "encryption"]
description: "Encrypted GCS backend with state locking"
- path: "infrastructure/gcp/environments/dev/terraform.tfvars"
must_contain: ["project", "region"]
description: "Development environment configuration"
- path: "infrastructure/gcp/environments/staging/terraform.tfvars"
must_contain: ["project", "region"]
description: "Staging environment configuration"
- path: "infrastructure/gcp/environments/prod/terraform.tfvars"
must_contain: ["project", "region", "multi_region"]
description: "Production multi-region configuration"
- path: "infrastructure/gcp/vpc-peering.tf"
must_contain: ["google_compute_network_peering"]
description: "VPC peering for multi-region or hybrid connectivity"
- path: "infrastructure/gcp/security.tf"
must_contain: ["google_secret_manager", "google_kms", "encryption"]
description: "Secret Manager and KMS encryption configuration"
- path: "infrastructure/gcp/monitoring.tf"
must_contain: ["google_monitoring_alert_policy", "google_logging_metric"]
description: "Comprehensive monitoring, alerting, and log-based metrics"
- path: "infrastructure/gcp/backup.tf"
must_contain: ["google_compute_snapshot", "schedule"]
description: "Automated backup and disaster recovery configuration"
- path: "infrastructure/gcp/vpc-service-controls.tf"
must_contain: ["google_access_context_manager", "perimeter"]
description: "VPC Service Controls for data exfiltration protection"
- path: "scripts/disaster-recovery.sh"
must_contain: ["backup", "restore", "snapshot"]
description: "Disaster recovery and failover procedures"
infrastructure:
kubernetes:
# GKE deployment files
- path: "infrastructure/gcp/gke-cluster.tf"
must_contain: ["google_container_cluster", "google_container_node_pool"]
description: "GKE cluster and node pool configuration"
- path: "infrastructure/gcp/gke-workload-identity.tf"
must_contain: ["google_service_account", "workload_identity_user"]
description: "Workload Identity for secure GCP service access"
- path: "k8s/deployment.yaml"
must_contain: ["apiVersion", "kind: Deployment", "spec"]
description: "Kubernetes deployment manifest"
- path: "k8s/service.yaml"
must_contain: ["apiVersion", "kind: Service", "type"]
description: "Kubernetes service manifest"
- path: "k8s/ingress.yaml"
must_contain: ["apiVersion", "kind: Ingress"]
description: "Kubernetes ingress for external access"
- path: "k8s/configmap.yaml"
must_contain: ["apiVersion", "kind: ConfigMap"]
description: "Application configuration as ConfigMap"
- path: "skaffold.yaml"
must_contain: ["apiVersion", "build", "deploy"]
description: "Skaffold configuration for local development and deployment"
managed_platform:
# Cloud Run deployment
- path: "infrastructure/gcp/cloud-run.tf"
must_contain: ["google_cloud_run_service", "template", "containers"]
description: "Cloud Run service configuration"
- path: "infrastructure/gcp/cloud-run-iam.tf"
must_contain: ["google_cloud_run_service_iam", "invoker"]
description: "Cloud Run IAM permissions for invokers"
- path: "Dockerfile"
must_contain: ["FROM", "EXPOSE", "CMD"]
description: "Container image for Cloud Run deployment"
- path: ".dockerignore"
must_contain: ["node_modules", ".git", "*.md"]
description: "Files to exclude from Docker build context"
- path: "cloudbuild.yaml"
must_contain: ["steps", "docker", "build", "gcloud", "run", "deploy"]
description: "Cloud Build pipeline for automated deployments"
# Cloud Functions deployment
- path: "infrastructure/gcp/cloud-functions.tf"
must_contain: ["google_cloudfunctions2_function", "runtime"]
description: "Cloud Functions (2nd gen) configuration"
- path: "functions/main.py"
must_contain: ["def", "request", "response"]
description: "Cloud Function entry point (Python example)"
- path: "functions/requirements.txt"
must_contain: ["functions-framework"]
description: "Python dependencies for Cloud Functions"
docker_compose:
# Compute Engine with Docker Compose
- path: "infrastructure/gcp/compute-instance.tf"
must_contain: ["google_compute_instance", "metadata_startup_script"]
description: "Compute Engine VM instance configuration"
- path: "infrastructure/gcp/firewall.tf"
must_contain: ["google_compute_firewall", "allow", "tcp"]
description: "Firewall rules for VM access"
- path: "docker-compose.yml"
must_contain: ["version", "services"]
description: "Docker Compose service definitions"
- path: "scripts/startup.sh"
must_contain: ["docker", "compose", "up"]
description: "VM startup script to launch Docker Compose"
- path: ".env.example"
must_contain: ["PROJECT_ID", "REGION"]
description: "Environment variable template"
scaffolding:
# Supporting files that enhance but aren't core deployment artifacts
- path: "infrastructure/gcp/terraform.tfvars.example"
reason: "Template for project-specific Terraform variables"
- path: "scripts/init-gcp-project.sh"
reason: "Script to enable required GCP APIs and create service accounts"
- path: "scripts/validate-deployment.sh"
reason: "Post-deployment validation and health checks"
- path: "docs/architecture.md"
reason: "Architecture diagram and design decisions"
- path: "docs/runbook.md"
reason: "Operational procedures and troubleshooting guide"
- path: ".terraform-version"
reason: "Specify required Terraform version for consistency"
- path: ".github/workflows/terraform-plan.yml"
reason: "CI pipeline for Terraform validation and planning"
- path: ".github/workflows/deploy.yml"
reason: "CI/CD pipeline for automated deployments"
metadata:
primary_blueprints: ["cloud"]
contributes_to:
- "GCP infrastructure provisioning"
- "Cloud deployment automation"
- "Infrastructure as Code"
- "Multi-environment management"
- "Cloud security and compliance"
- "Disaster recovery and high availability"
common_combinations:
- skill: "infrastructure-as-code"
reason: "Terraform best practices and module patterns"
- skill: "kubernetes-operations"
reason: "GKE cluster management and workload deployment"
- skill: "building-ci-pipelines"
reason: "Cloud Build and GitHub Actions integration"
- skill: "secret-management"
reason: "Secret Manager and sensitive data handling"
- skill: "observability"
reason: "Cloud Monitoring, Logging, and Trace integration"
- skill: "data-architecture"
reason: "BigQuery, Cloud Storage, and data pipeline deployment"
- skill: "implementing-mlops"
reason: "Vertex AI and ML infrastructure on GCP"
GCP Compute Services Reference
Detailed patterns and configurations for Google Cloud Platform compute services.
Table of Contents
1. Cloud Run (Serverless Containers) 2. Google Kubernetes Engine (GKE) 3. Cloud Functions 4. Compute Engine (VMs) 5. App Engine 6. Service Comparison Matrix
---
Cloud Run (Serverless Containers)
When to Use Cloud Run
Ideal For:
- Stateless HTTP services and APIs
- Microservices architecture
- Variable or unpredictable traffic
- Services that should scale to zero when idle
- Quick deployment without infrastructure management
Not Ideal For:
- Long-running jobs (use Cloud Run Jobs)
- Stateful applications (use GKE or Compute Engine)
- Applications requiring persistent connections (use GKE)
Cloud Run Configuration
Terraform Example:
resource "google_cloud_run_service" "api" {
name = "api-service"
location = "us-central1"
template {
spec {
containers {
image = "gcr.io/project-id/api:latest"
# Resource limits
resources {
limits = {
cpu = "2" # Up to 8 CPUs
memory = "2Gi" # Up to 32GB
}
}
# Environment variables
env {
name = "DATABASE_URL"
value = "postgresql://..."
}
# Secret from Secret Manager
env {
name = "API_KEY"
value_from {
secret_key_ref {
name = google_secret_manager_secret.api_key.secret_id
key = "latest"
}
}
}
# Port configuration
ports {
container_port = 8080
}
# Startup probe
startup_probe {
http_get {
path = "/health"
}
initial_delay_seconds = 0
timeout_seconds = 1
period_seconds = 3
failure_threshold = 3
}
}
# Concurrency control
container_concurrency = 80 # Max concurrent requests per instance
# Timeout
timeout_seconds = 300 # Max 60 minutes
# Service account for Workload Identity
service_account_name = google_service_account.api.email
}
metadata {
annotations = {
# Auto-scaling
"autoscaling.knative.dev/minScale" = "1"
"autoscaling.dev/maxScale" = "100"
# CPU allocation (always or request-based)
"run.googleapis.com/cpu-throttling" = "true" # CPU allocated only during requests
# Cloud SQL connection
"run.googleapis.com/cloudsql-instances" = google_sql_database_instance.main.connection_name
# VPC connector (for private resources)
"run.googleapis.com/vpc-access-connector" = google_vpc_access_connector.connector.id
"run.googleapis.com/vpc-access-egress" = "private-ranges-only"
}
labels = {
environment = "production"
team = "api"
}
}
}
traffic {
percent = 100
latest_revision = true
}
# Prevent accidental deletion
lifecycle {
prevent_destroy = true
}
}
# Public access
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
members = ["allUsers"]
}
}
resource "google_cloud_run_service_iam_policy" "noauth" {
location = google_cloud_run_service.api.location
service = google_cloud_run_service.api.name
policy_data = data.google_iam_policy.noauth.policy_data
}
# Private access (requires authentication)
resource "google_cloud_run_service_iam_member" "auth" {
location = google_cloud_run_service.api.location
service = google_cloud_run_service.api.name
role = "roles/run.invoker"
member = "serviceAccount:caller@project.iam.gserviceaccount.com"
}Cloud Run Jobs
For batch processing and scheduled tasks:
resource "google_cloud_run_v2_job" "batch_processor" {
name = "batch-processor"
location = "us-central1"
template {
template {
containers {
image = "gcr.io/project-id/batch:latest"
resources {
limits = {
cpu = "4"
memory = "8Gi"
}
}
}
# Max execution time
timeout = "3600s" # 1 hour
# Task configuration
max_retries = 3
}
# Parallelism
task_count = 10
parallelism = 5
}
}
# Schedule with Cloud Scheduler
resource "google_cloud_scheduler_job" "trigger" {
name = "trigger-batch"
description = "Trigger batch processing job"
schedule = "0 2 * * *" # Daily at 2am
time_zone = "America/New_York"
http_target {
http_method = "POST"
uri = "https://${google_cloud_run_v2_job.batch_processor.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${var.project_id}/jobs/${google_cloud_run_v2_job.batch_processor.name}:run"
oauth_token {
service_account_email = google_service_account.scheduler.email
}
}
}---
Google Kubernetes Engine (GKE)
When to Use GKE
Ideal For:
- Complex multi-service orchestration
- Stateful applications (databases, caches)
- Applications requiring persistent connections
- Existing Kubernetes deployments
- Advanced networking requirements
- Multi-tenant platforms
Not Ideal For:
- Simple stateless services (use Cloud Run)
- No Kubernetes expertise (use Cloud Run or App Engine)
GKE Autopilot vs Standard
| Feature | Autopilot | Standard |
|---|---|---|
| Node Management | Fully managed | Self-managed |
| Cost Model | Pay per pod resources | Pay for nodes |
| Configuration | Opinionated, secure defaults | Full customization |
| Scaling | Automatic | Manual or cluster autoscaler |
| Best For | Most workloads | Advanced customization needs |
GKE Autopilot Configuration
resource "google_container_cluster" "autopilot" {
name = "gke-autopilot-cluster"
location = "us-central1"
# Enable Autopilot
enable_autopilot = true
# Release channel (RAPID, REGULAR, STABLE)
release_channel {
channel = "REGULAR"
}
# IP allocation policy
ip_allocation_policy {
cluster_secondary_range_name = "pods"
services_secondary_range_name = "services"
}
# Workload Identity (required for Autopilot)
workload_identity_config {
workload_pool = "${var.project_id}.svc.id.goog"
}
# Private cluster
private_cluster_config {
enable_private_nodes = true
enable_private_endpoint = false
master_ipv4_cidr_block = "172.16.0.0/28"
}
# Master authorized networks
master_authorized_networks_config {
cidr_blocks {
cidr_block = "10.0.0.0/8"
display_name = "internal-network"
}
}
# Maintenance window
maintenance_policy {
daily_maintenance_window {
start_time = "03:00"
}
}
# Binary authorization
binary_authorization {
evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE"
}
# Network policy
network_policy {
enabled = true
provider = "PROVIDER_UNSPECIFIED"
}
# Monitoring and logging
monitoring_config {
enable_components = ["SYSTEM_COMPONENTS", "WORKLOADS"]
managed_prometheus {
enabled = true
}
}
logging_config {
enable_components = ["SYSTEM_COMPONENTS", "WORKLOADS"]
}
}GKE Standard Configuration
resource "google_container_cluster" "standard" {
name = "gke-standard-cluster"
location = "us-central1"
# Remove default node pool (create custom pool separately)
remove_default_node_pool = true
initial_node_count = 1
release_channel {
channel = "REGULAR"
}
workload_identity_config {
workload_pool = "${var.project_id}.svc.id.goog"
}
private_cluster_config {
enable_private_nodes = true
enable_private_endpoint = false
master_ipv4_cidr_block = "172.16.0.0/28"
}
ip_allocation_policy {
cluster_secondary_range_name = "pods"
services_secondary_range_name = "services"
}
network_policy {
enabled = true
provider = "PROVIDER_UNSPECIFIED"
}
addons_config {
http_load_balancing {
disabled = false
}
horizontal_pod_autoscaling {
disabled = false
}
network_policy_config {
disabled = false
}
gcp_filestore_csi_driver_config {
enabled = true
}
gce_persistent_disk_csi_driver_config {
enabled = true
}
}
}
# Custom node pool
resource "google_container_node_pool" "primary" {
name = "primary-pool"
location = "us-central1"
cluster = google_container_cluster.standard.name
node_count = 1
autoscaling {
min_node_count = 1
max_node_count = 10
}
management {
auto_repair = true
auto_upgrade = true
}
node_config {
preemptible = false
machine_type = "e2-standard-4"
disk_size_gb = 100
disk_type = "pd-standard"
# Service account with minimal permissions
service_account = google_service_account.gke_nodes.email
oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform"
]
# Workload Identity
workload_metadata_config {
mode = "GKE_METADATA"
}
# Shielded instance
shielded_instance_config {
enable_secure_boot = true
enable_integrity_monitoring = true
}
labels = {
environment = "production"
}
tags = ["gke-node"]
}
}
# Spot VM node pool (for fault-tolerant workloads)
resource "google_container_node_pool" "spot" {
name = "spot-pool"
location = "us-central1"
cluster = google_container_cluster.standard.name
node_count = 0
autoscaling {
min_node_count = 0
max_node_count = 20
}
node_config {
spot = true # 60-91% cheaper
machine_type = "e2-standard-4"
service_account = google_service_account.gke_nodes.email
oauth_scopes = [
"https://www.googleapis.com/auth/cloud-platform"
]
workload_metadata_config {
mode = "GKE_METADATA"
}
labels = {
workload-type = "batch"
}
taint {
key = "workload-type"
value = "batch"
effect = "NO_SCHEDULE"
}
}
}Workload Identity Setup
# Enable Workload Identity on cluster
gcloud container clusters update CLUSTER_NAME \
--workload-pool=PROJECT_ID.svc.id.goog
# Create Kubernetes service account
kubectl create serviceaccount KSA_NAME \
--namespace NAMESPACE
# Create GCP service account
gcloud iam service-accounts create GSA_NAME
# Bind Kubernetes SA to GCP SA
gcloud iam service-accounts add-iam-policy-binding \
GSA_NAME@PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"
# Annotate Kubernetes SA
kubectl annotate serviceaccount KSA_NAME \
--namespace NAMESPACE \
iam.gke.io/gcp-service-account=GSA_NAME@PROJECT_ID.iam.gserviceaccount.com---
Cloud Functions
When to Use Cloud Functions
Ideal For:
- Event-driven processing (Cloud Storage, Pub/Sub, Firestore triggers)
- Lightweight HTTP endpoints
- Single-purpose functions
- Integration glue between GCP services
Not Ideal For:
- Long-running tasks (10-minute max for gen2)
- Complex application logic (use Cloud Run)
- Stateful operations
Cloud Functions Gen2 (Recommended)
# Storage bucket for function source
resource "google_storage_bucket" "functions" {
name = "${var.project_id}-functions"
location = "US"
}
# Upload function source
resource "google_storage_bucket_object" "function_zip" {
name = "function-source.zip"
bucket = google_storage_bucket.functions.name
source = "path/to/function.zip"
}
# Cloud Function with HTTP trigger
resource "google_cloudfunctions2_function" "http_function" {
name = "http-function"
location = "us-central1"
build_config {
runtime = "python39"
entry_point = "hello_http"
source {
storage_source {
bucket = google_storage_bucket.functions.name
object = google_storage_bucket_object.function_zip.name
}
}
}
service_config {
max_instance_count = 100
min_instance_count = 0
available_memory = "256Mi"
timeout_seconds = 60
environment_variables = {
API_KEY = "value"
}
# Secret from Secret Manager
secret_environment_variables {
key = "DB_PASSWORD"
project_id = var.project_id
secret = google_secret_manager_secret.db_password.secret_id
version = "latest"
}
service_account_email = google_service_account.function.email
}
}
# Cloud Function with Pub/Sub trigger
resource "google_cloudfunctions2_function" "pubsub_function" {
name = "pubsub-function"
location = "us-central1"
build_config {
runtime = "python39"
entry_point = "process_message"
source {
storage_source {
bucket = google_storage_bucket.functions.name
object = google_storage_bucket_object.function_zip.name
}
}
}
service_config {
max_instance_count = 100
available_memory = "512Mi"
timeout_seconds = 300
}
event_trigger {
trigger_region = "us-central1"
event_type = "google.cloud.pubsub.topic.v1.messagePublished"
pubsub_topic = google_pubsub_topic.events.id
retry_policy = "RETRY_POLICY_RETRY"
}
}
# Cloud Function with Storage trigger
resource "google_cloudfunctions2_function" "storage_function" {
name = "storage-function"
location = "us-central1"
build_config {
runtime = "python39"
entry_point = "process_file"
source {
storage_source {
bucket = google_storage_bucket.functions.name
object = google_storage_bucket_object.function_zip.name
}
}
}
service_config {
max_instance_count = 50
available_memory = "1Gi"
timeout_seconds = 540
}
event_trigger {
trigger_region = "us-central1"
event_type = "google.cloud.storage.object.v1.finalized"
event_filters {
attribute = "bucket"
value = google_storage_bucket.uploads.name
}
}
}---
Compute Engine (VMs)
When to Use Compute Engine
Ideal For:
- Full OS control required
- GPU/TPU workloads
- Windows applications
- Legacy application lift-and-shift
- Custom kernel or networking
Not Ideal For:
- Simple web services (use Cloud Run)
- Don't want to manage infrastructure (use Cloud Run or App Engine)
Compute Engine Configuration
# Instance template for managed instance group
resource "google_compute_instance_template" "web" {
name_prefix = "web-template-"
machine_type = "e2-medium"
region = "us-central1"
disk {
source_image = "debian-cloud/debian-11"
auto_delete = true
boot = true
disk_size_gb = 20
disk_type = "pd-balanced"
}
network_interface {
network = google_compute_network.main.id
subnetwork = google_compute_subnetwork.private.id
# No external IP (use Cloud NAT)
access_config {
network_tier = "PREMIUM"
}
}
metadata_startup_script = file("startup.sh")
service_account {
email = google_service_account.instance.email
scopes = ["cloud-platform"]
}
shielded_instance_config {
enable_secure_boot = true
enable_integrity_monitoring = true
enable_vtpm = true
}
tags = ["web-server"]
lifecycle {
create_before_destroy = true
}
}
# Managed instance group with autoscaling
resource "google_compute_region_instance_group_manager" "web" {
name = "web-igm"
region = "us-central1"
base_instance_name = "web"
version {
instance_template = google_compute_instance_template.web.id
}
target_size = 3
named_port {
name = "http"
port = 80
}
auto_healing_policies {
health_check = google_compute_health_check.web.id
initial_delay_sec = 300
}
}
# Autoscaler
resource "google_compute_region_autoscaler" "web" {
name = "web-autoscaler"
region = "us-central1"
target = google_compute_region_instance_group_manager.web.id
autoscaling_policy {
min_replicas = 2
max_replicas = 10
cooldown_period = 60
cpu_utilization {
target = 0.6
}
}
}---
App Engine
When to Use App Engine
Ideal For:
- Simple web applications
- Quick prototyping
- Legacy App Engine applications
- No infrastructure management desired
Not Ideal For:
- New projects (Cloud Run is preferred)
- Need containerization (use Cloud Run)
- Complex orchestration (use GKE)
App Engine Configuration
# app.yaml
runtime: python39
entrypoint: gunicorn -b :$PORT main:app
instance_class: F2
automatic_scaling:
target_cpu_utilization: 0.65
min_instances: 1
max_instances: 10
min_pending_latency: 30ms
max_pending_latency: automatic
max_concurrent_requests: 50
env_variables:
API_KEY: "value"
handlers:
- url: /static
static_dir: static
- url: /.*
script: auto---
Service Comparison Matrix
| Feature | Cloud Run | GKE Autopilot | GKE Standard | Cloud Functions | Compute Engine | App Engine |
|---|---|---|---|---|---|---|
| Management | Fully managed | Fully managed | Self-managed nodes | Fully managed | Self-managed | Fully managed |
| Scale to Zero | Yes | No | No | Yes | No | No |
| Max Execution Time | 60 min | Unlimited | Unlimited | 60 min | Unlimited | 60 min |
| Min Instances | 0 | 0 | 0 | 0 | 0 | 1 |
| Max Instances | 1000 | Unlimited | Unlimited | 1000 | Unlimited | Unlimited |
| Cold Start | ~1s | N/A | N/A | 1-5s | Minutes | Seconds |
| Pricing Model | Per request | Per pod | Per node | Per invocation | Per VM hour | Per instance hour |
| Best For | HTTP APIs | Complex apps | Advanced K8s | Events | Full control | Simple web apps |
| Container Support | Yes | Yes | Yes | Limited | Yes | Limited |
| Persistent Connections | Limited | Yes | Yes | No | Yes | Limited |
| GPU Support | No | Yes | Yes | No | Yes | No |
Selection Decision Tree
Need to run application in GCP?
├─ Need Kubernetes? → YES
│ ├─ Need node customization? → YES → GKE Standard
│ └─ NO (want managed) → GKE Autopilot
│
├─ HTTP service? → YES
│ ├─ Stateless? → YES
│ │ ├─ Container-based? → YES → Cloud Run
│ │ └─ NO (simple web app) → App Engine
│ └─ NO (stateful) → Compute Engine or GKE
│
├─ Event-driven? → YES
│ ├─ Simple function? → YES → Cloud Functions
│ └─ Complex processing → Cloud Run Jobs
│
└─ Need full OS control? → YES → Compute EngineRecommendation: Start with Cloud Run for most HTTP services. Move to GKE only if you need Kubernetes-specific features or complex orchestration.
GCP Cost Optimization Reference
Strategies for reducing Google Cloud Platform costs.
Table of Contents
- Compute Cost Optimization
- Committed Use Discounts (57% off)
- Spot VMs (60-91% off)
- Right-Sizing VMs
- Cloud Run Cost Optimization
- Storage Cost Optimization
- Object Lifecycle Management
- Compression and Deduplication
- BigQuery Cost Optimization
- Partitioned and Clustered Tables
- Query Best Practices
- Flat-Rate Pricing
- Database Cost Optimization
- Cloud SQL Instance Scheduling
- Use Read Replicas Instead of Scaling Up
- Network Cost Optimization
- Use Regional Resources
- Cloud CDN for Egress
- Premium vs Standard Network Tier
- Monitoring and Alerts
- Cost Budget Alerts
- Cost Anomaly Detection
- Cost Optimization Summary
- Cost Monitoring Tools
- Best Practices Checklist
Compute Cost Optimization
Committed Use Discounts (57% off)
# Reserve compute resources for 1 or 3 years
resource "google_compute_commitment" "commitment" {
name = "compute-commitment"
region = "us-central1"
plan = "THIRTY_SIX_MONTH" # 1-year or 3-year
resources {
type = "VCPU"
amount = "100"
}
resources {
type = "MEMORY"
amount = "400" # GB
}
}Spot VMs (60-91% off)
resource "google_compute_instance_template" "spot" {
name_prefix = "spot-template-"
machine_type = "n2-standard-4"
scheduling {
preemptible = true
automatic_restart = false
on_host_maintenance = "TERMINATE"
provisioning_model = "SPOT"
instance_termination_action = "STOP"
}
disk {
source_image = "debian-cloud/debian-11"
}
network_interface {
network = "default"
}
}Right-Sizing VMs
# Get recommendations
gcloud recommender recommendations list \
--project=PROJECT_ID \
--location=us-central1 \
--recommender=google.compute.instance.MachineTypeRecommender
# Apply recommendation
gcloud compute instances set-machine-type INSTANCE_NAME \
--machine-type=n2-standard-2 \
--zone=us-central1-aCloud Run Cost Optimization
resource "google_cloud_run_service" "optimized" {
name = "optimized-service"
location = "us-central1"
template {
spec {
containers {
image = "gcr.io/project/app:latest"
resources {
limits = {
cpu = "1" # Right-size CPU
memory = "512Mi" # Right-size memory
}
}
}
# Scale to zero when idle
container_concurrency = 80
}
metadata {
annotations = {
"autoscaling.knative.dev/minScale" = "0" # Scale to zero
"autoscaling.knative.dev/maxScale" = "10"
# CPU allocated only during requests
"run.googleapis.com/cpu-throttling" = "true"
}
}
}
}Storage Cost Optimization
Object Lifecycle Management
resource "google_storage_bucket" "optimized" {
name = "optimized-bucket"
location = "US"
# Transition to cheaper storage classes
lifecycle_rule {
condition {
age = 30
}
action {
type = "SetStorageClass"
storage_class = "NEARLINE" # $0.01/GB/month vs $0.02/GB for Standard
}
}
lifecycle_rule {
condition {
age = 90
}
action {
type = "SetStorageClass"
storage_class = "COLDLINE" # $0.004/GB/month
}
}
lifecycle_rule {
condition {
age = 365
}
action {
type = "SetStorageClass"
storage_class = "ARCHIVE" # $0.0012/GB/month
}
}
# Delete old data
lifecycle_rule {
condition {
age = 730 # 2 years
}
action {
type = "Delete"
}
}
# Delete old versions
lifecycle_rule {
condition {
num_newer_versions = 3
}
action {
type = "Delete"
}
}
}Compression and Deduplication
from google.cloud import storage
import gzip
client = storage.Client()
bucket = client.bucket('my-bucket')
# Upload compressed objects
blob = bucket.blob('data.json.gz')
blob.content_encoding = 'gzip'
with gzip.open('data.json', 'rb') as f:
blob.upload_from_file(f, content_type='application/json')BigQuery Cost Optimization
Partitioned and Clustered Tables
resource "google_bigquery_table" "optimized" {
dataset_id = google_bigquery_dataset.analytics.dataset_id
table_id = "events_optimized"
# Partitioning reduces query costs
time_partitioning {
type = "DAY"
field = "event_timestamp"
expiration_ms = 7776000000 # Auto-delete after 90 days
}
# Clustering further reduces costs
clustering = ["user_id", "event_type", "country"]
# Range partitioning (alternative)
range_partitioning {
field = "user_id"
range {
start = 0
end = 1000000
interval = 10000
}
}
schema = jsonencode([
{ name = "event_timestamp", type = "TIMESTAMP", mode = "REQUIRED" },
{ name = "user_id", type = "INTEGER", mode = "REQUIRED" },
{ name = "event_type", type = "STRING", mode = "REQUIRED" },
{ name = "country", type = "STRING", mode = "NULLABLE" }
])
}Query Best Practices
-- BAD: Full table scan ($$$)
SELECT * FROM `project.dataset.table`;
-- GOOD: Query specific columns and partitions ($)
SELECT user_id, event_type
FROM `project.dataset.table`
WHERE event_timestamp >= '2025-01-01'
AND event_timestamp < '2025-01-02'
AND country = 'US';
-- Use LIMIT for exploration
SELECT *
FROM `project.dataset.table`
WHERE event_timestamp >= '2025-01-01'
LIMIT 1000;
-- Preview without cost
SELECT *
FROM `project.dataset.table`
TABLESAMPLE SYSTEM (1 PERCENT);Flat-Rate Pricing
For heavy BigQuery usage:
resource "google_bigquery_reservation" "reservation" {
name = "production-reservation"
location = "US"
# 100 slots = ~$2,000/month (vs on-demand at $5/TB)
# Break-even: ~400 TB queried per month
slot_capacity = 100
}
resource "google_bigquery_reservation_assignment" "assignment" {
assignee = "projects/${var.project_id}"
job_type = "QUERY"
reservation = google_bigquery_reservation.reservation.id
}Database Cost Optimization
Cloud SQL Instance Scheduling
# Stop instance during off-hours
gcloud sql instances patch INSTANCE_NAME \
--activation-policy=NEVER
# Start instance
gcloud sql instances patch INSTANCE_NAME \
--activation-policy=ALWAYS
# Automate with Cloud Scheduler
gcloud scheduler jobs create http stop-db \
--schedule="0 18 * * *" \
--uri="https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_NAME/stop" \
--http-method=POST \
--oauth-service-account-email=SERVICE_ACCOUNTUse Read Replicas Instead of Scaling Up
# Read replica in same region (cheaper than larger primary)
resource "google_sql_database_instance" "replica" {
name = "read-replica"
master_instance_name = google_sql_database_instance.main.name
region = "us-central1"
replica_configuration {
failover_target = false
}
settings {
tier = "db-custom-2-8192" # Smaller than primary
}
}Network Cost Optimization
Use Regional Resources
# Multi-region costs more for data processing
# Use regional unless global distribution required
resource "google_compute_backend_service" "regional" {
name = "regional-backend"
load_balancing_scheme = "INTERNAL_MANAGED" # Regional, cheaper
protocol = "HTTP"
}Cloud CDN for Egress
resource "google_compute_backend_service" "cdn_enabled" {
name = "cdn-backend"
# Enable CDN to reduce egress costs
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
default_ttl = 3600
}
}Premium vs Standard Network Tier
# Standard tier: 25-40% cheaper, acceptable for most workloads
resource "google_compute_address" "standard_tier" {
name = "standard-ip"
region = "us-central1"
network_tier = "STANDARD" # Cheaper than PREMIUM
}Monitoring and Alerts
Cost Budget Alerts
resource "google_billing_budget" "budget" {
billing_account = var.billing_account
display_name = "Monthly Budget"
budget_filter {
projects = ["projects/${var.project_id}"]
}
amount {
specified_amount {
currency_code = "USD"
units = "1000"
}
}
threshold_rules {
threshold_percent = 0.5
}
threshold_rules {
threshold_percent = 0.9
}
threshold_rules {
threshold_percent = 1.0
}
all_updates_rule {
pubsub_topic = google_pubsub_topic.budget_alerts.id
}
}Cost Anomaly Detection
# Enable cost anomaly detection
gcloud billing accounts describe BILLING_ACCOUNT \
--format="value(anomalyConfig.state)"
# List anomalies
gcloud billing accounts anomalies list \
--billing-account=BILLING_ACCOUNTCost Optimization Summary
| Service | Strategy | Savings |
|---|---|---|
| Compute | Committed use discounts | 57% |
| Compute | Spot VMs | 60-91% |
| Compute | Right-sizing | 20-40% |
| Cloud Run | Scale to zero | 100% when idle |
| Storage | Lifecycle management | 80-98% |
| BigQuery | Partitioning/clustering | 50-90% |
| BigQuery | Flat-rate (heavy use) | 40-60% |
| Cloud SQL | Instance scheduling | 50% (off hours) |
| Networking | CDN for egress | 30-50% |
| Networking | Standard tier | 25-40% |
Cost Monitoring Tools
# Export billing to BigQuery
gcloud alpha billing accounts update BILLING_ACCOUNT \
--export-enabled \
--export-dataset=PROJECT_ID:billing_export
# Query costs
SELECT
service.description AS service,
SUM(cost) AS total_cost
FROM `project.billing_export.gcp_billing_export_v1_*`
WHERE _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d', CURRENT_DATE())
GROUP BY service
ORDER BY total_cost DESC;Best Practices Checklist
- [ ] Use committed use discounts for predictable workloads
- [ ] Use Spot VMs for batch/fault-tolerant workloads
- [ ] Right-size all resources (use Recommender)
- [ ] Enable Cloud Run CPU throttling and scale-to-zero
- [ ] Implement Storage lifecycle policies
- [ ] Use partitioned and clustered tables in BigQuery
- [ ] Stop non-production databases during off-hours
- [ ] Enable Cloud CDN for static content
- [ ] Use Standard network tier where acceptable
- [ ] Set up budget alerts and anomaly detection
- [ ] Export billing data to BigQuery for analysis
- [ ] Review cost recommendations monthly
GCP Data Analytics Services Reference
Patterns for BigQuery, Pub/Sub, Dataflow, Dataproc, and Cloud Composer.
Table of Contents
1. BigQuery 2. Pub/Sub 3. Dataflow 4. Dataproc 5. Cloud Composer
---
BigQuery
Optimized Table Configuration
resource "google_bigquery_dataset" "analytics" {
dataset_id = "analytics"
location = "US"
description = "Analytics dataset"
default_table_expiration_ms = 7776000000 # 90 days
access {
role = "OWNER"
user_by_email = google_service_account.analytics.email
}
}
resource "google_bigquery_table" "events" {
dataset_id = google_bigquery_dataset.analytics.dataset_id
table_id = "events"
# Partitioning by day (reduces query cost)
time_partitioning {
type = "DAY"
field = "event_timestamp"
expiration_ms = 7776000000 # 90 days
}
# Clustering (further reduces query cost)
clustering = ["user_id", "event_type", "country"]
schema = jsonencode([
{
name = "event_id"
type = "STRING"
mode = "REQUIRED"
},
{
name = "event_timestamp"
type = "TIMESTAMP"
mode = "REQUIRED"
},
{
name = "user_id"
type = "STRING"
mode = "REQUIRED"
},
{
name = "event_type"
type = "STRING"
mode = "REQUIRED"
},
{
name = "country"
type = "STRING"
mode = "NULLABLE"
},
{
name = "properties"
type = "JSON"
mode = "NULLABLE"
}
])
}Query Optimization
from google.cloud import bigquery
client = bigquery.Client()
# Use parameterized queries
query = """
SELECT
event_type,
COUNT(*) as event_count,
COUNT(DISTINCT user_id) as unique_users
FROM `project.analytics.events`
WHERE event_timestamp >= @start_time
AND event_timestamp < @end_time
AND country = @country
GROUP BY event_type
ORDER BY event_count DESC
"""
job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("start_time", "TIMESTAMP", "2025-01-01"),
bigquery.ScalarQueryParameter("end_time", "TIMESTAMP", "2025-01-31"),
bigquery.ScalarQueryParameter("country", "STRING", "US"),
]
)
# Use query caching (24 hours by default)
query_job = client.query(query, job_config=job_config)
results = query_job.result()
# BigQuery ML
ml_query = """
CREATE OR REPLACE MODEL `project.analytics.user_churn_model`
OPTIONS(
model_type='LOGISTIC_REG',
input_label_cols=['churned']
) AS
SELECT
user_id,
activity_count,
last_active_days_ago,
churned
FROM `project.analytics.user_features`
"""---
Pub/Sub
Topic and Subscription Configuration
# Pub/Sub topic with schema
resource "google_pubsub_schema" "events" {
name = "events-schema"
type = "AVRO"
definition = jsonencode({
type = "record"
name = "Event"
fields = [
{ name = "event_id", type = "string" },
{ name = "timestamp", type = "long" },
{ name = "user_id", type = "string" },
{ name = "event_type", type = "string" }
]
})
}
resource "google_pubsub_topic" "events" {
name = "events-topic"
schema_settings {
schema = google_pubsub_schema.events.id
encoding = "JSON"
}
message_retention_duration = "604800s" # 7 days
}
# Pull subscription
resource "google_pubsub_subscription" "events_pull" {
name = "events-pull"
topic = google_pubsub_topic.events.name
ack_deadline_seconds = 20
message_retention_duration = "604800s"
retry_policy {
minimum_backoff = "10s"
maximum_backoff = "600s"
}
dead_letter_policy {
dead_letter_topic = google_pubsub_topic.dead_letter.id
max_delivery_attempts = 5
}
expiration_policy {
ttl = "" # Never expire
}
}
# Push subscription
resource "google_pubsub_subscription" "events_push" {
name = "events-push"
topic = google_pubsub_topic.events.name
push_config {
push_endpoint = "https://example.com/webhook"
oidc_token {
service_account_email = google_service_account.pubsub.email
}
attributes = {
x-goog-version = "v1"
}
}
}Python Publisher/Subscriber
from google.cloud import pubsub_v1
import json
# Publisher
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path('project-id', 'events-topic')
def publish_message(event_data):
message_json = json.dumps(event_data).encode('utf-8')
future = publisher.publish(
topic_path,
message_json,
event_type=event_data['event_type'] # Custom attribute
)
return future.result()
# Subscriber (pull)
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path('project-id', 'events-pull')
def callback(message):
print(f'Received: {message.data}')
message.ack() # Acknowledge receipt
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)---
Dataflow
Terraform Configuration
resource "google_dataflow_job" "stream_to_bq" {
name = "stream-events-to-bigquery"
template_gcs_path = "gs://dataflow-templates-us-central1/latest/PubSub_to_BigQuery"
temp_gcs_location = google_storage_bucket.dataflow_temp.url
parameters = {
inputTopic = google_pubsub_topic.events.id
outputTableSpec = "${var.project_id}:${google_bigquery_dataset.analytics.dataset_id}.${google_bigquery_table.events.table_id}"
}
on_delete = "cancel"
}Apache Beam Pipeline (Python)
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
def run_pipeline():
options = PipelineOptions(
project='project-id',
runner='DataflowRunner',
region='us-central1',
temp_location='gs://bucket/temp',
staging_location='gs://bucket/staging',
streaming=True
)
with beam.Pipeline(options=options) as pipeline:
(pipeline
| 'Read from Pub/Sub' >> beam.io.ReadFromPubSub(
topic='projects/project-id/topics/events-topic')
| 'Parse JSON' >> beam.Map(lambda msg: json.loads(msg))
| 'Transform' >> beam.Map(transform_event)
| 'Write to BigQuery' >> beam.io.WriteToBigQuery(
'project-id:analytics.events',
schema='event_id:STRING,timestamp:TIMESTAMP,user_id:STRING',
write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND,
create_disposition=beam.io.BigQueryDisposition.CREATE_IF_NEEDED)
)
def transform_event(event):
return {
'event_id': event['id'],
'timestamp': event['timestamp'],
'user_id': event['user']
}---
Dataproc
Cluster Configuration
resource "google_dataproc_cluster" "spark" {
name = "spark-cluster"
region = "us-central1"
cluster_config {
staging_bucket = google_storage_bucket.dataproc.name
master_config {
num_instances = 1
machine_type = "n2-standard-4"
disk_config {
boot_disk_type = "pd-ssd"
boot_disk_size_gb = 100
}
}
worker_config {
num_instances = 3
machine_type = "n2-standard-4"
disk_config {
boot_disk_size_gb = 100
}
}
preemptible_worker_config {
num_instances = 5
}
software_config {
image_version = "2.1-debian11"
properties = {
"spark:spark.executor.memory" = "4g"
}
}
gce_cluster_config {
zone = "us-central1-a"
service_account_scopes = ["cloud-platform"]
}
autoscaling_config {
policy_uri = google_dataproc_autoscaling_policy.policy.name
}
}
}
resource "google_dataproc_autoscaling_policy" "policy" {
policy_id = "dataproc-policy"
location = "us-central1"
worker_config {
max_instances = 10
min_instances = 2
}
basic_algorithm {
yarn_config {
graceful_decommission_timeout = "30s"
scale_up_factor = 0.05
scale_down_factor = 1.0
}
}
}---
Cloud Composer
Airflow Environment
resource "google_composer_environment" "airflow" {
name = "production-airflow"
region = "us-central1"
config {
software_config {
airflow_config_overrides = {
core-dags_are_paused_at_creation = "True"
webserver-rbac = "True"
}
pypi_packages = {
pandas = ""
numpy = ""
requests = ">=2.28.0"
}
env_variables = {
ENVIRONMENT = "production"
}
}
node_config {
zone = "us-central1-a"
machine_type = "n1-standard-4"
disk_size_gb = 100
service_account = google_service_account.composer.email
}
workloads_config {
scheduler {
cpu = 2
memory_gb = 7.5
storage_gb = 5
count = 2
}
web_server {
cpu = 2
memory_gb = 7.5
storage_gb = 5
}
worker {
cpu = 2
memory_gb = 7.5
storage_gb = 5
min_count = 2
max_count = 6
}
}
}
}Sample DAG
from datetime import datetime, timedelta
from airflow import DAG
from airflow.providers.google.cloud.operators.bigquery import BigQueryInsertJobOperator
from airflow.providers.google.cloud.transfers.gcs_to_bigquery import GCSToBigQueryOperator
default_args = {
'owner': 'data-team',
'depends_on_past': False,
'start_date': datetime(2025, 1, 1),
'email': ['alerts@example.com'],
'email_on_failure': True,
'retries': 3,
'retry_delay': timedelta(minutes=5),
}
with DAG(
'daily_analytics_pipeline',
default_args=default_args,
schedule_interval='0 2 * * *', # Daily at 2am
catchup=False,
) as dag:
load_data = GCSToBigQueryOperator(
task_id='load_data_from_gcs',
bucket='data-bucket',
source_objects=['data/*.csv'],
destination_project_dataset_table='project.analytics.raw_events',
write_disposition='WRITE_TRUNCATE',
)
transform = BigQueryInsertJobOperator(
task_id='transform_data',
configuration={
'query': {
'query': """
INSERT INTO `project.analytics.events`
SELECT * FROM `project.analytics.raw_events`
WHERE timestamp >= CURRENT_DATE()
""",
'useLegacySql': False,
}
},
)
load_data >> transformBest Practices
BigQuery
- Use partitioned and clustered tables
- Query only needed columns (avoid SELECT *)
- Use LIMIT for exploratory queries
- Cache results (24 hours)
- Use BI Engine for dashboards
Pub/Sub
- Use dead letter topics
- Set appropriate ack deadlines
- Implement exponential backoff
- Use message ordering when needed
- Monitor subscription backlog
Dataflow
- Use windowing for streaming
- Implement exactly-once processing
- Monitor pipeline metrics
- Use Flex templates for custom pipelines
- Enable autoscaling
Dataproc
- Use preemptible workers (60-91% cheaper)
- Enable autoscaling
- Store data in Cloud Storage (ephemeral clusters)
- Use initialization actions
- Monitor YARN metrics
Composer
- Use Workload Identity
- Set appropriate resource limits
- Monitor DAG performance
- Use XCom for small data only
- Implement alerting
GCP ML/AI Services Reference
Patterns for Vertex AI, AutoML, and pre-trained AI services.
Table of Contents
1. Vertex AI 2. AutoML 3. Pre-trained APIs 4. TPUs
---
Vertex AI
Custom Training Job
from google.cloud import aiplatform
aiplatform.init(
project='project-id',
location='us-central1',
staging_bucket='gs://my-bucket'
)
# Create custom training job
job = aiplatform.CustomTrainingJob(
display_name='custom-training-job',
script_path='train.py',
container_uri='gcr.io/cloud-aiplatform/training/pytorch-gpu.1-13:latest',
requirements=['pandas==2.0.0', 'scikit-learn==1.3.0'],
model_serving_container_image_uri='gcr.io/cloud-aiplatform/prediction/pytorch-gpu.1-13:latest',
)
# Run training
model = job.run(
dataset=dataset,
replica_count=1,
machine_type='n1-standard-8',
accelerator_type='NVIDIA_TESLA_V100',
accelerator_count=1,
model_display_name='my-model',
training_fraction_split=0.8,
validation_fraction_split=0.1,
test_fraction_split=0.1,
)
# Deploy model
endpoint = model.deploy(
deployed_model_display_name='deployed-model',
machine_type='n1-standard-4',
min_replica_count=1,
max_replica_count=10,
accelerator_type='NVIDIA_TESLA_T4',
accelerator_count=1,
)
# Make prediction
prediction = endpoint.predict(instances=[[5.1, 3.5, 1.4, 0.2]])Vertex AI Pipelines
from kfp.v2 import dsl
from kfp.v2.dsl import component, pipeline
@component(base_image='python:3.9')
def preprocess_data(input_path: str, output_path: str):
import pandas as pd
df = pd.read_csv(input_path)
# Preprocessing logic
df.to_csv(output_path, index=False)
@component(base_image='gcr.io/cloud-aiplatform/training/pytorch-gpu.1-13:latest')
def train_model(data_path: str, model_path: str):
# Training logic
pass
@pipeline(name='ml-pipeline')
def ml_pipeline(input_path: str):
preprocess_task = preprocess_data(input_path=input_path, output_path='/tmp/processed.csv')
train_task = train_model(data_path=preprocess_task.output, model_path='/tmp/model')
# Compile and run
from kfp.v2 import compiler
compiler.Compiler().compile(pipeline_func=ml_pipeline, package_path='pipeline.json')
from google.cloud import aiplatform
aiplatform.PipelineJob(
display_name='ml-pipeline-run',
template_path='pipeline.json',
parameter_values={'input_path': 'gs://bucket/data.csv'}
).run()---
AutoML
AutoML Tables (Structured Data)
from google.cloud import aiplatform
# Create dataset
dataset = aiplatform.TabularDataset.create(
display_name='sales-predictions',
gcs_source='gs://bucket/sales_data.csv',
)
# Train AutoML model
job = aiplatform.AutoMLTabularTrainingJob(
display_name='automl-sales-job',
optimization_prediction_type='regression',
optimization_objective='minimize-rmse',
)
model = job.run(
dataset=dataset,
target_column='sales_amount',
training_fraction_split=0.8,
validation_fraction_split=0.1,
test_fraction_split=0.1,
model_display_name='sales-prediction-model',
budget_milli_node_hours=8000, # 8 hours
)AutoML Vision
# Create image dataset
dataset = aiplatform.ImageDataset.create(
display_name='product-classification',
gcs_source='gs://bucket/images.csv', # CSV with image paths and labels
)
# Train image classification model
job = aiplatform.AutoMLImageTrainingJob(
display_name='automl-image-job',
prediction_type='classification',
multi_label=False,
)
model = job.run(
dataset=dataset,
model_display_name='product-classifier',
training_fraction_split=0.8,
validation_fraction_split=0.1,
test_fraction_split=0.1,
budget_milli_node_hours=20000, # 20 hours
)
# Deploy and predict
endpoint = model.deploy(machine_type='n1-standard-4')
prediction = endpoint.predict(instances=[{'content': 'gs://bucket/test_image.jpg'}])---
Pre-trained APIs
Vision API
from google.cloud import vision
client = vision.ImageAnnotatorClient()
# Image from GCS
image = vision.Image()
image.source.image_uri = 'gs://bucket/image.jpg'
# Or from local file
with open('image.jpg', 'rb') as f:
content = f.read()
image = vision.Image(content=content)
# Label detection
response = client.label_detection(image=image)
for label in response.label_annotations:
print(f'{label.description}: {label.score}')
# Text detection (OCR)
response = client.text_detection(image=image)
print(response.full_text_annotation.text)
# Face detection
response = client.face_detection(image=image)
for face in response.face_annotations:
print(f'Joy: {face.joy_likelihood}')
print(f'Sorrow: {face.sorrow_likelihood}')
# Object localization
response = client.object_localization(image=image)
for obj in response.localized_object_annotations:
print(f'{obj.name}: {obj.score}')Natural Language API
from google.cloud import language_v1
client = language_v1.LanguageServiceClient()
text = "Google Cloud Platform provides powerful AI services."
document = language_v1.Document(content=text, type_=language_v1.Document.Type.PLAIN_TEXT)
# Sentiment analysis
sentiment = client.analyze_sentiment(document=document).document_sentiment
print(f'Sentiment score: {sentiment.score}')
print(f'Sentiment magnitude: {sentiment.magnitude}')
# Entity extraction
response = client.analyze_entities(document=document)
for entity in response.entities:
print(f'{entity.name}: {entity.type_}')
# Syntax analysis
response = client.analyze_syntax(document=document)
for token in response.tokens:
print(f'{token.text.content}: {token.part_of_speech.tag}')Translation API
from google.cloud import translate_v2
client = translate_v2.Client()
# Translate text
result = client.translate('Hello, world!', target_language='es')
print(result['translatedText']) # "¡Hola Mundo!"
# Detect language
result = client.detect_language('Bonjour')
print(result['language']) # 'fr'
# Get supported languages
languages = client.get_languages()
for language in languages:
print(f'{language["name"]}: {language["language"]}')Speech-to-Text
from google.cloud import speech
client = speech.SpeechClient()
# Audio from GCS
audio = speech.RecognitionAudio(uri='gs://bucket/audio.wav')
# Or from local file
with open('audio.wav', 'rb') as f:
content = f.read()
audio = speech.RecognitionAudio(content=content)
config = speech.RecognitionConfig(
encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
sample_rate_hertz=16000,
language_code='en-US',
enable_automatic_punctuation=True,
)
# Synchronous recognition (< 60 seconds)
response = client.recognize(config=config, audio=audio)
for result in response.results:
print(result.alternatives[0].transcript)
# Long audio recognition
operation = client.long_running_recognize(config=config, audio=audio)
response = operation.result(timeout=300)---
TPUs
Cloud TPU Configuration
resource "google_tpu_node" "tpu" {
name = "ml-tpu"
zone = "us-central1-a"
accelerator_type = "v3-8" # 8 cores
tensorflow_version = "2.12.0"
network = google_compute_network.main.id
cidr_block = "10.0.0.0/29"
scheduling_config {
preemptible = false
}
labels = {
environment = "production"
}
}TPU Training Example
import tensorflow as tf
# TPU initialization
resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='ml-tpu')
tf.config.experimental_connect_to_cluster(resolver)
tf.tpu.experimental.initialize_tpu_system(resolver)
strategy = tf.distribute.TPUStrategy(resolver)
# Model training with TPU
with strategy.scope():
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Train on TPU
model.fit(train_dataset, epochs=10, validation_data=val_dataset)Service Selection Guide
| Task | Expertise Level | Service | Cost |
|---|---|---|---|
| Image classification | Low | AutoML Vision | $$ |
| Image classification | High | Custom Vertex AI | $$$ |
| Object detection | Low | Vision API | $ |
| Text classification | Low | AutoML Natural Language | $$ |
| Text classification | High | Custom Vertex AI | $$$ |
| Sentiment analysis | Any | Natural Language API | $ |
| Translation | Any | Translation API | $ |
| Speech recognition | Any | Speech-to-Text API | $ |
| Custom ML model | High | Vertex AI Training | $$$-$$$$ |
| Large model training | High | Vertex AI with TPUs | $$$$-$$$$$ |
Best Practices
- Start with pre-trained APIs for standard tasks
- Use AutoML for custom models with limited ML expertise
- Use Vertex AI custom training for advanced use cases
- Enable Vertex AI Model Monitoring for production models
- Use Feature Store for reusable features
- Implement ML pipelines for reproducibility
- Use TPUs for large-scale transformer model training
- Monitor prediction costs and latency
GCP Networking Reference
VPC, Load Balancing, CDN, and Cloud Armor patterns.
Table of Contents
VPC Configuration
resource "google_compute_network" "main" {
name = "main-vpc"
auto_create_subnetworks = false
routing_mode = "GLOBAL"
}
resource "google_compute_subnetwork" "private" {
name = "private-subnet"
ip_cidr_range = "10.0.1.0/24"
region = "us-central1"
network = google_compute_network.main.id
private_ip_google_access = true
secondary_ip_range {
range_name = "gke-pods"
ip_cidr_range = "10.1.0.0/16"
}
secondary_ip_range {
range_name = "gke-services"
ip_cidr_range = "10.2.0.0/20"
}
log_config {
aggregation_interval = "INTERVAL_5_SEC"
flow_sampling = 0.5
}
}
# Cloud NAT for private instances
resource "google_compute_router" "router" {
name = "nat-router"
region = "us-central1"
network = google_compute_network.main.id
}
resource "google_compute_router_nat" "nat" {
name = "nat-gateway"
router = google_compute_router.router.name
region = google_compute_router.router.region
nat_ip_allocate_option = "AUTO_ONLY"
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
log_config {
enable = true
filter = "ERRORS_ONLY"
}
}Global Load Balancing
# Global HTTP(S) Load Balancer
resource "google_compute_global_address" "lb_ip" {
name = "global-lb-ip"
}
resource "google_compute_global_forwarding_rule" "https" {
name = "https-forwarding-rule"
target = google_compute_target_https_proxy.default.id
port_range = "443"
ip_address = google_compute_global_address.lb_ip.address
}
resource "google_compute_target_https_proxy" "default" {
name = "https-proxy"
url_map = google_compute_url_map.default.id
ssl_certificates = [google_compute_managed_ssl_certificate.default.id]
}
resource "google_compute_managed_ssl_certificate" "default" {
name = "ssl-cert"
managed {
domains = ["example.com", "www.example.com"]
}
}
resource "google_compute_url_map" "default" {
name = "url-map"
default_service = google_compute_backend_service.default.id
host_rule {
hosts = ["example.com"]
path_matcher = "allpaths"
}
path_matcher {
name = "allpaths"
default_service = google_compute_backend_service.default.id
path_rule {
paths = ["/api/*"]
service = google_compute_backend_service.api.id
}
}
}
resource "google_compute_backend_service" "default" {
name = "backend-service"
protocol = "HTTP"
timeout_sec = 30
health_checks = [google_compute_health_check.default.id]
load_balancing_scheme = "EXTERNAL_MANAGED"
backend {
group = google_compute_region_network_endpoint_group.cloudrun.id
balancing_mode = "UTILIZATION"
capacity_scaler = 1.0
}
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
default_ttl = 3600
client_ttl = 7200
max_ttl = 86400
negative_caching = true
serve_while_stale = 86400
cache_key_policy {
include_protocol = true
include_host = true
}
}
iap {
oauth2_client_id = google_iap_client.default.client_id
oauth2_client_secret = google_iap_client.default.secret
}
}Cloud Armor (WAF)
resource "google_compute_security_policy" "policy" {
name = "security-policy"
# Default rule
rule {
action = "allow"
priority = "2147483647"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
}
# Block specific countries
rule {
action = "deny(403)"
priority = "1000"
match {
expr {
expression = "origin.region_code == 'CN' || origin.region_code == 'RU'"
}
}
}
# Rate limiting
rule {
action = "rate_based_ban"
priority = "2000"
match {
versioned_expr = "SRC_IPS_V1"
config {
src_ip_ranges = ["*"]
}
}
rate_limit_options {
conform_action = "allow"
exceed_action = "deny(429)"
rate_limit_threshold {
count = 100
interval_sec = 60
}
ban_duration_sec = 600
}
}
# SQL injection protection
rule {
action = "deny(403)"
priority = "3000"
match {
expr {
expression = "evaluatePreconfiguredExpr('sqli-stable')"
}
}
}
# XSS protection
rule {
action = "deny(403)"
priority = "3001"
match {
expr {
expression = "evaluatePreconfiguredExpr('xss-stable')"
}
}
}
adaptive_protection_config {
layer_7_ddos_defense_config {
enable = true
}
}
}
# Attach to backend service
resource "google_compute_backend_service_security_policy_attachment" "policy" {
backend_service = google_compute_backend_service.default.id
security_policy = google_compute_security_policy.policy.id
}VPC Peering
resource "google_compute_network_peering" "peering1" {
name = "peering-to-network2"
network = google_compute_network.network1.id
peer_network = google_compute_network.network2.id
export_custom_routes = true
import_custom_routes = true
}
resource "google_compute_network_peering" "peering2" {
name = "peering-to-network1"
network = google_compute_network.network2.id
peer_network = google_compute_network.network1.id
export_custom_routes = true
import_custom_routes = true
}Private Service Connection
resource "google_compute_global_address" "private_ip_alloc" {
name = "private-ip-alloc"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.main.id
}
resource "google_service_networking_connection" "private_vpc_connection" {
network = google_compute_network.main.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name]
}Related skills
FAQ
When should I use Cloud Run instead of GKE?
Use Cloud Run for stateless HTTP services that can auto-scale to zero; use GKE when you need Kubernetes orchestration or full control.
Which GCP database is for petabyte-scale analytics?
BigQuery, a serverless data warehouse for petabyte-scale SQL analytics.