hashicorp/terraform
Data models
The on-disk artifacts Terraform produces and consumes. All formats are versioned; backward compatibility is a design constraint.
State file (terraform.tfstate)
Versioned JSON, currently version 4. Defined by internal/states/statefile/.
Top-level shape:
{
"version": 4,
"terraform_version": "1.16.0",
"serial": 13,
"lineage": "abcdef12-3456-7890-abcd-ef1234567890",
"outputs": {
"instance_ip": {
"value": "10.0.0.1",
"type": "string",
"sensitive": false,
},
},
"resources": [
{
"module": "module.web",
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
/* schema-shaped JSON */
},
"sensitive_attributes": [],
"private": "<base64>",
"dependencies": ["aws_security_group.web"],
"create_before_destroy": false,
"identity_schema_version": 0,
"identity": {
/* identity-schema-shaped JSON */
},
},
],
},
],
"check_results": [
/* ... */
],
}Field notes:
serialincrements on every write. Remote state managers use it to detect concurrent writes.lineageis a UUID generated at first write. Mismatch indicates "different state on the other end" and aborts writes.modeismanagedforresourceblocks,datafordatablocks,ephemeralfor ephemeral resources,listfor the new list-resource type.provideris the fulladdrs.AbsProviderConfigstring form.attributesfollows the shape of the provider's resource schema at the version recorded inschema_version. The provider'sUpgradeResourceStateis called to migrate when the schema version is older than the provider's current version.sensitive_attributesis a list of attribute paths (e.g.[".password"]) marked sensitive — re-applied asctymarks at load time.identityandidentity_schema_versionare 1.16+ — provider-assigned stable identifiers.dependenciesis the list of resource addresses this instance refers to. The walker uses it for destroy-time ordering when the configuration is no longer present.
Older state file versions live in version1.go, version2.go, version3.go. The upgrade.go machinery chains them: a v1 file is upgraded to v2, then v3, then v4, in memory. Writes only emit v4.
Plan file (<output> from terraform plan -out=...)
A zip archive defined by internal/plans/planfile/. Contents:
| Path inside zip | Contents |
|---|---|
tfplan |
Protobuf-encoded plan (schema in internal/plans/planproto/). |
tfstate |
Prior state at plan time, in the v4 format. |
dependency-lock.hcl |
Snapshot of .terraform.lock.hcl so apply uses the same provider versions. |
Multiple files under terraform-config/ |
Tar-archived configuration. |
The plan file is self-contained: terraform apply <planfile> works without re-reading the user's .tf files. This is a deliberate property — planfiles are often produced on one machine (CI) and applied on another (a deployment runner).
The protobuf schema is reasonably stable but not as locked-down as the state schema. Plans are short-lived (typically minutes to hours), so newer Terraform versions don't always read older plans. Errors in this case point users to re-running terraform plan.
Dependency lock file (.terraform.lock.hcl)
HCL-formatted, defined by internal/depsfile/. One block per provider:
provider "registry.terraform.io/hashicorp/aws" {
version = "5.42.0"
constraints = "~> 5.0"
hashes = [
"h1:abc...",
"zh:def...",
"256colon:1234..."
]
}Fields:
version— the versionterraform initselected.constraints— the version constraints fromrequired_providers.hashes— one or more package hashes used for verification on subsequent runs.
Hash formats:
h1:— base64 of SHA256 of the package contents (canonical).zh:— SHA256 of the entire zip archive (used by some sources).256colon:— colon-separated hex SHA256 (used by some mirrors).
A given provider can have multiple hashes — typically one per platform — so the lock file can be portable across operating systems. The terraform providers lock subcommand adds platform-specific hashes.
JSON output formats (the -json outputs)
These are public APIs. Their schemas are defined in:
internal/command/jsonplan/—terraform show -json <plan>output.internal/command/jsonstate/—terraform show -json(no args) output.internal/command/jsonconfig/— configuration as JSON, included injsonplan.internal/command/jsonchecks/— pre/postcondition / check-block results.internal/command/jsonprovider/—terraform providers schema -jsonoutput.internal/command/jsonfunction/—terraform metadata functions -jsonoutput.internal/command/jsonformat/— the structural diff renderer used byplanoutput (consumesjsonplan).
Each package defines a top-level MarshalForFoo(...) function plus a stable struct schema. The format_version field in each output is bumped when the structure changes incompatibly; consumers should branch on it.
Module manifest (.terraform/modules/modules.json)
Format owned by internal/modsdir/. One entry per installed module instance:
{
"Modules": [
{
"Key": "",
"Source": "",
"Dir": ".",
},
{
"Key": "web",
"Source": "./modules/web",
"Dir": "modules/web",
},
{
"Key": "web.network",
"Source": "../shared/network",
"Dir": ".terraform/modules/web.network",
},
],
}Used by internal/configs/configload.Loader to translate from module.<name>.<sub> references to on-disk paths without re-running module installation.
Workspace marker (.terraform/environment)
A plain text file containing the selected workspace name. Used by the local backend; remote backends manage their own workspace state internally.
CLI configuration (~/.terraformrc)
See configuration. Format owned by internal/command/cliconfig/.
What's not a stable format
internal/stacks/tfstackdata1/— internal protobuf for stack plans/states. The README explicitly states this is internal; clients must use the rpcapi.- The
crash.logformat produced byinternal/logging/panic.go— Go's default panic dump, not a stable schema. - Internal log line formats (
[TRACE] ...) — for human consumption only.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.