Context
GCP budgets alert but take no action, so the non-production stop of 0172 had no GCP form. The GCP runtime was undecided, which left Cloud SQL without the backups and point-in-time recovery 0186 requires. The deploy service account heldroles/owner, and a long project name could make a service account id GCP refuses only at apply time.
Decision
- Spend stop. When
providers.gcp.budgets.stopNonProdAtis set, a project production does not run in gets a Cloud Function on its budget topic that detaches the project’s billing once the cost reaches that percentage. Its own service account holds onlyroles/billing.projectManageron the project; the function is internal-ingress only. Production is never detached. - Cloud SQL in the runtime stack.
gcpRuntimecreates the environment’s Postgres server fromshared.database(tier, version,highAvailability), always with daily backups stored in the server’s own region, keepingbackups.retentionDaysbackups, and point-in-time recovery forbackups.pitrDayswhenbackups.pitris on. The server is deletion-protected, joins the runway’s VPC on a private IP (or is reachable only through the connector over TLS) and uses the deployment’s data key when one is passed. - Deploy roles. The infra service account holds the predefined roles of the resources the programs manage
(
DEPLOY_ROLES), neverroles/owner.projectIamAdminremains, so the trust stays the GitHub environment’s. - Service account guard. Every service account id a deployment makes is checked against GCP’s 30 characters while
the runway is read, so
stackra validatefails before Pulumi runs.
Consequences
- A sandbox project stops spending at its threshold without an operator; re-linking billing is an owner step.
- A new resource kind in infra-gcp adds its role to
DEPLOY_ROLESin the same change. - The budget on the billing account needs
roles/billing.costsManagergranted by the owner.
Enforcement
packages/infrastructure/infra-gcp/src/node/functions/__tests__/{spend-stop,gcp-runtime,ci-access,gcp-baseline}.function.test.ts;
packages/infrastructure/infra-gcp/src/core/functions/__tests__/{service-account-id,gcp-runtime-config}.function.test.ts.
Planned — the spend stop exercised on a sandbox project by the owner.
Supersedes and sources
Supersedes: none. Sources: STA-730; ADR 0354 OQ1; JUR-215;notes/handover/build-wave10-2026-10-25.md (infra-gcp).