12.2 Inspect State with the CLI
Key Takeaways
- terraform state list prints resource addresses in state; optional address patterns or -id= filter the list
- terraform state show ADDRESS prints one resource's attributes for humans, not for scripts
- terraform show and terraform show -json inspect the whole latest state snapshot or a saved plan file
- terraform output reads root-module outputs from state; -json and -raw are the automation forms
- These inspect commands do not create, update, or destroy infrastructure
12.2 Inspect State with the CLI
Quick Answer:
terraform state listnames what is in state.terraform state show ADDRESSprints one resource for a human.terraform show(optionally-json) prints the whole current state snapshot or a saved plan file.terraform outputprints root-module outputs. None of these commands create, update, or destroy infrastructure.
Objective 7b on Terraform Associate (004) is: use the CLI to inspect state on Terraform 1.12. Chapter 11 already covered backends, locking, and drift operations (state mv, state rm, apply -replace). This section is the read side. If you answer 7b with state rm or import, you picked a mutating command.
Official references: terraform state, terraform state list, terraform state show, terraform show, and terraform output.
Why this objective appears on 004
Operators need to answer "what does Terraform think it owns?" without applying. The exam mixes four similar verbs on purpose: show versus state show, state list versus output, human text versus -json. A candidate who greps terraform.tfstate by hand, or who thinks state show returns the JSON schema, fails 7b.
The inspect toolkit
| Command | Scope | Typical consumer | Changes infrastructure? |
|---|---|---|---|
terraform state list [address...] | Addresses in state (all, or filtered) | Humans, grep, scripts that only need names | No |
terraform state show ADDRESS | One resource instance | Humans at a terminal | No |
terraform show [file] | Entire latest state snapshot, or a state/plan file | Humans reviewing state or a saved plan | No |
terraform show -json [file] | Same, machine-readable | CI, custom tools, documented JSON format | No |
terraform output [NAME] | Root-module outputs stored in state | Humans; -json / -raw for scripts | No |
All terraform state subcommands work with remote state the same way they work with local state. A read still does a network round-trip to the backend. Read-only subcommands (list, show) do not write backup files. Mutating subcommands (mv, rm, replace-provider) always write backups — that is chapter 11, not 7b.
terraform state list
terraform state list aws_instance.web
terraform state list module.elb
terraform state list -id=sg-1234abcd
terraform state show 'aws_instance.web'
terraform state show 'aws_instance.web[0]'
terraform state show 'aws_instance.web["env"]'
terraform state show 'module.foo.aws_instance.web'
terraform show
terraform show tfplan
terraform show -json
terraform show -json tfplan
terraform output
terraform output lb_address
terraform output -json
terraform output -raw lb_address
terraform state list
Usage: terraform state list [options] [address...].
With no addresses, it lists every resource instance in the current state's snapshot, including nested modules. With one or more address patterns, it lists matching instances only. Official sort order: module depth first (root resources, then deeper modules), then alphabetically. That is why aws_instance.foo appears before module.elb.aws_elb.main.
Patterns use resource addressing:
aws_instance.barlists every index (bar[0],bar[1]).module.elblists that module and its submodules.-id=sg-1234abcdlists the instance whose provider ID is that string. Useful when you know the security-group ID from the console and need the Terraform address.
-state=path is a legacy local-backend option. On a configured remote backend, you do not point state list at a random file to "inspect production." You select the workspace / backend that already holds that state.
state list prints addresses, not attribute values. It is the inventory command.
terraform state show versus terraform show
This contrast is the 7b discriminator.
terraform state show ADDRESS requires an address that points to exactly one instance. It prints that instance's attributes in a human-oriented HCL-like dump. HashiCorp states the output is not for programmatic consumption. Do not parse it in CI. Indexed addresses need quoting ('packet_device.worker[0]', 'packet_device.worker["example"]').
terraform show [file] prints a human-readable view of:
- the latest state snapshot, if you pass no path, or
- a state file or a saved plan file, if you pass that path.
Use it to inspect a terraform plan -out=tfplan artifact before terraform apply tfplan (chapter 5). Use it to read "state as Terraform sees it" without opening the raw JSON blob.
terraform show -json is the documented machine-readable path. For state (including the no-path case) it emits the JSON state representation. For a plan file it emits plan + configuration + current state. The schema lives in HashiCorp's JSON output format docs. Official caveats on 1.12:
-jsonprints sensitive values in plaintext. Treat the stream as a secret.- If providers were upgraded to a new schema version since the snapshot was written, upgrade/refresh state before expecting
show -jsonto decode it cleanly. - A plan you want to inspect as JSON should not have been created with
-refresh=false.
flowchart LR
State["Current state snapshot"] --> List["state list<br/>addresses only"]
State --> One["state show ADDRESS<br/>one resource, human text"]
State --> All["show / show -json<br/>whole snapshot"]
PlanFile["Saved plan file"] --> All
State --> Out["output / output -json<br/>root outputs"]
If a question says "print the ami of aws_instance.web for the on-call engineer," the command is terraform state show aws_instance.web. If it says "dump the entire state for an inventory tool" or "inspect the saved plan as JSON," the command is terraform show -json (with a plan path when the subject is the plan). If it says "list every address in module vpc," the command is terraform state list module.vpc.
terraform output
Usage: terraform output [options] [NAME].
Outputs are not the same as resource attributes in state. output reads values Terraform already stored from output blocks in the root module. Child-module outputs appear only if the root re-exports them.
| Invocation | Result |
|---|---|
terraform output | All root outputs, human format; sensitive = true values show as <sensitive> |
terraform output NAME | That one value; sensitive values are not redacted when you name them |
terraform output -json | Stable JSON object (or a single value if NAME is set); sensitive values in plaintext |
terraform output -raw NAME | Bare string/number/bool for shell scripts; not for objects/lists — use -json |
Ephemeral outputs are omitted entirely, even by name. They are never stored in state (objective 4h). -raw is UTF-8 text, not raw bytes.
Human terraform output formatting can change between versions. Automation should use -json (and jq) or -raw for a single primitive. That is the same philosophy as show -json versus state show.
Inspect means do not change infrastructure
7b commands read. They do not add instances, destroy buckets, or rewrite resource bindings.
They may still:
- contact a remote backend to fetch the snapshot,
- print secrets (
show -json,output -json,output -raw,output NAMEfor a sensitive output), - fail if the working directory is not initialized or the backend is unreachable.
They do not refresh remote objects the way terraform plan does. state show prints what is in the snapshot, which can be stale relative to the cloud account. If the question is "did someone change the instance type in the console?," inspection of state is not enough — that is a plan / refresh / drift question (6d). If the question is "what address and attributes does this workspace currently record?," inspection is enough.
Do not confuse inspect with:
terraform state pull— raw state JSON to stdout (useful, but 7b's documented human/JSON pair isshow/show -json).terraform console— expression REPL against configuration + state, not the listed 7b toolkit.terraform apply/import/state rm/state mv— mutations.
Scenario: the Friday incident
On-call Jordan needs the production NAT gateway's Elastic IP without opening the AWS console. The root module exports nat_eip. terraform output -raw nat_eip prints the address for a script. A teammate asks whether aws_nat_gateway.this is even in this workspace. terraform state list aws_nat_gateway.this prints the address (or nothing). To see allocation_id and subnet_id as recorded, Jordan runs terraform state show aws_nat_gateway.this. An inventory job needs the whole snapshot; CI runs terraform show -json and parses the documented structure. Nobody runs apply. Nobody opens terraform.tfstate in an editor.
Later, a saved plan tfplan is waiting for approval. Reviewers run terraform show tfplan, not terraform state show, because a plan is not a single resource address.
004 traps for objective 7b
terraform showis the whole state or a plan file.terraform state showis one address.state showis human text. Programmatic state isterraform show -json.state listlists addresses;outputlists root outputs.-jsonand severaloutputforms reveal sensitive values.- Inspect commands do not refresh or apply.
outputdoes not print child-module outputs unless the root re-exports them.
On Terraform 1.12, how do terraform show and terraform state show differ?
A CI job must read the current workspace state with a stable, documented machine-readable format. Which command does HashiCorp point you to?
Which set of Terraform 1.12 commands inspects state or outputs without creating, updating, or destroying infrastructure?