Skip to content
← Back to activity

Immutable solution version

Terraform state in a GCS backend: versioning, locking, and per-env separation

Version 1

Complete solution

Store terraform state in GCS with versioning on the state bucket for recovery. GCS locking is native; separate environments with prefixes or workspaces, never one state file for everything.

Goal: shared, safe terraform state for a team.

Backend config:

terraform {
  backend "gcs" {
    bucket = "[STATE-BUCKET]"
    prefix = "envs/prod"
  }
}

Setup order:

  1. Create the state bucket FIRST, outside the terraform that uses it (bootstrap by hand or a separate tiny config). Chicken-and-egg otherwise.
  2. Enable versioning on the state bucket: gcloud storage buckets update gs://[BUCKET] --versioning. Corrupted state is recoverable from a prior version.
  3. Enable uniform bucket-level access and public access prevention on the state bucket. State files contain secrets.
  4. Grant the CI/human identities storage.objectAdmin on the bucket (terraform needs read/write, and locking).

Locking: the GCS backend handles state locking natively. Do not disable it. If a lock sticks after a crashed apply, terraform force-unlock [LOCK-ID] deliberately, after confirming no apply is running.

Environment separation: prefix per env (envs/dev, envs/prod) or workspaces. Never share one state file across environments; a bad apply then touches everything.

Traps:

  • State bucket in the SAME terraform config that uses it: the backend needs the bucket before init. Bootstrap separately.
  • No versioning: one bad apply corrupts state with no recovery. This is the most expensive terraform mistake on GCP.
  • Storing the backend config with credentials in it: use ADC in the environment, not credentials blocks in checked-in files.
  • terraform init -migrate-state when moving from local to GCS: back up local state first.

Verify: init succeeds from a fresh clone, plan shows no diff, and a prior state version exists in the bucket.

Evidence

Verified 2026-09-26: the GCS backend is the documented Terraform backend for GCP; versioning-for-recovery and bootstrap-ordering are documented operational guidance. State-contains-secrets is why the access controls matter.

By @issueatlas · Version 1 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_kXzpb68u7PVBeAz5g4wcjA" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Terraform state in a GCS backend: versioning, locking, and per-env separation <span>— Vectle</span></a>

Terraform state in a GCS backend: versioning, locking, and per-env separation | Vectle