Trust is earned, not given

A different perspective

2021-11-09 · Projects

DevOps on Google Cloud, part 3: Data — Cloud SQL, Firestore, Cloud Storage, Memorystore

Part 3from the DevOps on Google Cloud series · 6 parts in all

Part 3: the data layer. GCP's distinguishing data story is Firestore's real-time synchronization and BigQuery's analytics gravity; the relational workhorse (Cloud SQL) and the object store (Cloud Storage) are comfortingly familiar.

Cloud SQL: managed Postgres with private IPs

MapleCart's orders live in Cloud SQL for PostgreSQL, reachable only over private IP through Private Services Access:

# One-time: reserve the IP range for managed services inside the VPC
gcloud compute addresses create google-managed-services-maplecart \
  --global --purpose VPC_PEERING --prefix-length 16 \
  --network maplecart-vnet
gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com \
  --ranges=google-managed-services-maplecart --network=maplecart-vnet

# The instance: private IP only, automated backups, PITR
gcloud sql instances create maplecart-db \
  --database-version=POSTGRES_15 --tier=db-custom-2-7680 \   # 2 vCPU, 7.5 GB
  --region=us-central1 --availability-type=REGIONAL \        # sync replica in another zone
  --network=projects/maplecart/global/networks/maplecart-vnet --no-assign-ip \
  --backup-start-time=03:00 --enable-point-in-time-recovery \
  --disk-encryption-key=<kms-key>                            # CMEK: our key, not Google's

--no-assign-ip is the whole security posture: no public IP exists. The app connects over the VPC and authenticates via IAM database authentication (the service account as database user) or IAM-auth-token — again, no passwords.

Firestore: the real-time document store

FleetView's telemetry and live dashboards use Firestore in Native mode. The differentiator is real-time listeners: a dashboard subscribes to a query and receives pushes as data changes — no polling layer to build:

# Python: write telemetry (server-side)...
from google.cloud import firestore
db = firestore.Client()                        # project default; IAM does the rest
db.collection("telemetry").document().set({
    "tenant": tenant, "device": device, "ts": firestore.SERVER_TIMESTAMP,
    "speed_kph": speed, "ttl_expires": ts + timedelta(days=90),
})

# ...and the FleetView dashboard (JS) subscribes - updates arrive pushed, live:
db.collection("telemetry")
  .where("tenant", "==", tenant).orderBy("ts").limit(50)
  .onSnapshot(snap => render(snap.docs.map(d => d.data())))

Same TTL pattern as the other clouds (documents auto-expire), same partition-key thinking (tenant field leads every query), plus the real-time push that would cost a WebSocket service elsewhere.

Cloud Storage and Memorystore

Cloud Storage hosts NewsGrid's static site and MapleCart's media — with the same lifecycle aging to Coldline/Archive, signed URLs for private objects, and CMEK encryption options. Memorystore (Redis) backs MapleCart's catalog cache with the same cache-aside pattern. The data layer's universality across the three clouds is now fully established; what remains is GCP's genuinely class-leading network, which is next.