Terraform State Management

LinuxBeginner
Practice Now

Introduction

Terraform uses a state file to store information about the infrastructure it manages. This state file is crucial as it maps the resources defined in your configuration files to the real-world resources. By maintaining this state, Terraform can determine which resources to create, update, or destroy.

In this lab, you will get hands-on experience with managing Terraform's state. You will learn how to use various terraform state subcommands to inspect the current state, list managed resources, rename a resource within the state, and refresh the state to align it with the actual infrastructure. These are fundamental skills for any Terraform user.

View current state with terraform show

In this step, you will learn how to view the current state using the terraform show command. This command provides a human-readable output of the resources currently managed by Terraform, as recorded in the state file. It's a safe, read-only way to inspect your infrastructure's state.

The setup script for this lab has already initialized Terraform and created a resource, generating a terraform.tfstate file. Let's inspect it.

Run the following command in your terminal:

terraform show

You will see a detailed output describing the local_file resource that Terraform is managing.

## local_file.example:
resource "local_file" "example" {
    content              = "This is an example file managed by Terraform."
    content_base64sha256 = "F5EYZhFNzSXdE4CUftwQoDVqvdiufZpVyiLMqyZVOcQ="
    content_base64sha512 = "m1hvaxMuc/EhaKintyI54NSTTJ5yXpqHPCBNoHubF0rvF3JAj36lMj20aPcv21+3/OK+SqkiTlnT/LdvLCwqDA=="
    content_md5          = "a43bdd236c2f0f4d87452ba2ef0867e4"
    content_sha1         = "ec3adcab998872def2df6200fb03992ac6f237a4"
    content_sha256       = "17911866114dcd25dd1380947edc10a0356abdd8ae7d9a55ca22ccab265539c4"
    content_sha512       = "9b586f6b132e73f12168a8a7b72239e0d4934c9e725e9a873c204da07b9b174aef1772408f7ea5323db468f72fdb5fb7fce2be4aa9224e59d3fcb76f2c2c2a0c"
    directory_permission = "0777"
    file_permission      = "0777"
    filename             = "./example.txt"
    id                   = "ec3adcab998872def2df6200fb03992ac6f237a4"
}

This output confirms that Terraform is aware of one resource, local_file.example, and lists all of its attributes.

Inspect state file terraform.tfstate

In this step, you will inspect the raw state file, terraform.tfstate. While terraform show provides a user-friendly view, looking at the raw JSON file helps you understand how Terraform stores data.

Warning: You should almost never edit the terraform.tfstate file manually. Incorrect modifications can corrupt your state and lead to serious issues. We are only viewing it for educational purposes.

Use the cat command to display the contents of the state file:

cat terraform.tfstate

The output will be a JSON object. It contains metadata like the Terraform version and, most importantly, an array of resources.

{
  "version": 4,
  "terraform_version": "1.13.3",
  "serial": 1,
  "lineage": "2a568739-a81d-ced7-dee1-7a92a1666022",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "local_file",
      "name": "example",
      "provider": "provider[\"registry.terraform.io/hashicorp/local\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "content": "This is an example file managed by Terraform.",
            "content_base64sha256": "...",
            "content_base64sha512": "...",
            "content_md5": "...",
            "content_sha1": "...",
            "content_sha256": "...",
            "content_sha512": "...",
            "directory_permission": "0777",
            "file_permission": "0777",
            "filename": "./example.txt",
            "id": "ec3adcab998872def2df6200fb03992ac6f237a4",
            "sensitive_content": null,
            "source": null
          },
          "sensitive_attributes": [
            [
              {
                "type": "get_attr",
                "value": "sensitive_content"
              }
            ]
          ],
          "identity_schema_version": 0
        }
      ]
    }
  ],
  "check_results": null
}

This raw data is what Terraform uses to create execution plans.

Run terraform state list to list resources

In this step, you will use terraform state list to get a concise list of all resources in the state. When your infrastructure grows and you have dozens or hundreds of resources, terraform show can be too verbose. The state list command provides a simple, newline-separated list of resource addresses.

Execute the command in your terminal:

terraform state list

