Terraform records the state of the resources it manages in a state file
(terraform.tfstate). It maps your configuration to the real resources Terraform
manages - lose it and Terraform loses track of everything it built.
On the first apply, Terraform writes a state file recording the current
state of your infrastructure - you don't author it. It maps your config to the
real resources Terraform manages. Verify results in the console (Compute Engine
→ VM instances): the instance appears after apply and is gone after destroy.
⚠GotchaNever touch the state file by hand
The state file is created and updated automatically - do not modify or edit it. Editing
it by hand desynchronizes Terraform from reality.
Before any operation Terraform first does a refresh: it reads the live
infrastructure and updates the state to match reality. It then compares three
things for every resource - your configuration, the state file, and the
live resource - and that comparison is what produces the plan.
On every run Terraform reads the config and the state, then per resource decides Create, Read, No-op, Update, or Delete before outputting the plan.
Not in state → the resource is new, so Terraform plans Create(); after
apply it's recorded in state under its resource-block name.
In state, no changes → No-op.
In state with changes → Update() in place.
In state but removed from config (or a destroy plan) → Delete().
⚠GotchaSome updates force a destroy and re-create
If an argument can't be updated in-place because of a remote API limitation,
Terraform destroys and re-creates the resource instead of updating it. Watch for
this in the plan - it can mean downtime.
By default the state file is stored locally, alongside your configuration. It can also be
stored remotely - the preferred method when working in a team. Store it in a GCS
backend with locking and versioning so everyone shares one state safely and two
concurrent apply runs can't collide.
Terraform saves state two ways: locally, where terraform apply writes a terraform.tfstate file into the working directory, or remotely, in a shared backend like a Google Cloud Storage bucket or Terraform Cloud.
Local state suits a single developer, but when several people run Terraform against their own
copies, each machine holds its own picture of the infrastructure. Three problems follow, all
solved by a remote GCS backend:
Three issues with keeping Terraform state on a local machine: no shared access (teammates cannot reach the same file), no locking (concurrent applies corrupt state and lose data), and no confidentiality (state sits in plain text, exposing secrets like database credentials).
Store Terraform state remotely in a Cloud Storage bucket, in two steps: main.tf (M) defines a google_storage_bucket resource that creates the bucket, then backend.tf (B) points the terraform backend "gcs" block at that same bucket so state lives there.
Moving state to a bucket is a one-time, two-step migration - the M and B badges above map
each file to the block it holds:
CommandsMigrate local state to a GCS backend
# 1. Add a google_storage_bucket resource to main.tf, then create the bucket:
terraform apply
# 2. Add a terraform { backend "gcs" { bucket = ..., prefix = ... } } block to backend.tf
# 3. Configure the backend - Terraform detects the local state and offers to copy it:
terraform init # answer "yes" to copy terraform.tfstate into the bucket
After init, state lives in the bucket. Terraform pulls the latest state before running a
command and pushes it back after - so there's no stale copy and no manual error.
⚠GotchaSet the bucket `location` deliberately
In the google_storage_bucket resource the location is hardcoded to US (a multi-region
bucket in the US). Change it to the location you actually want before you apply.
Four practices cover state optimization and security, each with its own accent below.
Beyond these, keep state out of source control with .gitignore and restrict the
remote bucket so only the build system and highly privileged administrators can
reach it.
Four Terraform state best practices, each color-accented: use remote state when working in teams (it supports locking and versioning); don't store secrets in a state file (Terraform stores secret values in plaintext); encrypt state (customer-supplied encryption keys add a layer of protection); and don't modify state manually (use the terraform state command when you need to change it).