Cloud Engineering

Set Up a Google Cloud Landing Zone with Terraform Example Foundation

Advanced45 min to complete13 min readSeptember 24, 2026

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.

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
Google Cloud
GCP
Terraform
Landing Zone
Cloud Foundation Toolkit
Shared VPC
Platform Engineering

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.

bash
gcloud organizations list

If this returns nothing, stop here and resolve that before continuing.

Step 2: Stage 0 — bootstrap

bash
git clone https://github.com/terraform-google-modules/terraform-example-foundation.git
cd terraform-example-foundation/0-bootstrap

This 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:

bash
terraform init
terraform plan
terraform apply

Do 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

bash
cd ../1-org
terraform init
terraform plan
terraform apply

This 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

bash
cd ../2-environments
terraform init
terraform apply

This 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:

bash
# Shared VPC per environment
cd ../3-networks-svpc

# — or — hub-and-spoke via Network Connectivity Center
cd ../3-networks-hub-and-spoke
bash
terraform init
terraform apply

3-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

bash
cd ../4-projects
terraform init
terraform apply

This 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

bash
cd ../5-app-infra
terraform init
terraform apply

Deploys 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

bash
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.