CoursesInfrastructure as Code & automationBeginner · Terraform basics

State: the heart of Terraform

How Terraform tracks reality.

Beginner14 min · lesson 5 of 23

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. This is how Terraform knows, on the next run, that the aws_instance.web in your code is that specific EC2 instance it created last time — so it can decide whether 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 file
maps code → real ID
3real resource
i-0abc123 in the cloud
4plan
code vs state vs reality = the diff
On each run: read state, refresh from the real API, compare to your code, and plan the difference. State is Terraform’s memory.

Why state must be handled carefully

Two facts make state a serious topic. First, state can contain sensitive data — database passwords, private keys, and other resource attributes are stored in it 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 is exactly what the remote-state lesson covers.

Inspecting state

You rarely edit state by hand, but you do inspect it. terraform state list shows every resource Terraform is tracking; terraform state show <addr> shows the recorded attributes of one; and terraform show displays the whole state. When Terraform proposes a change you do not understand, comparing your code against terraform 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 contains plaintext secrets and is frequently large and machine-generated — committing it to a repository 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 (next intermediate section) that stores state securely, encrypts it, and locks it so two applies cannot corrupt it. Treat the state file with the same care as the credentials it contains.