Where Should You Store Your Infrastructure State? A Practical Guide
You have just finished writing a Terraform configuration that provisions a handful of servers and a database. You run terraform apply on your laptop, and everything works. Your colleague, who needs to add a load balancer, runs the same configuration from their machine. Suddenly, the database disappears. Not because the code was wrong, but because your colleague's local state file did not know the database already existed.
This scenario is not hypothetical. It happens every day in teams that store infrastructure state as a local file on each developer's machine. The problem is simple: when multiple people manage the same infrastructure, each person's local state quickly becomes outdated. Resources get overwritten, duplicated, or accidentally destroyed. The fix is equally simple: store state in a shared, secure location that everyone on the team can access.
What Is State, and Why Does It Matter?
State is the record of everything your infrastructure tool has created. It contains resource IDs, IP addresses, configuration values, and sometimes even passwords or API keys stored as plain text. When you run terraform plan, the tool reads the current state to understand what already exists and what needs to change. Without accurate state, the tool cannot know whether a resource should be created, updated, or left alone.
If state is lost or corrupted, the tool loses track of your infrastructure. You end up with orphaned resources that cost money but are no longer managed. Or worse, you accidentally recreate resources that were already running, causing downtime.
The Local File Trap
The simplest way to store state is as a file on your own machine. For learning or personal projects, this works fine. You are the only person touching the infrastructure, so there is no conflict.
But the moment a second person joins, local state breaks. Here is what happens:
- You create a server. Your state file records it.
- Your colleague runs the same configuration. Their state file is empty, so the tool tries to create another server with the same name.
- The cloud provider rejects the duplicate, or worse, the tool overwrites the existing server because it does not know it exists.
Even if you share the state file through version control, you run into merge conflicts. Two people cannot edit the same state file at the same time without overwriting each other's changes. This is why teams that manage infrastructure together must use a remote backend.
To help you decide which approach fits your situation, here is a decision flowchart:
Remote Backend: The Shared Source of Truth
A remote backend stores state in a location that everyone on the team can access. Common choices include an S3 bucket on AWS, a GCS bucket on Google Cloud, or an Azure Storage container. Everyone points their infrastructure tool to the same backend, so the state is always consistent.
Here is a minimal Terraform backend configuration that uses an S3 bucket for state storage and a DynamoDB table for locking:
terraform {
backend "s3" {
bucket = "my-company-terraform-state"
key = "production/network/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"
encrypt = true
}
}
Before using this configuration, create the S3 bucket with versioning enabled and a DynamoDB table with a primary key named LockID (type String). The encrypt = true setting ensures the state file is encrypted at rest.
But a remote backend is not just a shared folder. You need to think about several things before choosing one.
Access Control Is Non-Negotiable
State files contain sensitive information. Resource IDs, IP addresses, and sometimes credentials are stored in plain text. If someone outside your team gains read access to the state, they can see the details of your entire infrastructure. If they gain write access, they can corrupt or delete resources.
Lock down the bucket or container where state is stored. Use IAM policies or role-based access to ensure only authorized people and systems can read or write state. Treat the state bucket like you would treat a production database.
Speed and Cost Trade-Offs
Local state is fast because the file is on your machine. Remote backends require downloading state before a plan or apply, and uploading it afterward. For small teams with a few dozen resources, this adds a second or two. For large infrastructure with thousands of resources, the download and upload can take minutes.
Some backends charge per operation or per gigabyte of storage. S3, for example, charges for PUT and GET requests. If your team runs terraform plan dozens of times a day, those costs add up. Choose a backend that fits your team's usage pattern.
Versioning Saves You From Mistakes
Some remote backends support versioning. S3 can keep a history of every state file change. If someone applies a change that breaks things, you can roll back to a previous state version and recover.
Versioning is not enabled by default. You must turn it on explicitly. Do not assume your backend automatically keeps history. Check the documentation and enable versioning before you need it.
Managed Backends Reduce Operational Overhead
If you do not want to manage a bucket, access policies, and versioning yourself, consider a managed backend like Terraform Cloud or HashiCorp Consul. These services are designed specifically for state management. They include versioning, history, locking, and integration with CI/CD pipelines.
The trade-off is cost and vendor lock-in. Managed backends charge per user or per workspace. You also depend on the provider's uptime and API availability. For teams that want to focus on infrastructure rather than state management, this trade-off is often worth it.
Locking Prevents Concurrent Changes
Even with a remote backend, two people can run terraform apply at the same time. Without locking, both operations read the same state, make changes, and write back. The second write overwrites the first, and the first person's changes are lost.
Most remote backends support locking. S3 with DynamoDB, for example, uses a DynamoDB table to hold a lock. When someone starts an operation, the tool acquires the lock. Other operations must wait until the lock is released. This prevents state corruption from concurrent writes.
Locking is not optional for teams. If your backend does not support it, find one that does.
A Practical Checklist for State Storage
Before you decide where to store state, run through this checklist:
- Is the backend accessible to everyone who needs it?
- Is access restricted to authorized people and systems?
- Does the backend support versioning?
- Does the backend support locking?
- Is the cost acceptable for your team's usage?
- Is the latency acceptable for your workflow?
If you answer yes to all six, you have a solid state backend.
The Concrete Takeaway
Do not store infrastructure state on your laptop. Use a remote backend that supports access control, versioning, and locking. The few minutes it takes to set up a proper state backend will save you from hours of debugging when someone accidentally deletes a resource or overwrites a colleague's changes. Your infrastructure is only as reliable as the state that tracks it. Make sure that state lives somewhere safe.