GCP Patterns
Cloud Run Service (serverless containers)
# cloudbuild.yaml
steps:
- name: gcr.io/cloud-builders/docker
args: [build, -t, '$_IMAGE', .]
- name: gcr.io/cloud-builders/docker
args: [push, '$_IMAGE']
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: gcloud
args:
- run
- deploy
- myapp
- --image=$_IMAGE
- --region=us-central1
- --platform=managed
- --allow-unauthenticated
- --min-instances=1
- --max-instances=10
- --memory=512Mi
- --cpu=1
- --concurrency=80
- --set-env-vars=ENV=prod
- --set-secrets=DB_PASSWORD=db-password:latest
Terraform GKE Cluster
resource "google_container_cluster" "primary" {
name = "myapp-prod"
location = "us-central1"
remove_default_node_pool = true
initial_node_count = 1
workload_identity_config {
workload_pool = "${var.project_id}.svc.id.goog"
}
network = google_compute_network.vpc.name
subnetwork = google_compute_subnetwork.subnet.name
}
resource "google_container_node_pool" "nodes" {
name = "default-pool"
cluster = google_container_cluster.primary.name
location = "us-central1"
autoscaling {
min_node_count = 1
max_node_count = 5
}
node_config {
machine_type = "e2-standard-4"
disk_size_gb = 50
oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
workload_metadata_config {
mode = "GKE_METADATA"
}
}
}
Workload Identity (GKE → GCP APIs)
# Create GCP service account
gcloud iam service-accounts create myapp-sa \
--display-name="MyApp Service Account"
# Grant permissions
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:myapp-sa@PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
# Bind to Kubernetes service account
gcloud iam service-accounts add-iam-policy-binding \
myapp-sa@PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:PROJECT_ID.svc.id.goog[myapp/myapp-ksa]"
# Kubernetes ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: myapp-ksa
namespace: myapp
annotations:
iam.gke.io/gcp-service-account: myapp-sa@PROJECT_ID.iam.gserviceaccount.com
Cloud SQL (Postgres) with Auth Proxy
# In GKE deployment — sidecar pattern
containers:
- name: cloud-sql-proxy
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2
args:
- --structured-logs
- --port=5432
- PROJECT_ID:us-central1:mydb
securityContext:
runAsNonRoot: true
resources:
requests: { cpu: 100m, memory: 64Mi }
Pub/Sub Push Subscription
from google.cloud import pubsub_v1
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path("my-project", "my-topic")
# Publish with ordering key
future = publisher.publish(
topic_path,
data=json.dumps({"event": "order.created", "id": order_id}).encode(),
ordering_key=user_id, # guarantees order per user
event_type="order.created",
)
future.result(timeout=30)
Key Rules
- Use Workload Identity instead of service account key files — no key rotation needed
- Enable VPC-native clusters (alias IP) for direct pod-to-pod routing
- Cloud Run: set
--min-instances=1 for latency-sensitive services (avoids cold starts)
- Use Artifact Registry, not Container Registry (GCR is deprecated)
- Enable Binary Authorization to enforce only signed images in GKE