What is Terraform State?
If you write a Terraform configuration to create an EC2 instance, and run terraform apply, AWS creates the instance.
If you run terraform apply a second time, how does Terraform know not to create a second instance?
The answer is State.
Terraform must store state about your managed infrastructure to map real-world cloud resources back to the resources declared in your .tf configuration files.
By default, this state is stored in a local JSON file named terraform.tfstate.
Your Code (main.tf)
↓
Terraform
↓
State File (terraform.tfstate) ← "I remember creating i-12345!"
↓
Real Cloud Infrastructure
Why does Terraform need State?
Couldn't Terraform just ask AWS what resources exist every time it runs? State serves three critical purposes that make this impossible in practice.
1. Mapping Reality to Code
Your code calls the server aws_instance.web.
AWS knows the server as i-0f8a9b2c3d4e5f6g7.
Terraform uses the state file to map web to i-0f8a9b2c3d4e5f6g7.
If you change the instance type in your code from t2.micro to t3.micro, Terraform checks the state, sees that web maps to i-0f8a9b..., and issues an API call to strictly update that specific instance.
2. Tracking Metadata and Dependencies
Terraform tracks resource dependencies in the state file. If you delete a VPC and an EC2 instance from your code, Terraform uses the state file's dependency tracking to know it must destroy the EC2 instance before it destroys the VPC.
3. Performance Check Caching
In a massive enterprise environment with 10,000 resources, making 10,000 API calls to AWS just to see "what exists right now" would take hours and result in API throttling. State acts as a cache. Terraform only needs to query the cloud provider about resources it expects to exist.
Inspecting the State File
CRITICAL RULE: Never, ever manually edit the terraform.tfstate file with a text editor. Doing so can irreversibly corrupt your infrastructure mapping. Let Terraform manage it via CLI commands.
The state file is just JSON. If you open a basic terraform.tfstate file, it looks like this:
{
"version": 4,
"terraform_version": "1.7.0",
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"ami": "ami-0c55b159cbfafe1f0",
"arn": "arn:aws:ec2:us-east-1:123456789012:instance/i-0abcdef1234567890",
"id": "i-0abcdef1234567890",
"instance_state": "running",
"private_ip": "10.0.1.5",
"public_ip": "203.0.113.10"
}
}
]
}
]
}Notice that the state file captures everything about the resource—even attributes you didn't explicitly set in your code, like the auto-assigned public_ip or arn.
The terraform state Command
Instead of editing the file manually, Terraform provides safe CLI commands to inspect and modify state.
Reviewing State
To see a simple list of all resources currently tracked in state:
terraform state listOutput:
aws_instance.web
aws_security_group.allow_web
To see all the cached details (IPs, IDs, ARNs) of a specific resource:
terraform state show aws_instance.webSafely Modifying State
Sometimes you change the name of a resource block in your code:
- resource "aws_instance" "old_name" {
+ resource "aws_instance" "new_name" {If you just run terraform apply, Terraform will destroy old_name and create a brand new machine called new_name. This causes severe downtime!
Instead, tell Terraform you just renamed it in the code by moving it in the state:
terraform state mv aws_instance.old_name aws_instance.new_nameNow, terraform plan will show zero changes!
If you deleted a resource manually in the AWS Console (which you shouldn't do!), you can remove it from Terraform's memory so it doesn't try to manage it anymore:
terraform state rm aws_instance.broken_serverThe Danger of Local State
By default, terraform.tfstate is saved on your local computer's hard drive.
This is a massive problem for teams:
- Developer A runs
terraform applyand generates a state file on their laptop. - Developer B joins the team, pulls the code from Git, and runs
terraform apply. - Because Developer B doesn't have Developer A's local state file, Terraform thinks nothing exists.
- Developer B's Terraform attempts to recreate everything from scratch, causing massive errors or duplicate infrastructure.
Furthermore, state files often contain plain-text secrets (like database passwords or API keys) generated during the apply phase. Checking terraform.tfstate into Git is a massive security risk!
You must ALWAYS add *.tfstate and *.tfstate.backup to your .gitignore file. Never commit state to a git repository.
The Solution: In a team setting, you must use Remote State, which we will cover in the next tutorial.