terraform plan, which acts as a safety net: it shows exactly what Terraform intends to do before making any real changes. That helps prevent surprises like accidentally deleting resources.
Terraform plan generates an execution plan that lists the actions Terraform will take to bring real-world resources in line with your configuration. This is a dry run — nothing is created, modified, or destroyed during planning.

terraform plan like looking at a map before a drive: you can review the route, spot potential issues, and choose whether to proceed. If the plan shows something unexpected, update your configuration before applying changes.
Always run
terraform plan to review changes before terraform apply. It’s a best practice for any environment, and essential in production.terraform plan:
- Terraform refreshes state (by default) by querying provider APIs to get the current real-world resource state.
- Terraform compares the refreshed state with your configuration and state file, then generates an execution plan that lists resource actions.
- The plan shows resource actions with symbols indicating the intended change.
terraform plan output (representative):
| Symbol | Meaning | Notes |
|---|---|---|
+ | Create | Attributes that are not known until apply are shown as (known after apply) |
~ | Update in-place | The provider supports changing the resource without destroying it |
- | Destroy | Resource will be removed because it is no longer in configuration |
-/+ | Destroy and then create replacement | Change cannot be done in-place; the plan will show which attribute # forces replacement |
random_pet.additional_petis marked+(a new resource).random_pet.exampleis marked-/+because changinglengthfrom2to3forces replacement; Terraform annotates the attribute with# forces replacement.vault_generic_secret.example_kvis updated in-place; sensitive values are shown as(sensitive value)to avoid leaking secrets.vault_generic_secret.example_secretis scheduled for destruction since it was removed from the configuration; its attributes are shown as being removed (set tonull).

- By default,
terraform planrefreshes state from providers to ensure the plan reflects the current world. This makes the plan accurate for most use cases. - If you need to avoid provider queries (for example, to reduce API calls during ad-hoc checks), you can pass
-refresh=false, but this may cause the plan to be based on stale information.
Using
-refresh=false can produce misleading plans because Terraform will not reconcile state with the provider. Use it cautiously and avoid it in production workflows where accuracy matters.| Command | Purpose | Example |
|---|---|---|
terraform plan | Preview changes | terraform plan |
terraform plan -out=<file> | Save a plan to a file for later apply | terraform plan -out=myplan.tfplan |
terraform apply <file> | Apply a saved plan file (no re-plan) | terraform apply myplan.tfplan |
terraform apply myplan.tfplan, Terraform skips the planning phase and executes the saved plan exactly as recorded. This ensures determinism and is ideal for audit trails and automated approvals.
Summary and best practices
- Treat
terraform planas a dry-run: it refreshes state, calculates the delta, and displays actions with clear symbols. - Always review the plan before applying, especially in production environments.
- Use
terraform plan -out=FILEto produce a saved, deterministic plan that can be reviewed and applied later. - Be mindful of sensitive values: Terraform hides them in plan output.
- Pay attention to
-/+replacement annotations so you understand when resources will be destroyed and recreated.