D

Terraform

Terraform CLI commands, workspaces and infrastructure lifecycle management.

Updated 2026-09-03

On this page

Terraform provisions and manages infrastructure declaratively from HCL configuration. This page covers the CLI workflow you'll use daily — init, plan, apply, and the state operations that keep a team's infrastructure in sync.

Installation

terraform version

Prints the installed Terraform version and any configured provider versions.

terraform -help

Lists all subcommands. Run `terraform <subcommand> -help` for flags on any of them.

Initialization

terraform init

Downloads providers and modules, and configures the backend. Always the first command run in a new or cloned working directory.

terraform init -upgrade

Installs the latest acceptable provider and module versions, ignoring what's currently cached.

terraform init -reconfigure

Reconfigures the backend from scratch, ignoring any existing saved configuration. Use when backend settings changed.

terraform init -migrate-state

Reconfigures the backend and attempts to migrate the existing state to the new backend automatically.

Reconfigure vs. migrate-state

Use -reconfigure when you're pointing at a fresh backend and don't need the old state carried over. Use -migrate-state when you're moving existing state to a new backend and want Terraform to copy it for you.

Formatting and Validation

terraform fmt

Rewrites .tf files to the canonical style. Add -recursive to format subdirectories too.

terraform validate

Checks configuration syntax and internal consistency without touching any real infrastructure or state.

Planning

terraform plan

Shows what Terraform would change to match configuration, without applying it.

terraform plan -out=tfplan

Saves the plan to a file so the exact reviewed plan can be applied later, guaranteeing apply matches what was reviewed.

terraform show tfplan

Renders a saved plan file back into human-readable output.

Apply

terraform apply

Shows a plan and prompts for approval before applying it.

terraform apply tfplan

Applies a previously saved plan file exactly as reviewed, with no new plan or prompt.

terraform apply -auto-approve
destructive

Applies without an interactive approval prompt. Safe in CI with a reviewed plan artifact; risky when run against a fresh plan on a shared environment.

Prefer terraform apply tfplan in pipelines — it applies exactly what was reviewed, rather than re-planning and auto-approving whatever comes out.

Destroy

terraform destroy
destructive

Destroys every resource Terraform manages in the current workspace. Irreversible for anything without external backups or snapshots.

terraform destroy -target=aws_instance.example
destructive

Destroys only the targeted resource. A scoping escape hatch, not a routine workflow — targeted operations can drift state from configuration.

State

terraform state list

Lists every resource address currently tracked in state.

terraform state show aws_instance.example

Prints the full recorded attributes of a single resource in state.

terraform state mv aws_instance.old aws_instance.new

Renames or moves a resource within state without destroying and recreating the underlying infrastructure.

terraform state rm aws_instance.example
destructive

Removes a resource from state without destroying it in the real world. The resource keeps running but Terraform forgets about it — a common step before re-importing under a different address.

terraform state pull

Downloads and prints the current remote state as raw JSON.

terraform state push terraform.tfstate
destructive

Overwrites remote state with a local file. Only for recovery — a bad push can corrupt team state for everyone.

Import

terraform import aws_instance.example i-0123456789abcdef0

Brings a resource that already exists in the real world under Terraform management, associating it with a resource address in config.

Write the config first

terraform import only populates state — it does not generate the matching .tf configuration. Write (or generate) the resource block first, then import, then run terraform plan to confirm no diff.

Refresh

terraform apply -refresh-only

Updates state to match real infrastructure and shows you the diff first, requiring approval before writing it. The safe way to reconcile drift.

terraform plan -refresh-only

Shows what a refresh would change in state, without writing anything. Use this to detect drift without side effects.

terraform refresh
destructive

Legacy command that updates state to match real infrastructure immediately, with no plan shown and no approval step. Superseded by terraform apply -refresh-only, which is safer.

Workspaces

terraform workspace list

Lists all workspaces in the current backend; the active one is marked with an asterisk.

terraform workspace new dev

Creates a new workspace with its own isolated state file, and switches to it.

terraform workspace select prod

Switches the active workspace without creating one.

Workspaces aren't environments

Terraform workspaces share the same configuration and only isolate state. Most teams use separate root modules or a wrapper like Terragrunt for genuinely distinct environments (different variables, providers, or approval flows) — reserve workspaces for lightweight variations of the same config, like short-lived feature branches.

Troubleshooting

Common failure modes — state locks, drift, provider mismatches — have their own dedicated walkthroughs.

terraform force-unlock LOCK_ID
destructive

Manually releases a stuck state lock. Only run this after confirming no other terraform process is actually running against this state.

See the Terraform Troubleshooting tab for the full diagnostic sequence for state locks, corrupted state, drift, and failed applies.

Official documentation