Terraform state schema

Hi @sc250024,

The state snapshot format is an implementation detail of Terraform and not a public interface intended for external integration. Because Terraform needs to be about to round-trip all of the information it produces from one run to the next, the exact details of these snapshots tend to change slightly between Terraform releases as new features require tracking new data or tracking existing data in a different way.

There is a different JSON format which exposes a subset of the state data in a manner that is suitable for public consumption and subject to the v1.x compatibility promises. You can find the documentation about that format in JSON Output Format; you can run terraform show -json to produce the structure described under “State Representation”.


I can still say a little about the specific details you were wondering about, in case this helps satisfies your curiosity:

Terraform uses “version” to recognize when the current state snapshot is in an earlier version of the format and therefore might need upgrading, or in a later version of the format and would therefore not be safe to read by an earlier version of Terraform (because it might contain information the older version doesn’t understand).

Terraform uses “lineage” and “serial” together as a way to catch situations where two parties are trying to make changes with Terraform in an order that could potentially cause problems

For example:

  • Party A: terraform plan -out=tfplan
  • Party B: terraform plan -out=tfplan
  • Party A: terraform apply tfplan
  • Party B: terraform apply tfplan

When Party B runs the final command, Terraform will notice that the serial in the latest state snapshot is different than the one that was used to create tfplan and so will refuse to apply that stale plan.

“Lineage” deals with a different situation of trying to apply a saved plan to the wrong state altogether. Whenever Terraform creates the first state snapshot for a new configuration or workspace it will generate a new random lineage and record it in that first snapshot. Any subsequent snapshots in the same configuration/workspace will preserve the same lineage and increment snapshot.

Terraform uses these two fields in conjunction with the remote state backend locking mechanisms, so make sure that a correctly-configured Terraform can’t race against another one running on another system to try to update serial at the same time, or to write a snapshot intended for some other configuration/workspace.

What I’ve described here is an implementation detail of current versions of Terraform and not guaranteed to remain true in future versions of Terraform.

1 Like