English for Terraform Developers
Master the vocabulary for discussing state, modules, plans, and drift when managing infrastructure as code with Terraform.
Terraform conversations lean heavily on a handful of precise terms — state, plan, drift, module — and mixing them up in a review or an incident writeup can genuinely confuse people about what actually happened to the infrastructure. Being exact about this vocabulary matters most when something has gone wrong, since “the deploy broke it” says far less than “the plan showed an unexpected destroy-and-recreate on the production database.”
Key Vocabulary
State (Terraform state) The file (or remote backend) where Terraform records the current known configuration of every resource it manages, used to compute the difference between desired and actual infrastructure. Example: “The plan is showing this resource as needing to be created, even though it already exists — that usually means it’s missing from state rather than missing from the cloud provider.”
Plan The preview Terraform generates before applying changes, showing exactly which resources will be created, modified, or destroyed, and how, without making any actual changes yet. Example: “Always read the plan output carefully before approving — this one shows a destroy-and-recreate on the database, which would cause real downtime if we didn’t catch it here.”
Apply The step where Terraform actually executes the changes shown in a plan, modifying real infrastructure to match the desired configuration. Example: “We’re requiring a manual approval step between plan and apply on production, specifically so a human reviews any destructive changes before they happen.”
Drift (configuration drift) The divergence between what Terraform’s state believes about infrastructure and what actually exists in the cloud provider, often caused by manual changes made outside of Terraform. Example: “Someone changed this security group directly in the console, so we now have drift — Terraform’s state doesn’t reflect the actual rule that’s live in production.”
Module A reusable, self-contained package of Terraform configuration that can be called with different input variables to provision similar infrastructure in multiple places. Example: “Instead of duplicating this VPC configuration across three environments, we extracted it into a module and pass in environment-specific variables.”
Provider The plugin that lets Terraform interact with a specific platform’s API — like AWS, Google Cloud, or Kubernetes — translating resource definitions into actual API calls. Example: “We pinned the provider version explicitly after a minor version bump changed a default value and caused an unexpected diff on every subsequent plan.”
Resource
A single infrastructure object — like a virtual machine, a database instance, or a DNS record — declared in configuration and tracked individually in Terraform’s state.
Example: “This resource block is missing a lifecycle rule to prevent accidental destruction, which is risky for something as critical as the production database.”
Import (state import) The process of bringing an existing piece of infrastructure — created outside Terraform — under Terraform’s management by adding it to state without recreating it. Example: “We imported this manually-created load balancer into state so Terraform manages it going forward, instead of leaving it as an unmanaged exception.”
Common Phrases
In code reviews:
- “This module doesn’t expose a variable for the instance size, so every environment is hardcoded to the same value — can we parameterize that?”
- “We’re missing a
prevent_destroylifecycle rule on this resource, which seems risky given how disruptive accidentally destroying it would be.” - “This provider version isn’t pinned, so a future minor version bump could silently change behavior here without anyone noticing until the next plan.”
In standups:
- “Yesterday I imported the manually-created S3 bucket into Terraform state; today I’m reconciling the drift between its actual configuration and what our module declares.”
- “I’m blocked on a plan that wants to destroy and recreate the production database — I need to figure out why before I can approve applying it.”
- “I finished extracting our networking configuration into a reusable module, so each environment now just passes in its own variables.”
In incident writeups:
- “The plan output clearly showed a destroy-and-recreate on this resource, but it wasn’t reviewed carefully before being applied, which caused the outage.”
- “Configuration drift had accumulated because someone made a manual change directly in the console weeks earlier, and Terraform’s state never reflected it.”
- “We’re adding a mandatory manual review step for any plan containing a destroy action on a stateful resource, to prevent this specific failure mode from recurring.”
Phrases to Avoid
Saying “the deploy broke the infrastructure” vaguely. Say instead: “the apply included an unreviewed destroy-and-recreate on this resource” — this is specific enough that anyone reading the incident report understands exactly what happened and why.
Saying “it’s out of sync” instead of naming drift. Say instead: “there’s configuration drift between Terraform’s state and the actual resource, likely from a manual change” — this names the specific, well-understood failure mode and points toward reconciling state or importing the change.
Saying “just apply it” without mentioning the plan. Say instead: “review the plan output first, especially any destroy actions, before approving the apply” — skipping the plan review step is one of the most common causes of accidental infrastructure destruction.
Quick Reference
| Term | How to use it |
|---|---|
| state | ”This resource is missing from state, so the plan wants to create it again.” |
| plan | ”The plan shows a destroy-and-recreate on the database — review carefully.” |
| drift | ”Manual console changes caused drift between state and actual config.” |
| module | ”We extracted this into a reusable module with environment variables.” |
| provider | ”We pinned the provider version to avoid a silent behavior change.” |
| import | ”We imported the manually-created bucket into state.” |
Key Takeaways
- Always name a destructive plan action specifically (“destroy-and-recreate on X”) rather than describing an incident as “the deploy broke things.”
- Distinguish drift from a genuine bug — drift specifically means state and reality have diverged, often due to a manual out-of-band change.
- Treat the plan step as a mandatory review gate for destructive actions, not a formality to skip before applying.
- Extract repeated infrastructure patterns into modules with explicit input variables, rather than duplicating configuration across environments.
- Pin provider versions deliberately, since even minor version bumps can silently change default behavior and produce unexpected plan diffs.