GCP Overview¶
One project, one region, one cluster, many namespaces. Tomoda's GCP footprint is intentionally small so that every operator can hold the whole topology in their head.
Single-project setup
There is no separate tomoda-dev and tomoda-prod project. Everything runs in development-485000 in us-central1 and is isolated by Kubernetes namespace. The project name is a historical artifact — treat it as the production project.
Topology at a glance¶
What lives where¶
| Concern | Resource | Page |
|---|---|---|
| Compute | GKE cluster + 2 node pools | GKE |
| Network | Custom VPC + secondary ranges | VPC |
| CI | Cloud Build triggers + SA | Cloud Build |
| Images | 2 Artifact Registry repos | Artifact Registry |
| GitOps | Argo CD via Helm | Argo CD |
| Auth | IAP brand + OAuth client | OAuth & Dex |
| Geocoder index | …-photon-index-usc1 GCS bucket |
Photon Indexer |
| DB backups | tomoda-db-backups-… GCS bucket |
Backup |
| Identity | Workload Identity bindings | IAM |
Environment isolation¶
Because there is only one project, "dev" and "prod" are not GCP-level boundaries. They show up as:
- Kubernetes namespaces —
tomoda-dev,tomoda-prod,data(single namespace, holds bothpostgres-devandpostgres-prodclusters). - Artifact Registry repos —
tomoda-dev-repofor main-branch builds,tomoda-prod-repofor semver-tag builds. Cloud Build pushes to whichever repo the trigger configures. - OAuth client IDs — three sets of Google OAuth client IDs (web/iOS/Android) baked into Cloud Build substitutions: one set for dev, one for prod, plus an internal one for middleware tools like Argo CD itself.
If you need stronger isolation later (separate billing, separate IAM blast radius, separate APIs), the migration path is to split the GKE cluster and node pools into a new project; the Terraform code is already parameterised on var.project_id.
Terraform workflow¶
cd infrastructure/gcp
terraform init # connects to gs://development-485000-tfstate
terraform plan -var-file=terraform.tfvars
terraform apply -var-file=terraform.tfvars
The infrastructure/gcp/README.md mentions workspaces (internal / development / production), but the live environment runs the default workspace and the terraform.tfvars checked in points at development-485000. Do not create new workspaces without first migrating state — there is none for them.
Provider quirks¶
- The Google provider sets
user_project_override = trueandbilling_project = var.project_id. This stops API calls from being billed to Google's internal gcloud client project (764086051850) when operators are using user ADC, which would otherwise fail withSERVICE_DISABLED. - The
kubernetesandhelmproviders authenticate against the GKE cluster using the operator's currentgcloudaccess token — there is no kubeconfig file involved.terraform applytherefore requirescontainer.clusters.getCredentialsongke-tomoda.