State: Terraform’s memory

How Terraform tracks what it manages.

Beginner14 min · lesson 3 of 15

State is the single most important — and most misunderstood — concept in Terraform. When Terraform creates resources it records what it made in a state file (terraform.tfstate), a JSON map linking each resource in your code to the real resource’s ID in the cloud. That is how, on the next run, it knows the aws_instance.web in your code is that specific EC2 instance from last time — so it can decide to change it, leave it, or (if you removed it from code) destroy it. Without state, Terraform would have no memory of what it manages.

What state connects
1your code
aws_instance.web
2state
maps code → real ID
3real resource
i-0abc123 in the cloud
4plan
code vs state vs reality = the diff
Each run: read state, refresh from the real API, compare to your code, plan the difference. State is the memory.

Why state must be handled carefully

Two facts make state a serious topic. First, it can contain sensitive data — database passwords, private keys, and other attributes are stored in plaintext, so the state file is as sensitive as the secrets inside it. Second, if state is lost or corrupted, Terraform forgets what it manages and may try to recreate resources that already exist, causing conflicts and duplicates. So state must be stored safely, backed up, and — for teams — shared and locked, which the remote-state lesson covers.

Inspecting state

You rarely edit state by hand, but you inspect it constantly. terraform state list shows every resource Terraform tracks; terraform state show <addr> shows one resource’s recorded attributes. When Terraform proposes a change you do not understand, comparing your code against state show for that resource usually reveals why — state is the ground truth of what Terraform believes exists.

terminal
$ terraform state list
aws_security_group.web_sg
aws_instance.web
$ terraform state show aws_instance.web | head
# aws_instance.web:
resource "aws_instance" "web" {
id = "i-0abc123def456" # the real resource this code maps to
instance_type = "t3.micro"
}
Never commit terraform.tfstate to Git
The state file holds plaintext secrets and is machine-generated — committing it leaks those secrets to everyone with repo access and causes conflicts when two people run Terraform. Add terraform.tfstate to .gitignore, and for anything beyond a solo experiment use a remote backend that stores state securely, encrypts it, and locks it. Treat the state file with the same care as the credentials it contains.