Terraform Essentials — Plan and Apply, Variables, Outputs, Data Sources, and Sharing State at Scale
Plan and apply, saved and stale plans, variables, outputs and data sources as the Terraform docs define them. Why terraform_remote_state fails at scale and the documented alternatives.
Overview
Most Terraform incidents are not provider bugs. They are a plan that was reviewed against one state and applied against another, a variable that came from a file nobody meant to load, a secret that was marked sensitive and still ended up readable in state, or a downstream configuration that broke because an upstream team renamed an output. This page covers the core building blocks (plan, apply, variables, locals, outputs, data sources) exactly as the Terraform documentation defines them, then the scaling problem every growing platform team hits: sharing values between many configurations with terraform_remote_state.
The one idea to keep: state is a single document. The terraform_remote_state documentation warns that anyone who can read a configuration's root module outputs can also read its full state snapshot. Everything about how mature setups share data follows from that, plus the coupling it creates.
Symptom to first command
- Apply fails with Saved plan is stale — terraform plan -out=tfplan again, then terraform apply tfplan — Plan and apply
- Plan shows changes nobody made in code — terraform plan -refresh-only — Plan and apply
- A variable has a value you did not expect — terraform plan -var-file=prod.tfvars with no auto-loaded files present — Variables and precedence
- Output refers to sensitive values — Add sensitive = true to the output block — Outputs and sensitive values
- A secret shows in plain text in CI logs — Check for terraform output -json or terraform show -json in the pipeline — Outputs and sensitive values
- A data source attribute shows as known after apply — Check for depends_on or a reference to a resource changing in this plan — Data sources versus resources
- Consumer plan fails with Unsupported attribute on outputs — terraform output in the producer configuration — Sharing state at scale
- Plan wants to destroy production — terraform workspace show and check the backend config — Mistakes
What you will be able to do
- Explain what terraform plan and terraform apply each do, and run them safely in CI with a saved plan file.
- Recite the documented variable precedence order and find where an unexpected value came from.
- Say precisely what sensitive = true hides and what it does not (state, plan files, -json output).
- Contrast a data source with a resource, and say when Terraform reads a data source during apply instead of plan.
- Explain why terraform_remote_state fails at scale (full state access, tight coupling, no ordering, brittle outputs) and name the documented alternatives: provider data sources, a parameter store or key/value store, tfe_outputs, run triggers and Stacks.
- Recover from and prevent the common mistakes: wrong variable file, wrong workspace, leaked secrets, accidental destroys.
Key concepts
- Saved plan
- A plan written with -out=FILE and applied with terraform apply FILE. Applying it needs no prompt and accepts no planning options; it is rejected if the state serial changed since planning.
- Lineage and serial
- Metadata in each state snapshot. A saved plan records both; apply refuses a plan whose serial (stale) or lineage (different state) no longer matches.
- Refresh-only mode
- A plan or apply that only updates state and root outputs to match changes made outside Terraform. Replaces the deprecated terraform refresh command.
- Variable precedence
- Command line -var and -var-file plus HCP Terraform variables, then *.auto.tfvars, terraform.tfvars.json, terraform.tfvars, TF_VAR_ environment variables, then the default.
- Sensitive
- Redacts a variable or output in CLI output. The value is still stored in state and plan files, and -json or -raw output shows it.
- Ephemeral value
- A variable, child module output or ephemeral block value (Terraform 1.10+) that Terraform omits from state and plan files.
- Data source
- A data block that reads information through a provider without creating or changing anything. Read during plan unless it depends on changes in the same plan.
- terraform_remote_state
- Built-in data source that reads another configuration's root module outputs from its backend; reading it requires access to the whole state snapshot.
- tfe_outputs
- tfe provider data source that reads an HCP Terraform workspace's outputs, with values (sensitive) and nonsensitive_values, without full state access.
- Run trigger
- HCP Terraform link that queues a run in a target workspace after a successful apply in a source workspace; up to 20 sources per workspace.
When to use it
- You are preparing for a DevOps, SRE or platform interview that includes Terraform fundamentals.
- Your CI pipeline runs plan and apply in separate jobs and you need the saved plan workflow to be safe.
- Several Terraform configurations share values and you are deciding between terraform_remote_state, data sources, a parameter store, tfe_outputs or Stacks.
- A secret appeared in a log or state file and you need to know what sensitive does and does not protect.
- A plan proposed something unexpected and you need to trace which variable source or data source caused it.
Interview questions
- Explain the actual failure mode of using terraform_remote_state data source to share outputs between many terraform configurations at scale and what you'd use instead in a mature setup
- What's a data source in Terraform, how is it different from a resource block
- Difference between terraform plan and terraform apply
- Purpose of variables and output blocks in terraform
- What does terraform plan -refresh-only do, and why was terraform refresh deprecated?
- A variable marked sensitive still leaked. Where can a sensitive value still appear, and how do you keep it out?
- A variable has a value you did not expect in production. How do you find where it came from?
- How do you run plan and apply safely in a CI/CD pipeline?
- When does Terraform read a data source during apply instead of plan, and what does depends_on do to it?
- Two HCP Terraform workspaces must share a value, and the consumer must update when the producer changes. How do you set it up?
Sign up free to read the full topic
More DevOps topics
Start free on Cariara · Coding problems · System design studio