Environments
Every app moves through the same ladder: preview environments per pull request, then dev → qa → prod. dev, qa, and preview all live on the shared nonprod cluster; prod is a separate cluster reached only by a manually-approved promotion.
At a glance
| Env | Trigger | Cluster / project | Namespace | Hostname | Gateway / TLS |
|---|---|---|---|---|---|
| dev | push to main | u2i-nonprod / c-u2i-nonprod | {app}-dev | dev.{app}.u2i.dev | eg (Envoy) + Let's Encrypt |
| qa | version tag v* | u2i-nonprod / c-u2i-nonprod | {app}-qa | qa.{app}.u2i.dev | eg (Envoy) + Let's Encrypt |
| preview | pull request | u2i-nonprod / c-u2i-nonprod | {app}-pr-{N} | pr-{N}.{app}.u2i.dev | eg (Envoy) + Let's Encrypt |
| prod | manual promotion (approval) | u2i-prod / c-u2i-prod | {app}-prod | {app}.u2i.dev | managed-lb + Certificate Manager |
dev
Continuous integration target — always reflects main.
- Fires on every push to main via the {app}-dev-trigger Cloud Build trigger.
- Builds the image (tag dev-{SHA}), packages the Helm chart, pushes it to the config-sync OCI registry, and updates the RepoSync — Config Sync then reconciles it into the {app}-dev namespace.
- Rolls out automatically; no approval gate.
- Served in-cluster via the Envoy Gateway (gatewayMode: eg) with a cert-manager Let's Encrypt certificate; external-dns publishes the A record automatically.
qa
Release candidate — what you cut a version tag for.
- Fires when a version tag (v*) is pushed, via the {app}-qa-deployment trigger.
- Creates a release in the {app}-qa-prod-pipeline; the qa target deploys automatically.
- Runs on the same nonprod cluster as dev, in the {app}-qa namespace, with prod-like resource limits for realistic testing.
- Same eg gateway + Let's Encrypt TLS as dev.
preview (per-PR)
Ephemeral environment for reviewing a pull request.
- Fires when a PR is opened, via the {app}-preview-deployment trigger.
- Spins up a dynamic {app}-pr-{N} namespace and applies the manifests directly (bypassing Config Sync) so the review URL comes up fast.
- Runs on spot nodes with smaller resource and cache limits to keep previews cheap.
- Reachable at pr-{N}.{app}.u2i.dev; the namespace is torn down automatically when the PR is closed.
prod
Production — promoted deliberately, never on a push.
- Reached by promoting a qa release through the {app}-qa-prod-pipeline; the prod target is gated behind a manual approval from the app's approver_group.
- Runs on the separate u2i-prod cluster / c-u2i-prod project, in the {app}-prod namespace.
- The prod cluster has no in-cluster Envoy gateway, so it uses gatewayMode: managed-lb — a Google Cloud load balancer with a global static IP and a Certificate Manager cert-map.
- DNS A-records for the apex hostname are declared explicitly (no external-dns auto-publish in prod).