Terraform Guide

Terraform state: what it tells you, and the four things it does not

By the engineer who builds Datadef, from client work on data platforms · Reviewed August 21, 2026

Terraform state is a JSON index mapping the addresses in your configuration to real resource ids, with a cache of attributes so that plan can diff without querying everything. That is its entire job, and it does it well. The trouble starts when teams treat it as the record of their architecture, because four categories of truth are simply not in there.

6 min readFor teams deciding whether their diagrams should come from state or from code

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

132/20003 credits left
Try:

No account needed · Editable canvas, not a picture

What state is actually for

State exists so that terraform plan can be fast and correct. It records which real resource corresponds to which configuration address, remembers attributes that would otherwise require a round trip to the provider, and tracks the dependency order needed to destroy things safely. Every one of those is an operational concern at apply time.

Note what that implies: state is written by apply. It describes a moment when Terraform last ran, which is not the same as now and not the same as what the repository currently says.

The four blind spots

Intent. State has no idea why the storage module was split out of the platform module, why one environment uses a premium SKU, or which convention is deliberate. Those are decisions, and they only exist in prose that someone wrote or did not.

Unmanaged resources. Terraform cannot detect drift on things it does not manage. A bucket created by hand, a DNS record from before the repo existed, a policy owned by another team: all invisible in state, and all part of the real architecture. This is the blind spot that bites during incidents.

Shape. State is a flat list of resource instances. The module structure that a reader relies on to make sense of a platform survives only as an address prefix, and none of the semantic grouping, boundaries, or flows that make a diagram legible are recorded at all.

The near future. A merged pull request that has not been applied yet does not exist in state, while it very much exists in the repository and in the plan for next Tuesday. Documentation generated from state is documentation of the last apply.

STATE ANSWERS                       SOURCE ANSWERS
which real id backs this address    what resources exist and of what type
what did apply last produce         how modules are bounded and wired
is the cloud drifting from code     what differs between environments
destroy ordering                    what a merged change will create

STATE ALSO CONTAINS                 SOURCE CONTAINS
real ids, endpoints, and any        only what a person wrote: no
value marked sensitive, stored      provider-written attribute, and
in the clear                        nothing needing cloud access

Use each one for what it is good at

For drift detection, state and plan are the right tools, and nothing else can do the job: only a diff against the real cloud tells you someone resized an instance by hand. Keep that loop.

For architecture, read the source. It is authoritative by definition, since it is what apply will make true, and it carries the module boundaries, the references, and the per-environment values that state flattens away. Datadef parses the .tf and .tfvars files of the connected repository and never touches state, init, or your cloud account, which also removes a security conversation. HashiCorp is direct about why it exists: state and plan files hold resource attributes and metadata that can contain sensitive values such as initial database passwords or API tokens, and anything marked sensitive is written to both files in the clear. That reasoning is unpacked in diagrams without state or init.

Concretely, one parse of the source produces two artifacts that state cannot: a diagram whose node identities are Terraform addresses, and a module reference table listing every module with its source and its resource count, where a registry module reads external because its contents are not in your repository. Neither needs a credential that could reach the cloud.

The two answer different questions, and a team that runs both knows when the cloud disagrees with the code and what the code says the architecture is. The failure is picking one and expecting it to cover the other.

FAQ

Does Terraform state show my architecture?

Not in a usable form. State is a flat index of resource instances mapped to real ids, with no module semantics, boundaries, or flows preserved for a reader. It answers what apply last created, which is a different question from how the system is organized.

Can Terraform detect resources created outside Terraform?

No. Terraform only reconciles what it manages, so anything created by hand, by another team, or by another tool is invisible to plan and to state. Those resources have to be documented separately or imported before Terraform can see them.

Is it safe to give a diagramming tool my Terraform state file?

It deserves a security review. State contains real resource ids, endpoints, and attributes that some providers persist in clear text, including values a team would treat as secrets. Source parsing avoids the question entirely because .tf files contain no credentials.

Should an architecture diagram come from state or from code?

From code. The source declares every resource, module, and reference that apply will create, keeps the module structure that makes a diagram readable, and reflects merged changes before they are applied. State reflects the last apply and flattens the structure.

What does state tell you that the source cannot?

Runtime facts. The real ids and endpoints of provisioned resources, the attributes a provider computed rather than a person wrote, whether the last apply succeeded, and whether the cloud has since drifted from the configuration. Those are operational questions, and they are exactly where plan and state remain irreplaceable. Nothing derived from source files can answer any of them.