The output will be very straightforward, showing just the address of the resource we created.

local_file.example

This command is extremely useful for scripting or for quickly identifying a specific resource's address when you need to target it with other commands.

Use terraform state mv to rename resource

In this step, you will learn how to rename a resource in the state file using terraform state mv. This is a common task when refactoring your Terraform code. If you rename a resource block in your .tf file, Terraform will think you want to destroy the old resource and create a new one. The state mv command allows you to update the state file to match your code changes, preventing unnecessary destruction and creation.

First, let's rename the resource in our configuration file. Open main.tf with the nano editor:

nano main.tf

Change the resource name from example to example_renamed. The file should look like this:

resource "local_file" "example_renamed" {
  content  = "This is an example file managed by Terraform."
  filename = "${path.module}/example.txt"
}

Press Ctrl+X, then Y, and Enter to save and exit.

Now, run terraform plan to see what Terraform intends to do:

terraform plan

The plan will show that Terraform wants to destroy local_file.example and create local_file.example_renamed, which is not what we want.

local_file.example: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  ## local_file.example will be destroyed
  ## (because local_file.example is not in configuration)
  - resource "local_file" "example" {
      - content              = "This is an example file managed by Terraform." -> null
      - content_base64sha256 = "F5EYZhFNzSXdE4CUftwQoDVqvdiufZpVyiLMqyZVOcQ=" -> null
      - content_base64sha512 = "m1hvaxMuc/EhaKintyI54NSTTJ5yXpqHPCBNoHubF0rvF3JAj36lMj20aPcv21+3/OK+SqkiTlnT/LdvLCwqDA==" -> null
      - content_md5          = "a43bdd236c2f0f4d87452ba2ef0867e4" -> null
      - content_sha1         = "ec3adcab998872def2df6200fb03992ac6f237a4" -> null
      - content_sha256       = "17911866114dcd25dd1380947edc10a0356abdd8ae7d9a55ca22ccab265539c4" -> null
      - content_sha512       = "9b586f6b132e73f12168a8a7b72239e0d4934c9e725e9a873c204da07b9b174aef1772408f7ea5323db468f72fdb5fb7fce2be4aa9224e59d3fcb76f2c2c2a0c" -> null
      - directory_permission = "0777" -> null
      - file_permission      = "0777" -> null
      - filename             = "./example.txt" -> null
      - id                   = "ec3adcab998872def2df6200fb03992ac6f237a4" -> null
    }

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

To fix this, we'll tell Terraform that we've simply moved the resource. Run the terraform state mv command with the old address and the new address:

terraform state mv local_file.example local_file.example_renamed

You will see a confirmation message:

Move "local_file.example" to "local_file.example_renamed"
Successfully moved 1 object(s).

Now, run terraform plan again:

terraform plan

This time, Terraform reports that no changes are needed because the state now matches the configuration.

local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Run terraform refresh to update state

In this step, you will use terraform refresh to reconcile the state file with the real-world infrastructure. Sometimes, changes are made to your infrastructure outside of Terraform's control. This is known as "drift." The refresh command updates the state file to reflect these changes.

Let's simulate drift by manually deleting the file that Terraform created.

rm example.txt

Now, if you run a plan, Terraform will detect that the file is missing and needs to be recreated.

terraform plan
local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

However, the terraform refresh command can also be used to explicitly refresh the state. This command checks the actual resources and updates the state file accordingly.

terraform refresh
local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Now run terraform plan again to confirm the state is up to date.

terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

You have successfully used terraform refresh to correct state drift.

Summary

Congratulations on completing this lab on Terraform State Management!

In this lab, you gained practical experience with essential terraform state subcommands. You learned how to:

  • Use terraform show to view a human-readable representation of your infrastructure's state.
  • Inspect the raw terraform.tfstate JSON file to understand its structure.
  • Get a clean list of all managed resources with terraform state list.
  • Safely rename a resource in your configuration and update the state accordingly using terraform state mv.
  • Reconcile your state file with real-world infrastructure and correct drift using terraform refresh.

Mastering these commands is fundamental to managing your infrastructure effectively and confidently with Terraform.