Clicking and ad-hoc gcloud do not scale; IaC makes environments reviewable, reproducible and recoverable.
Terraform (HashiCorp, or the open-source fork OpenTofu) is the most common way to manage Google Cloud infrastructure as code. You declare resources in .tf files; terraform plan shows the diff against reality; terraform apply makes it so.
Google Cloud specifics:
- The
googleprovider (andgoogle-betafor preview features) authenticates with ADC. Setimpersonate_service_accountso humans and CI apply as one controlled service account instead of their own broad rights. - Store state remotely in a Cloud Storage bucket with the
gcsbackend; it supports locking. Enable object versioning on that bucket, and treat state as sensitive: it can contain secrets. - Enable APIs as resources (
google_project_service) so a fresh project bootstraps itself. - IAM has three resource styles:
_iam_policy(authoritative for the whole resource, dangerous),_iam_binding(authoritative for one role) and_iam_member(adds one member, safest to mix with other tools).
Google's Cloud Foundation Fabric and Terraform blueprints provide vetted modules for projects, VPCs and landing zones. Infrastructure Manager runs Terraform as a managed service; the older Deployment Manager is deprecated.
Run Terraform from CI (e.g. Cloud Build or GitHub Actions with Workload Identity Federation) after code review, not from laptops.
Example
terraform {
required_providers {
google = { source = "hashicorp/google", version = "~> 7.0" }
}
backend "gcs" {
bucket = "shop-tf-state"
prefix = "envs/dev"
}
}
provider "google" {
project = "shop-dev-4821"
region = "europe-west1"
impersonate_service_account = "terraform@shop-dev-4821.iam.gserviceaccount.com"
}
resource "google_project_service" "run" { service = "run.googleapis.com" }
resource "google_storage_bucket" "uploads" {
name = "shop-dev-4821-uploads"
location = "EUROPE-WEST1"
uniform_bucket_level_access = true
public_access_prevention = "enforced"
}Remember
- plan shows the diff; apply makes it real
- Remote state in a versioned GCS bucket; it is sensitive
- Apply via an impersonated service account from CI
- Prefer _iam_member over authoritative _iam_policy
Watch out for
- Using google_project_iam_policy, which silently removes every binding not listed, including Google service agents.