liveBook · Manning

Terraform state file

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

A file containing Terraform's persisted representation of managed infrastructure and configuration state.

Suppose you rename a Terraform resource but want to keep the infrastructure it already created. Terraform needs a reliable link between the name in your configuration and the real object. State preserves that link, along with metadata about the resources Terraform manages. Terraform refreshes state during planning and uses it to decide what must change. Each deployment has its own state, stored through a backend. section 6.5 section 6.1.1 section 6.0 section 1.2

With the local backend, the state file is readable JSON, normally named terraform.tfstate. Its main parts are:

  • version and terraform_version identify the state format and the Terraform version that wrote it. serial increases when state changes; lineage identifies a particular state across its history. section 6.3.1
  • resources records managed resources and data sources, including their module, type, name, provider, instances, and attributes. These entries connect configured objects to what Terraform tracks. section 6.3.4
  • outputs stores root-module outputs, not every child-module output. State also stores results of configured checks. section 6.3.4
Listing 6.3 Terraform state as JSON
{
  "version": 4,                                                   #1
  "terraform_version": "1.5.4",                                   #2
  "serial": 6,                                                    #3
  "lineage": "7490ef49-8634-ac56-596b-6f2f4259bece",              #4
  "outputs": {                                                    #5
    "password": {
      "value": "[-Cz\u003em@XQnZc",
      "type": "string",
      "sensitive": true
    }
  },
  "resources": [                                                  #6
    {
      "module": "module.my_password",
      "mode": "data",
      "type": "null_data_source",
      "name": "values",
      "provider": "provider[\"registry.terraform.io/hashicorp/null\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "has_computed_default": "default",
            "id": "static",
            "inputs": null,
            "outputs": null,
            "random": "1249756966943803081"
          },
          "sensitive_attributes": []
        }
      ]
    },
    {
      "module": "module.my_password",
      "mode": "managed",
      "type": "random_password",
      "name": "new_password",
      "provider": "provider[\"registry.terraform.io/hashicorp/random\"]",
      "instances": [
        {
          "schema_version": 3,
          "attributes": {
            "bcrypt_hash": "$2a$10$DxQHHtRQY9.I.vGpLGLjV..
c9pbvfh2vFDax0OFRag1TN4Om44t0.",
            "id": "none",
            "keepers": null,
            "length": 12,
            "lower": true,
            "min_lower": 0,
            "min_numeric": 0,
            "min_special": 0,
            "min_upper": 0,
            "number": true,
            "numeric": true,
            "override_special": null,
            "result": "[-Cz\u003em@XQnZc",                        #7
            "special": true,
            "upper": true
          },
          "sensitive_attributes": []                              #8
        }
      ]
    }
  ],
  "check_results": [                                              #9
    {
      "object_kind": "check",
      "config_addr": "module.my_password.check.password_strength",
      "status": "pass",
      "objects": [
        {
          "object_addr": "module.my_password.check.password_strength",
          "status": "pass"
        }
      ]
    }
  ]
}
#1 This version is for the state data structure itself.
#2 This is the version of Terraform that generated this file.
#3 The serial is the version of the file itself. This is the sixth state file version for the project.
#4 The lineage is a UUID created when the project is initialized for the first time. The lineage should never change.
#5 Outputs are from the root-level module. The output from our child module is not included.
#6 Every resource and data source in the project will have an associated object here.
#7 This value was generated by the resource itself.
#8 In theory, the result should have been flagged, but the sensitive_attributes field does not appear to be used anymore.
#9 Results from check block are stored in state.

The JSON listing shows serial and lineage beside a child-module resource and a root output. Notice that a value marked sensitive still has a value in the state representation. section 6.3.1

Create and inspect a local state file

A child module creates a random_password resource and exposes a sensitive password output. With the local backend, run terraform init and then terraform apply; Terraform writes terraform.tfstate. Inspect its resources to find the child-module entry, and its outputs to find the root output. This example needs no provider authentication because the random resource exists only in state. section 6.3.1 section 6.3.4

Treat state as operational data, not a file to edit routinely. Losing or corrupting it can prevent an upgrade plan or make Terraform plan to create resources again; recovery may require importing existing resources. For shared deployments, choose a centralized backend with restricted access, access logging, encryption, locking, and tested backups. Locking matters because concurrent changes can corrupt state. Use Terraform’s state tools or configuration-based changes when you need to change what Terraform tracks without changing the infrastructure itself. section 6.2.1 section 6.4.2 section 6.5

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Explains the local JSON layout, identifiers, resources, outputs, and checks, then gives backend safeguards without detailing each backend’s configuration.
Examples
Uses a locally stored JSON state file generated by a child-module random_password resource and a sensitive root output.
What it assumes
Assumes basic Terraform configuration and commands while introducing the state file’s fields through a single-resource example.
What you can do after
Operate/configure it by inspecting state, choosing protective backend settings, and using Terraform tools rather than routinely editing state directly.
How it connects
Connects state to workspaces, backends, resource graphs, plans, root-module outputs, and state drift.

Also explained in

Compare how 2 books explain Terraform state file →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.