Chapter 7: Modules
Topic 44

The Cloud Foundation Toolkit

CFTRegistry

The Cloud Foundation Toolkit, or CFT, is a library of production-grade Terraform modules that Google itself writes, publishes, and maintains under the terraform-google-modules namespace on the Registry — project-factory, network, kubernetes-engine, cloud-storage, and dozens more. You consume them through the registry source from the previous topic, and they mean you rarely write a VPC or a project bootstrap from scratch.

That Google's own recommended answer for standing up GCP at scale is a set of Terraform modules is the loudest possible signal of where the platform points its customers. Google's native Deployment Manager is deprecated; its blueprints, its landing-zone guidance, and its reference architectures are CFT modules. When the cloud vendor ships its best practices as Terraform you can terraform apply, the question of which IaC tool to standardize on has already been answered for you.

What CFT Is

CFT is the terraform-google-modules GitHub organization and the matching Registry namespace: opinionated, tested, versioned Terraform modules that encode Google's recommended patterns for projects, networks, IAM, GKE, and storage. Instead of assembling those resources yourself and re-deriving the rules each cloud team learns the hard way, you call a reviewed module that already has them baked in. The modules are open source, carry their own test suites, and version independently of each other.

The Modules You Will Actually Use

Four modules cover most of the scaffolding around the Hatch pipeline. project-factory creates a project with its APIs enabled, billing linked, and a default service account wired up. network builds a VPC with subnets, secondary ranges, and routes. kubernetes-engine stands up a hardened GKE cluster. cloud-storage creates buckets with sane defaults. These are the undifferentiated plumbing — the project, the VPC, the storage scaffolding — while the ingest-pipeline module, the part that is Hatch, stays yours.

CFT does the project and VPC; your own module does the pipeline
module "project" {
  source  = "terraform-google-modules/project-factory/google"
  version = "~> 17.0"
  name            = "hatch-pipeline-prod"
  org_id          = var.org_id
  billing_account = var.billing_account
  activate_apis   = ["run.googleapis.com", "pubsub.googleapis.com", "bigquery.googleapis.com"]
}

module "network" {
  source  = "terraform-google-modules/network/google"
  version = "~> 9.0"
  project_id   = module.project.project_id
  network_name = "hatch-vpc"
  # subnets, secondary ranges, routes — all in one reviewed module
}

module "ingest_pipeline" {       # the part that IS Hatch — stays your own module
  source     = "./modules/ingest-pipeline"
  project_id = module.project.project_id
  event_name = "clickstream"
}
What to write vs what to adopt
write it yourself
The ingest-pipeline module — the part that is Hatch, your product.
adopt CFT
project-factory, network, GKE — undifferentiated plumbing Google already maintains.

Why Google Publishes It

A project-factory module bakes in the parts every team otherwise gets subtly wrong: the API-enablement ordering, the default-service-account handling, and the label conventions. Enabling an API and creating a resource that needs it in the same apply is a classic ordering bug; CFT has the dependency wired so it just works. Google ships the patterns as code so the ecosystem stops re-deriving them — and so that "how do I do X on GCP" has a concrete Terraform answer instead of a doc page you translate by hand.

Evaluating a Public Module Before Adopting

Adopting any public module is a supply-chain decision, and CFT does not exempt you from the diligence. Check the last release date and the commit cadence, the open-issue count, whether the module pins its own provider versions, and whether it ships an examples/ directory you can run. Above all, check the namespace: a module under terraform-google-modules is Google-maintained, while one from a random author may be abandoned and pin an old google provider that blocks your next upgrade.

Being Google-published makes a module trustworthy, not magic. CFT defaults are sane, not automatically least-privilege or right for your org. Run a plan and read what project-factory actually grants and what network actually opens before the first apply — the defaults are a good starting point, not a substitute for reading what lands in your project.

Submodules Within CFT

Many CFT modules ship submodules you reference by the double-slash path. The network module has subnets, routes, and firewall-rules as submodules, so you can compose just the piece you need — terraform-google-modules/network/google//modules/firewall-rules — rather than pulling in the whole VPC module for one rule set. Reaching for the submodule keeps you from inheriting inputs and defaults for resources you never wanted, and is the difference between using CFT precisely and dragging in a heavyweight dependency for a small need.

Writing It Yourself vs Adopting CFT

Roll your own — when the resource set is small, Hatch-specific, and you want full control. The ingest-pipeline module is your product; you write it, version it, and own its interface. Anything that is the differentiated thing you are building belongs to you.

Adopt CFT — for the heavy, error-prone scaffolding: projects, VPCs, GKE. Google has already encoded the API ordering and defaults you would get wrong, and maintaining your own copy buys nothing. The rule of thumb: write the module that is your product, consume the module that is undifferentiated plumbing.

Common Mistakes
  • Hand-rolling a google_project plus a dozen google_project_service and default-SA resources when project-factory already encodes the correct ordering and is one module call.
  • Adopting a public module from a random GitHub author without checking maintenance — an abandoned module pins an old provider and blocks your google upgrade.
  • Pulling in the entire CFT network module when you needed only its firewall-rules submodule — you inherit inputs and defaults for resources you do not want.
  • Assuming a Google-published module is automatically least-privilege or right for your org — CFT defaults are sane, not magic, and you still read what project-factory grants before applying.
  • Pinning no version on a CFT module, so a fresh init jumps a major release that renames inputs out from under your config.
Best Practices
  • Default to the terraform-google-modules CFT module for projects, networks, and GKE rather than assembling those resources by hand.
  • Evaluate any public module on release recency, issue count, provider pinning, and examples/ before adopting — treat it as a supply-chain dependency.
  • Compose CFT submodules (network//modules/firewall-rules) to pull in only the piece you need instead of the whole module.
  • Read what a CFT module actually creates and grants by running plan before the first apply, rather than trusting the defaults blind.
  • Write your own module for the part that is your product, and consume CFT for the undifferentiated plumbing around it.
Comparable tools AWS terraform-aws-modules — the structural analog, but community-led, not vendor-led Pulumi component packages as the published unit of reuse Helm charts as the Kubernetes published-module analog

Knowledge Check

What is the Cloud Foundation Toolkit, and who maintains it?

  • A library of Terraform modules Google itself publishes and maintains under terraform-google-modules
  • A community-driven collection of unofficial GCP modules contributed by volunteers, with no vendor involvement
  • Google's deprecated Deployment Manager templates, repackaged as Terraform for backward compatibility
  • A paid HashiCorp service that provisions and runs the GCP modules on managed infrastructure for you

What signal does Google publishing its recommended patterns as Terraform modules send?

  • Terraform is where Google points its customers — the IaC standardization question is effectively answered
  • Google plans to deprecate Terraform support and replace it with its own native IaC tool soon
  • CFT modules only run inside Google's managed Infrastructure Manager service, never the open-source binary
  • The modules are experimental previews, not meant for production landing zones

You need only a set of firewall rules, not a whole VPC. What is the right move with CFT?

  • Reference the firewall-rules submodule via the double-slash path instead of the full network module
  • Adopt the whole network module and disable the subnet and route resources you don't need with flags
  • Fork the network module into your own repo and delete every resource except the firewall rules
  • Write the firewall rules by hand, since CFT ships no submodules you can target on their own

When should you write your own module rather than adopt CFT?

  • For the small, Hatch-specific resource set that is your product, like the ingest pipeline
  • For the project bootstrap, since CFT's project-factory is too opinionated about API ordering to trust
  • For the VPC, because a hand-rolled network with your own subnets is always more reliable
  • Always — adopting any public module is a supply-chain security risk not worth taking on

You got correct