Post

Understanding Terraform: Desired State vs. Actual State

Understanding Terraform: Desired State vs. Actual State

Introduction

Imagine you’re building with LEGO blocks. You have a picture of what you want to build (a castle), and you start putting blocks together. The picture is your desired state, and what you’ve built so far is your actual state.

Terraform works just like that, but with cloud resources instead of LEGO blocks!

What is Desired State?

Desired state is like your wish list or blueprint. It’s what you want your infrastructure to look like.

In Terraform, you write this wish list in files ending with .tf. These files use a language called HCL (HashiCorp Configuration Language) to describe what you want.

For example, if you want a toy box (a virtual machine), you might write:

1
2
3
4
5
6
7
resource "aws_instance" "my_toy_box" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "MyToyBox"
  }
}

This is saying: “I want a toy box called ‘MyToyBox’, this size, with these features.”

What is Actual State?

Actual state is what you actually have right now. It’s what exists in the real world (or cloud).

Terraform keeps track of what it has created in a special file called the state file (usually named terraform.tfstate). This is like Terraform’s memory of what it has built so far.

How Terraform Compares Desired and Actual State

When you run Terraform, it does something very clever:

  1. It looks at your .tf files to understand your desired state
  2. It looks at the actual state (either from the state file or by checking the cloud directly)
  3. It figures out what needs to change to make the actual state match the desired state

This process is like looking at your LEGO castle picture, looking at what you’ve built so far, and figuring out what LEGO pieces you need to add or remove.

Terraform Commands for Managing State

1. terraform init

This is like getting your LEGO pieces ready before you start building.

1
terraform init

This command prepares Terraform to work with your configuration. It downloads any providers (like AWS, Azure, or Google Cloud) that you’ll need.

2. terraform plan

This is like looking at your LEGO instructions and figuring out what steps you need to take.

1
terraform plan

This command compares your desired state with the actual state and shows you what changes Terraform will make. It’s a preview - nothing actually changes yet!

Example output:

1
2
3
4
5
+ aws_instance.my_toy_box
    ami:           "ami-0c55b159cbfafe1f0"
    instance_type: "t2.micro"
    tags.%:        "1"
    tags.Name:     "MyToyBox"

The + means “add something new”. You might also see:

  • - which means “remove something”
  • ~ which means “change something that exists”

3. terraform apply

This is like actually building with your LEGO pieces!

1
terraform apply

This command makes the actual changes needed to match your desired state. Terraform will show you the plan first and ask “Are you sure?” before making any changes.

4. terraform show

This is like looking at what you’ve built so far.

1
terraform show

This shows you the current actual state that Terraform knows about.

5. terraform state list

This shows you a list of all the resources (toys) that Terraform is managing.

1
terraform state list

Example output:

1
aws_instance.my_toy_box

6. terraform refresh

This is like checking if someone moved your LEGO pieces when you weren’t looking.

1
terraform refresh

This updates Terraform’s understanding of the actual state by checking the real resources in the cloud.

A Simple Example: Building a Toy Box

Let’s walk through an example:

Step 1: Write Your Desired State

Create a file called main.tf:

1
2
3
4
5
6
7
8
9
10
11
provider "aws" {
  region = "us-west-2"
}

resource "aws_instance" "my_toy_box" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "MyToyBox"
  }
}

Step 2: Initialize Terraform

1
terraform init

Step 3: See What Will Be Created

1
terraform plan

Terraform will say: “I’m going to create a new toy box called ‘MyToyBox’!”

Step 4: Create the Toy Box

1
terraform apply

Terraform asks: “Are you sure you want me to create this toy box?” You type: yes

Terraform creates the toy box in AWS!

Step 5: Change Your Desired State

Let’s say you want a bigger toy box. Update main.tf:

1
2
3
4
5
6
7
resource "aws_instance" "my_toy_box" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"  # Changed from t2.micro to t3.micro
  tags = {
    Name = "MyToyBox"
  }
}

Step 6: See What Will Change

1
terraform plan

Terraform will say: “I’m going to change your toy box from t2.micro to t3.micro!”

Step 7: Apply the Change

1
terraform apply

Terraform asks: “Are you sure you want me to change your toy box?” You type: yes

Terraform updates the toy box in AWS!

What Happens if Someone Changes Things Outside Terraform?

Imagine your friend goes and moves some of your LEGO pieces without telling you.

If someone changes the actual state directly (like through the AWS console), Terraform might get confused.

For example, if someone manually changes the tag on your toy box to “YourToyBox” instead of “MyToyBox”:

  1. Run terraform plan
  2. Terraform will say: “Hey, someone changed the tag! I’m going to change it back to ‘MyToyBox’!”
  3. When you run terraform apply, Terraform will fix this “drift” and make the actual state match your desired state again.

Working with Teams

When working with a team, you should store your terraform state file remotely so everyone can use the same “memory” of what’s been built.

Add this to your configuration:

1
2
3
4
5
6
7
terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "project/terraform.tfstate"
    region = "us-west-2"
  }
}

This tells Terraform to store its memory (state) in an S3 bucket that everyone can access.

Conclusion

Terraform is like a helpful robot that:

  1. Listens to what you want (desired state in .tf files)
  2. Remembers what it built before (actual state in the state file)
  3. Figures out what steps to take to make reality match your wishes
  4. Makes those changes for you when you say “go ahead”

This approach, called “infrastructure as code,” helps you build and maintain your cloud resources in a predictable, consistent way!

Remember:

  • Desired State = What you want (in .tf files)
  • Actual State = What you have (in reality and tracked in .tfstate)
  • Terraform’s job is to make the actual state match the desired state!
This post is licensed under CC BY 4.0 by the author.