Skip to main content

Terraform State

Exam guide§2.4

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.

State is created and managed automatically

GotchaThe state file is created automatically

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.

What's inside a state file

A snippet from a state file - state records the metadata of each resource it created: the resource type, name, and the provider that manages it.

{
"version": 4,
"terraform_version": "1.2.3",
"serial": 2,
"lineage": "f9e0d82a-4bb4-1db2-7912-3d31117903cc",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "google_storage_bucket",
"name": "test-bucket-for-state",
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
"instances": [
{
"schema_version": 0
}
]
}
]
}

How state drives the plan

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.

YesNoYesNoYesNoStartRead configurationRead StateResource in State?Read()Has Changes?Is Destroy Plan?Create()No-opUpdate()Delete()Output planEnd
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 changesNo-op.
  • In state with changesUpdate() 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.

Where state lives: local vs remote

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.

Ways to save a state fileSave locally-- servers/-- main.tf-- variables.tf-- outputs.tf-- main.tfterraform.tfstateThe terraform apply commandautomatically generates a state filethat is saved in a working directory.Save remotelyThe file is stored in a remotelocation like a Google Storagebucket or Terraform Cloud.
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.

Why local state breaks down for a team

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:

Issues with storing the Terraform state locallyNo shared accessFor any update to the infrastructure, each member of your teamneeds access to the same state file.No lockingWhen team members run Terraform at the same time, they run intoconflict in access, which leads to data corruption and data loss.No confidentialityState file exposes all sensitive data such as username andpassword of the database.
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 state in a GCS backend

Store Terraform state remotely in a Cloud Storage bucket-- main.tfM-- backend.tfBCreate the bucket.Change the backend configurationMresource "google_storage_bucket" "default" { name = "<my_unique_bucket_name>" force_destroy = false location = "US" storage_class = "STANDARD" versioning { enabled = true }}Bterraform { backend "gcs" { bucket = "<my_unique_bucket_name>" prefix = "terraform/state" }}
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.

State best practices

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.

Terraform state best practicesUse remote state whenworking in teamsRemote state supports locking and versioning.Don't store secrets in astate fileAvoid storing secrets in state because Terraformstores secret values in plaintext.Encrypt stateUse customer-supplied encryption keys to add alayer of protection.Don't modify statemanuallyUse the terraform state command when youneed to modify a state.
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).