Store Terraform state in a remote backend with bucket versioning turned on, encryption enabled and locking active. Versioning is your recovery path after an accidental delete or bad write. Treat the state file as sensitive, because it often contains secret values.
Why state needs its own plan
State records which real resources belong to which parts of your code. Lose it and Terraform no longer knows what it manages. A plan can propose creating duplicates of resources that already exist, or an operator may be tempted to import everything by hand.
Two facts shape the plan. First, HashiCorp's documentation says state snapshots often include sensitive information, and that reading remote state needs access to the whole snapshot. Second, the S3 backend documentation says it is highly recommended to enable bucket versioning so you can recover state after accidental deletions and human error.
Setup checklist for an S3 style backend
- Versioning on the bucket. It is set on the bucket itself, not as a Terraform argument.
- Encryption. The backend has an option to encrypt the state and lock files, and a KMS key option so you control the key. Grant Terraform only the key actions it needs.
- Locking. The backend supports a lock file option, default off. The older DynamoDB lock option is documented as deprecated, so plan a move if you use it.
- Narrow access. Few identities should read or write state. Many roles only need to read outputs, which is better served by publishing those values elsewhere.
- Separate states. Split by environment and by blast radius so one bad write cannot affect everything.
Recovery steps
- Stop all runs and CI jobs that use the state, so no one writes while you recover.
- List the object versions in the bucket and find the last good one.
- Restore that version as the current one, then run a plan with no changes applied.
- Read the plan. A clean plan means state and reality match. Unexpected changes mean the restored version is older than some real change, so reconcile before applying.
- Record what happened and why in a ticket.
Keep a copy outside the backend
Versioning protects against edits. It does not protect against someone deleting the bucket or the account being closed. Copy state files on a schedule to a second location with separate credentials, and keep the infrastructure code itself in offline or separately stored backups. CISA's ransomware guide specifically recommends keeping infrastructure as code template files in offline backups so cloud resources can be redeployed quickly.
What not to do
- Do not commit state files to Git.
- Do not put customer-supplied encryption keys in a Terraform file. The documentation warns that doing so persists the key into state, and recommends an environment variable.
- Do not edit state by hand unless you have copied it first.
Safeguard scans infrastructure as code files in pull requests with policies and gates, which can flag a backend defined without encryption. A free scan is available.
Quick check
Can I rebuild state from my code alone?
Partly, by importing each existing resource, but it is slow and error prone at scale. Versioned backups of state are much faster.
Is the state file really sensitive?
Treat it that way. HashiCorp says state snapshots often include sensitive information, so apply the same access limits you would to a secrets store.
Sources
Last reviewed: 19 October 2026.