Terraform state explained: the map behind every plan
State touches half of the 004 objectives: fundamentals, the workflow, state management, maintenance and HCP Terraform. Learn it once, properly, and those questions get easy.

What state does
It maps code to real objects. Your configuration says aws_instance.web. State records which real instance ID that address points to, so Terraform updates the right object instead of creating a new one.
It stores attributes and dependencies. IDs, IP addresses and other values live in state, which is how other resources and outputs can reference them, and how Terraform knows what to destroy and in what order.
It makes plans possible. terraform plan refreshes state against real infrastructure, then compares the result with your configuration to decide what to create, update, replace or destroy.
Local vs remote state
- terraform.tfstate in the working directory
- terraform.tfstate.backup keeps the previous version
- CLI workspaces go under terraform.tfstate.d
- No sharing, and every copy can drift apart
- Fine for learning and personal experiments
- State in S3, Azure Storage, GCS, HCP Terraform and others
- Locking so two applies cannot run at once
- Encryption at rest and access control
- Declared in a backend block, or a cloud block for HCP Terraform
- Other configurations can read outputs with terraform_remote_state
Locking, in four facts
The state commands and blocks you must know
| Task | Use |
|---|---|
| List every tracked resource | terraform state list |
| See every attribute of one resource | terraform state show ADDRESS |
| Move to a new backend and keep existing state | terraform init -migrate-state |
| Point at a new backend without copying state | terraform init -reconfigure |
| Detect drift without proposing changes | terraform plan -refresh-only |
| Accept drift into state without touching infrastructure | terraform apply -refresh-only |
| Bring an existing object under management, reviewed in a plan | An import block, then plan and apply |
| Rename a resource without destroying it | A moved block (or terraform state mv for a one-off) |
| Stop managing an object without destroying it | A removed block (or terraform state rm) |
Secrets in state
State stores attribute values in plain text, including database passwords and keys that providers return. Treat the state file as sensitive: keep it in an encrypted remote backend with tight access, never in Git.
sensitive = true hides a value in plan and output text. It does not remove it from state. Ephemeral values are never written to plan or state files, and write-only arguments let a provider accept a secret, such as a database password, without storing it. For Vault, the recommended pattern reads secrets at apply time rather than hardcoding them in configuration.
5 practice questions on Terraform state
Taken from the Terraform 004 course. Click an option; every option is explained.
A new configuration has no backend block and no cloud block. An engineer runs terraform apply. Where is the state stored?
- HCP Terraform is used only when the configuration has a cloud block or remote backend.
- That file records the backend configuration of the working directory, not the managed resources. Local state lives in terraform.tfstate.
- Terraform always saves state. The local backend is the default.
- Correct. Without a backend, Terraform uses the local backend and writes terraform.tfstate in the root module directory.
A CI runner crashed in the middle of an apply. Now every run fails because the state is still locked, and no Terraform process is running. What should the engineer run?
- Reinitializing the backend does not release an existing lock.
- Correct. force-unlock removes a lock left behind when automatic unlocking failed. The lock ID is shown in the error.
- state rm removes resources from state. It does not handle locks.
- A zero timeout fails immediately. It does not release the lock.
A team has been using local state and now adds an s3 backend block. They want to keep their existing resources under management. What should they run?
- Correct. When the backend changes, init with -migrate-state copies the existing state into the new backend.
- -reconfigure starts with the new backend and does not copy the old state.
- This updates state from real infrastructure. It does not move state between backends.
- Pushing before init would still target the old local backend.
An engineer suspects someone changed resources in the cloud console. They want to see how real infrastructure differs from state without proposing any changes to match the configuration. Which command should they run?
- This skips the refresh, so drift would not be detected.
- Correct. A refresh-only plan shows how state would be updated to match real infrastructure, without proposing configuration changes.
- validate checks syntax and references only. It never contacts the provider APIs.
- show displays saved state or a plan file. It does not compare state with real infrastructure.
A team on Terraform 1.12 wants to set a database admin password without the password ever being stored in state. The provider supports it. What should they use?
- sensitive hides the value in output, but the password is still stored in state.
- Correct. Write-only arguments accept values, including ephemeral ones, that are sent to the provider but never saved in state or plan.
- Provisioners can log values, and this does not keep the password out of state.
- Root modules cannot declare ephemeral outputs, and an output does not set a resource argument.
State questions hide in every objective
Drill them in six timed Terraform 004 exams where every option is explained.
FAQ
What is Terraform state?
A record, usually terraform.tfstate, that maps each resource in your configuration to the real object it manages, with its attributes and dependencies. Terraform compares configuration, state and real infrastructure to build a plan.
Where is state stored by default?
With no backend or cloud block, Terraform uses the local backend and writes terraform.tfstate in the working directory, keeping the previous version as terraform.tfstate.backup.
Should I commit terraform.tfstate to Git?
No. State can contain secrets in plain text and Git gives you no locking. Use a remote backend with encryption, access control and locking, or HCP Terraform.
What does terraform force-unlock do?
It removes a lock that was left behind, for example after a CI runner crashed mid-apply. Use it only when you are sure no other Terraform process is running.
Does sensitive = true keep a value out of state?
No. It redacts the value in CLI output, but the value is still stored in state. To keep a secret out of state, use ephemeral values and write-only arguments where the provider supports them.
More guides: Terraform 003 vs 004 · Terraform 004 study plan · Free Terraform 004 questions · all guides