Cloud and infrastructure as code
Terraform state and locking
The state file maps your code to real resources. Keep it in a remote backend with locking, and treat import, move and remove as production surgery.
Terraform does not scan your whole cloud account on each run. It keeps a state file: a JSON map from each resource address, such as aws_s3_bucket.assets, to the real cloud ID and attributes. Without that map, Terraform cannot tell which real resources it owns.
Concept
Before you start. Read plan and apply. A plan is the desired config compared with the state, refreshed against the cloud API.
The big idea
Think of state as a hotel's check-in list. It maps each guest name to a room number. The list is useful because the desk can answer quickly without walking every floor.
Where the analogy breaks: the list can be wrong. A guest may leave without telling the desk, and that is drift. Terraform fixes only what it can see, so the list must stay accurate.
Local state and remote backends
Local state (terraform.tfstate on disk) is fine for a laptop experiment. For a team it is risky. It has no locking, it is easy to lose, and people often commit it to git. State can contain passwords and private keys.
Use a remote backend. This example stores state in an S3 bucket:
terraform {
backend "s3" {
bucket = "acme-tf-state"
key = "prod/payments/terraform.tfstate"
region = "us-east-1"
encrypt = true
use_lockfile = true # native S3 locking (Terraform 1.9+)
}
}You need three properties: durable storage, encryption at rest, and locking.
Walking through a race without a lock
Two applies start at the same time, with no lock.
Apply A reads state: bucket, no versioning
Apply B reads state: bucket, no versioning
Apply A writes state: bucket, versioning on
Apply B writes state: bucket, tags added <- A's write is lostThe bucket still has versioning, but state no longer records it. The next plan may try to undo the setting or miss it. That is classic drift, and it is hard to untangle later.
State surgery
Sometimes you must edit the map without changing the cloud.
| Command | Use when |
|---|---|
terraform import | The resource already exists and should be managed |
terraform state mv | You renamed a resource address in code |
terraform state rm | Stop managing a resource, but leave it running |
terraform refresh | Re-read remote attributes into state |
Renaming a resource in code without a move makes the next plan destroy the old address and create a new one. For a database, that means a new, empty instance. The fix is a move:
terraform state mv aws_db_instance.main aws_db_instance.primary
terraform planNo changes. Your infrastructure matches the configuration.After any surgery, the plan should show no changes. If it does not, stop and read it.
Common mistakes
- Committing state to git. If it leaks, rotate the secrets in it, then move to a remote backend.
- Running two applies at once without a lock. One write silently overwrites the other.
- Editing state and not checking the plan afterward. A wrong
importattaches the wrong object to a name.
Check yourself
- Why can't Terraform rely only on your code? Answer: it needs the state to know which real resource each address refers to, and which ones it created.
- You renamed a resource in code. Which command stops a destroy?
Answer:
terraform state mvfrom the old address to the new one, then confirm the plan shows no changes.
Key takeaways
- State maps each resource address to a real ID. Plans depend on it.
- Use a remote backend with encryption and locking.
- Treat
import,mvandrmwith the care of a data migration. - Next, modules and environments shows how to split state across environments.
Further learning
State (Terraform docs)An introduction to state, information that Terraform uses to map resources to a configuration, track metadata, and improve performance.State | Terraform | HashiCorp Developer
The s3 backend (Terraform docs)Terraform can store and lock state remotely in Amazon S3.Backend Type: s3 | Terraform | HashiCorp Developer
How to manage Terraform state (Gruntwork)Managing Terraform state: a guide to file layout, isolation, and locking for Terraform projects, part of the Comprehensive Guide to Terraform series.blog.gruntwork.io
Importing existing resources (Terraform docs)Learn about importing existing infrastructure resources to your Terraform workspace using the bulk import workflow or the single-resource import workflowImport resources overview | Terraform | HashiCorp Developer
Related
Infrastructure as code with Terraform
Declaring infrastructure in code — providers, state, plans, modules, environments and the habits that keep apply safe.
Terraform plan and apply
The Terraform loop. Write resources, read the plan, then apply it. Learn the building blocks and the plan symbols that flag replacements.
Safe Terraform changes
Run plans in CI, check policy before apply, and guard stateful resources in the config. Force-new changes need extra care because they can replace data.