G
GuideDevOps
Lesson 7 of 14

State Management

Part of the Terraform tutorial series.

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

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 list

Output:

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.web

Safely 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_name

Now, 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_server

The Danger of Local State

By default, terraform.tfstate is saved on your local computer's hard drive.

This is a massive problem for teams:

  1. Developer A runs terraform apply and generates a state file on their laptop.
  2. Developer B joins the team, pulls the code from Git, and runs terraform apply.
  3. Because Developer B doesn't have Developer A's local state file, Terraform thinks nothing exists.
  4. 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!

The Solution: In a team setting, you must use Remote State, which we will cover in the next tutorial.