Terraform State Explained, Including the Scary Parts
Table of Contents
Introduction #
Terraform state sounds harmless right up until the day it becomes the reason you are afraid to run terraform apply.
Most of the time, state quietly does its job in the background. It helps Terraform remember which real resources belong to which configuration. That is what makes planning, updating, and destroying infrastructure possible in a predictable way.
The scary part is that when state is missing, outdated, damaged, or simply not the state you thought you were using, Terraform can stop being predictable very quickly.
This post breaks down:
- What Terraform state is
- Why it matters so much
- What people usually mean by state corruption
- What to do if the state goes wrong
- How to reduce the chance of it happening again
What Terraform State Is #
Terraform uses a state file to keep a record of the infrastructure it manages.
That state maps your Terraform configuration to real resources in the target platform. For example, if your code defines an Azure resource group, virtual network, subnet, or AKS cluster, the state helps Terraform understand which real objects match those blocks.
Without state, Terraform would have a much harder time answering questions like:
- What already exists?
- What changed since the last run?
- Which resource needs to be updated?
- Which output values should be returned?
By default, local state is stored in a file named:
|
|
In team environments, local state is usually not enough. That is why remote backends such as Azure Storage, Amazon S3, or Terraform Cloud are commonly used.
Why State Matters So Much #
State is one of the reasons Terraform can compare desired infrastructure with existing infrastructure and produce a plan instead of blindly creating resources.
When state is correct, Terraform can:
- Detect changes
- Update existing resources safely
- Avoid recreating infrastructure unnecessarily
- Track dependencies between resources
- Return useful outputs
When state is wrong, Terraform can make the wrong decision with full confidence, which is a very dangerous quality in automation.
That can lead to problems such as:
- Terraform trying to create resources that already exist
- Terraform wanting to destroy or replace something unexpectedly
- Resources existing in the cloud but not in state
- State referring to resources that no longer exist
- Teams stepping on each other because they used different state copies
What “State Corruption” Usually Means #
When people say the state is corrupted, they do not always mean the JSON file is unreadable.
Sometimes it does mean the file itself is damaged. For example:
- A merge conflict was accidentally committed into a local state file
- The file was edited manually and broken
- A partial write left the file malformed
But more often, “corruption” means the state can no longer be trusted as an accurate view of reality.
That can happen when:
- Someone changed infrastructure manually in the cloud portal
terraform applyfailed halfway through- The wrong backend was used
- The wrong workspace was selected
- A stale local copy of state was used
- State locking failed and two runs overlapped
- A resource was deleted outside Terraform
So there are really two separate problems:
- The state file is technically broken.
- The state file is technically valid, but operationally wrong.
Both are serious, but the recovery steps are slightly different.
First Rule: Stop Making It Worse #
If you think the state is corrupted, the first thing to do is stop running terraform apply repeatedly to see if it fixes itself.
That usually turns a small recovery task into a larger investigation.
Start with this:
- Stop all active Terraform changes for that environment.
- Confirm nobody else on the team is running Terraform.
- Make a backup of the current state immediately.
- Identify whether you are dealing with local state, remote state, drift, or a backend mix-up.
If the state is remote, pull a copy before touching anything:
|
|
If the state is local, copy the file somewhere safe before doing anything else.
Step 1: Figure Out What Kind of Problem You Have #
Before fixing state, work out which of these situations you are in.
Case 1: The State File Is Unreadable #
Examples:
- Terraform reports invalid JSON
- The file contains merge markers
- The file is truncated
In that case, check whether you have:
- A previous backup
- Remote backend version history
- Storage account blob versioning or snapshots
- A teammate with a known-good copy from before the problem
If a known-good backup exists, restoring that backup is usually safer than trying to hand-edit broken state.
Case 2: The State File Is Readable but Out of Sync #
Examples:
- The resource exists in Azure but Terraform wants to create it
- Terraform thinks something exists, but it was manually deleted
- A failed apply created only part of the intended infrastructure
This is usually drift or incomplete state, not file corruption in the strict sense.
Case 3: You Used the Wrong Backend or Workspace #
Examples:
- You accidentally pointed Terraform at a different storage account or key
- You ran in the wrong workspace
- You initialized the directory against the wrong environment
This can look like total state loss when the real issue is that Terraform is reading the wrong state entirely.
Check:
|
|
Then inspect the backend configuration carefully and confirm you are in the expected environment.
Step 2: Compare State With Reality #
Once you know the type of problem, compare what Terraform believes with what actually exists.
Useful commands include:
|
|
If you use Azure, also compare against the platform directly with tools such as:
|
|
You are trying to answer simple questions:
- Which resources exist in the cloud?
- Which resources exist in state?
- Which resources exist in code?
- Which of those three do not match?
That comparison usually tells you whether you need to restore, import, remove, or move state entries.
Step 3: Recover the Smallest Thing Possible #
A good recovery rule is: fix the minimum amount of state needed to get back to a trustworthy plan.
Do not jump straight to rebuilding the entire state if only one resource is wrong.
If a Resource Exists but Is Missing From State #
Import it:
|
|
Example:
|
|
This tells Terraform to start tracking a real resource that already exists.
If a Resource Is in State but Should No Longer Be Managed #
Remove it from state:
|
|
This removes the object from Terraform’s state without deleting the real infrastructure.
That command is useful when:
- The resource was imported by mistake
- A resource is being handed off to another configuration
- The state entry is wrong and needs to be rebuilt cleanly
Use it carefully, because after removal Terraform may try to create the resource again if it is still present in code.
If the Address Changed #
Move the state entry:
|
|
This is useful after refactoring modules, renaming resources, or reorganizing code.
If a Resource Was Deleted Manually #
If the real resource is gone but still exists in state, run terraform plan and see whether Terraform can safely recreate it.
If recreation is acceptable, that may be enough.
If recreation would be destructive or complicated, stop and review dependencies before applying anything.
What To Do After a Failed Apply #
A failed apply is one of the most common ways state becomes scary.
Terraform may have:
- Created some resources
- Failed on others
- Updated state for only part of the run
In that situation:
- Do not immediately rerun
apply. - Review the error that caused the failure.
- Compare actual infrastructure with the current state.
- Run
terraform planto see Terraform’s next proposed action. - Import or repair only the missing pieces if needed.
The main risk is assuming Terraform knows exactly where it left off. Sometimes it does. Sometimes it does not.
If the State File Itself Is Damaged #
If the JSON is actually broken, the best recovery path is usually:
- Restore the last known-good backup.
- Pull the latest recoverable remote version if available.
- Run
terraform plan. - Reconcile any drift that happened after that backup.
Hand-editing raw state should be a last resort.
It is possible, but it is easy to make things worse because state includes internal metadata, resource addresses, instances, dependencies, and provider information that Terraform expects to be consistent.
If you must hand-edit state:
- Keep multiple backups
- Change as little as possible
- Validate by running
terraform plan - Be prepared to restore and try again
How To Prevent State Problems #
You cannot remove all risk, but you can make state much safer.
Use a Remote Backend #
A remote backend is usually better than passing state files around locally.
It gives you:
- Centralized state
- Better team coordination
- Easier backup and recovery
- Less chance of someone using an old local copy
Enable Locking #
State locking helps stop two people or two pipelines from changing the same state at the same time.
Without locking, state corruption becomes much more likely.
Keep State Out of Git #
Terraform configuration belongs in Git.
Terraform state usually does not.
State can contain infrastructure metadata, IDs, output values, and sometimes sensitive information. It is not a normal collaboration artifact.
Avoid Manual Changes #
If people regularly change infrastructure in the cloud portal, drift becomes normal and state becomes less trustworthy.
Sometimes emergency changes are necessary, but they should be reflected back into Terraform as soon as possible.
Separate Environments Properly #
Production, test, and development should not share the same state unless that is very intentionally designed.
Environment confusion is one of the easiest ways to create terrifying plans.
Back Up State #
This sounds obvious, but it matters.
If your backend supports versioning, snapshots, soft delete, or recovery history, turn those features on.