· Documentation · 3 min read
The template in depth — architecture, modules, and CI
A tour of how astro-gcp-cloudrun-starter is put together — the Terraform layers and modules, the keyless CI/CD pipeline, and the hardened container that runs on Cloud Run.
While it’s quick to deploy, this template has a fair amount going on internally. This page documents the moving parts so you can adapt them with confidence.
Repository layout
src/ # Astro v6 site (pages, components, content, config.yaml)
Dockerfile # multi-stage: Node 22 build → nginx:8080 serve (~25MB, non-root)
.github/workflows/ # deploy-dev / staging / prod (keyless, app-deploy-only)
terraform/
bootstrap/ # one-time seed: projects, state bucket, automation SA
environments/ # shared, dev, staging, production layers
modules/ # iam, cloud_run, artifact_registry, monitoring, logging,
# secret_manager, cost_governance, networking, ...
docs/ # SETUP_PLAYBOOK, FRESH_USER_WALKTHROUGH, IAC_RULES, GAP_REGISTERThe Terraform layers
The infrastructure is deliberately split so that the dangerous, one-time setup is isolated from day-to-day changes:
bootstrapruns once with local state, creates the four projects + the GCS state bucket + thesa-terraform-adminautomation account, then migrates its own state into GCS. It also enables the seed APIs that every later step depends on (includingiamcredentialsandcloudbilling).sharedholds the cross-cutting resources: the Workload Identity pool/provider (scoped to this repo), the GitHub deploy service account, and the Artifact Registry.environments/*each adopt their bootstrap-created project (create_project = false) and compose the modules into a running environment.
Notable modules
iam— runtime and deploy service accounts, the WIF pool/provider, and the cross-project grants that let the deploy SA ship Cloud Run revisions and pull images from the shared registry.cloud_run— the v2 service with enforced resource limits, scale-to-zero, CPU throttling, liveness/startup probes, and optional Secret-Manager-backed env vars.cost_governance— a per-project billing budget with 50/80/100% alerts.monitoring/logging— uptime checks, an availability SLO, alert policies, and audit log export.- Feature-gated modules (
networking,cloud_sql,dns,load_balancer,cloud_armor,vertex_ai) are off by default for cost and are enabled per-environment via tfvars.
The CI/CD pipeline
The deploy workflows authenticate to GCP with Workload Identity Federation — no stored secrets. They build the container, push it to Artifact Registry tagged with the commit SHA, deploy a new Cloud Run revision, and smoke-test the public URL.
Crucially, the pipeline is app-deploy-only: it ships images but does not run terraform apply. Infrastructure is changed deliberately from a controlled environment, which keeps the CI identity least-privilege — it cannot alter or destroy your infrastructure.
The container
A multi-stage Dockerfile builds the static Astro site with Node 22, then serves dist/ with nginx on port 8080 as a non-root user. The result is a ~25MB image with a health check. To use a different framework, keep that contract — build your app and listen on 8080 — and the rest of the template carries over unchanged.
Where to go next
- Fresh User Walkthrough — zero to a live URL.
- Setup Playbook — bootstrap and Terraform detail.
- IaC Governance Rules — the 9 rules that keep the infrastructure reproducible.