Set Up a Google Cloud Landing Zone with Terraform Example Foundation
Quick answer
Bootstrap a Google Cloud landing zone (what Google itself calls a 'cloud foundation') using the official Terraform Example Foundation — org-level folder structure, environment separation, and Shared VPC networking, stage by stage.
- Step 1: Confirm you have an actual Organization resource
- Step 2: Stage 0 — bootstrap
- Step 3: Stage 1 — org
- Step 4: Stage 2 — environments
- Step 5: Stage 3 — networking
advanced · 45 min
Before you begin
- A Google Cloud Organization (not a standalone project — this requires an org resource)
- A billing account linked to the organization
- Organization-level IAM permissions sufficient to create projects, assign IAM roles, and enable organization policies
- Terraform installed locally or in your CI runner
- gcloud CLI authenticated against the target organization
If you want the conceptual comparison of landing zones across AWS, Azure, and GCP first, read What Is a Cloud Landing Zone? before this tutorial.
Google's own documentation calls this pattern a landing zone (interchangeably a "cloud foundation"), and its official Terraform-based reference implementation is Terraform Example Foundation, maintained at terraform-google-modules/terraform-example-foundation. It deploys via the Cloud Foundation Toolkit (CFT) bootstrap module, in a fixed sequence of numbered stages — each stage's Terraform state depends on the previous one, so you run them in order, not in parallel.
This is more involved than a single terraform apply — treat each stage below as its own directory with its own state, applied one at a time.
Step 1: Confirm you have an actual Organization resource
This whole pattern assumes a Google Cloud Organization, not a standalone project with no org attached. If you signed up for GCP without Google Workspace or Cloud Identity backing it, you likely don't have one yet — set that up first; none of the stages below work without an org node to attach the folder hierarchy to.
gcloud organizations listIf this returns nothing, stop here and resolve that before continuing.
Step 2: Stage 0 — bootstrap
git clone https://github.com/terraform-google-modules/terraform-example-foundation.git
cd terraform-example-foundation/0-bootstrapThis stage runs the CFT Bootstrap module, which bootstraps the organization itself: it creates the seed project, the Terraform state bucket(s), and the service accounts and IAM bindings every later stage needs to run non-interactively. Review terraform.tfvars.example, fill in your org ID, billing account ID, and group emails for the various admin roles it expects, then:
terraform init
terraform plan
terraform applyDo not skip reviewing the plan here — this stage is granting broad organization-level permissions to the service accounts that every later stage will run as.
Step 3: Stage 1 — org
cd ../1-org
terraform init
terraform plan
terraform applyThis establishes the shared common folder and the network folder, along with the projects and environment-specific network infrastructure that later stages build on.
Step 4: Stage 2 — environments
cd ../2-environments
terraform init
terraform applyThis creates the environment-specific folder structure — Terraform Example Foundation's default split is development, nonproduction, and production — each with its own KMS and Secret Manager projects. This three-way split (not just "prod vs. non-prod") is a deliberate opinion baked into the reference architecture: it exists so a compromised or misconfigured dev environment can't reach production secrets or keys, not just production compute.
Step 5: Stage 3 — networking
Pick one topology, not both:
# Shared VPC per environment
cd ../3-networks-svpc
# — or — hub-and-spoke via Network Connectivity Center
cd ../3-networks-hub-and-spoketerraform init
terraform apply3-networks-svpc gives each environment its own Shared VPC with firewall policies, Cloud NAT, and DNS. 3-networks-hub-and-spoke builds the equivalent connectivity through a hub-and-spoke topology instead — pick whichever matches your actual network topology decision, made before you started (see the conceptual post linked above if you haven't made that call yet).
Step 6: Stage 4 — projects
cd ../4-projects
terraform init
terraform applyThis is where individual service projects get created and attached to the Shared VPC, organized by business unit, along with the CI/CD pipeline infrastructure that later application teams will use to deploy their own workloads. This is the GCP equivalent of AWS's "vend an account" or Azure's "subscription vending" step — the repeatable unit a workload team actually receives.
Step 7 (optional): Stage 5 — app infra
cd ../5-app-infra
terraform init
terraform applyDeploys sample Compute Engine infrastructure purely to prove the foundation actually works end-to-end — a real workload team's own Terraform replaces this stage, it isn't meant to stay in place.
Step 8: Verify the folder hierarchy
gcloud resource-manager folders list --organization=<your-org-id>Confirm the common, network, and the three environment folders (development, nonproduction, production) all exist under your organization, each with the expected projects underneath.
What you should have now
- An organization-level Terraform bootstrap with its own state and service accounts, separate from any single workload
- Environment folders (development / nonproduction / production) with hard separation at the KMS and Secret Manager level, not just naming convention
- Either Shared VPC or hub-and-spoke networking already wired per environment
- A repeatable "stage 4" pattern for vending new service projects to workload teams, instead of hand-creating projects in the console
We built Podscape to simplify Kubernetes workflows like this — logs, events, and cluster state in one interface, without switching tools.
Struggling with this in production?
We help teams fix these exact issues. Our engineers have deployed these patterns across production environments at scale.