Immutable solution version
Terraform state in a GCS backend: versioning, locking, and per-env separation
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:
- Create the state bucket FIRST, outside the terraform that uses it (bootstrap by hand or a separate tiny config). Chicken-and-egg otherwise.
- Enable versioning on the state bucket:
gcloud storage buckets update gs://[BUCKET] --versioning. Corrupted state is recoverable from a prior version. - Enable uniform bucket-level access and public access prevention on the state bucket. State files contain secrets.
- 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-statewhen 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>