Study guide
12.2 Inspect State with the CLI
HashiCorp Certified: Terraform Associate 004
Track your progress as you read
Finished sections get a check mark.
1 Introduction & Exam Overview
1.1 Current Exam Facts 1.2 Format, Delivery, Retakes, and Recertification 1.3 004 Changes, Terraform 1.12, and Study Plan
2 Infrastructure as Code with Terraform
2.1 What Infrastructure as Code Is 2.2 Advantages of IaC Patterns 2.3 Multi-Cloud, Hybrid, and Service-Agnostic Workflows
3 Terraform Fundamentals: Providers & State
3.1 Install and Version Terraform Providers 3.2 How Terraform Uses Providers 3.3 Configuration with Multiple Providers 3.4 How Terraform Uses and Manages State
4 Core Terraform Workflow: Init & Validate
4.1 The Terraform Write–Plan–Apply Workflow 4.2 Initialize a Working Directory 4.3 Validate a Configuration
5 Plan, Apply, Destroy, and Formatting
5.1 Generate and Review an Execution Plan 5.2 Apply Changes to Infrastructure 5.3 Destroy Terraform-Managed Infrastructure 5.4 Formatting and Style Adjustments
6 Resources, Data Sources, and References
6.1 Resource Blocks vs Data Blocks 6.2 Resource Attributes and Cross-Resource References 6.3 Resource Addressing and Interpolation Patterns
7 Variables, Outputs, and Complex Types
7.1 Input Variables, tfvars, and Precedence 7.2 Output Values 7.3 Complex Types: list, map, object, tuple, set
8 Dynamic Configuration and Dependencies
8.1 Expressions, count, for_each, and dynamic Blocks 8.2 Built-in Functions 8.3 Dependencies, depends_on, and Lifecycle Rules
9 Conditions, Secrets, and Sensitive Data
9.1 Custom Conditions: validation, precondition, postcondition, check 9.2 Sensitive Data Handling 9.3 Vault, Ephemeral Values, and Write-Only Arguments
10 Terraform Modules
10.1 How Terraform Sources Modules 10.2 Variable Scope within Modules 10.3 Using Modules in Configuration 10.4 Managing Module Versions
11 Terraform State Management
11.1 The Local Backend 11.2 State Locking 11.3 Remote State and the backend Block 11.4 Resource Drift and State Operations
12 Maintain Infrastructure with Terraform
12.1 Import Existing Infrastructure 12.2 Inspect State with the CLI 12.3 Verbose Logging and Diagnostics
13 HCP Terraform
13.1 Create Infrastructure with HCP Terraform 13.2 Collaboration and Governance Features 13.3 Workspaces and Projects 13.4 HCP Terraform Integrations
12.2 Inspect State with the CLI
Key Takeaways Explain This Topic AI
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
- Last updated: August 2026
12.2 Inspect State with the CLI
Quick Answer: terraform state list names what is in state. terraform state show ADDRESS prints one resource for a human. terraform show (optionally -json ) prints the whole current state snapshot or a saved plan file. terraform output prints 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.bar lists every index ( bar[0] , bar[1] ).
module.elb lists that module and its submodules.
-id=sg-1234abcd lists 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:
-json prints 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 -json to decode it cleanly.
A plan you want to inspect as JSON should not have been created with -refresh=false .
Loading diagram...
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 NAME for 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 is show / 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 show is the whole state or a plan file. terraform state show is one address.
state show is human text. Programmatic state is terraform show -json .
state list lists addresses; output lists root outputs.
-json and several output forms reveal sensitive values.
Inspect commands do not refresh or apply.
output does not print child-module outputs unless the root re-exports them.