Terraform Plan
The terraform plan command shows you exactly what Terraform will create, change, or destroy before it does anything. It reads your configuration files, compares them to the current state file, and prints a diff — giving you a safe preview before you apply.
What Is Terraform Plan?
Terraform plan is the review step before any infrastructure change. It reads your .tf files, looks at the current state file, checks what actually exists in the cloud, and prints a precise diff showing what will be created, modified, or destroyed. Nothing changes when you run plan — it is entirely read-only.
At Razorpay, no infrastructure change gets applied without a plan output reviewed in a pull request. Plan is the safety check that catches mistakes before they cost money or cause downtime.
Running Terraform Plan
# Basic plan — shows what will changeterraform plan # Save the plan to a file (recommended for CI/CD)terraform plan -out=tfplan # Apply exactly the saved plan later (no re-evaluation)terraform apply tfplan # Plan for a specific variable fileterraform plan -var-file=prod.tfvars # Plan targeting a specific resource onlyterraform plan -target=aws_s3_bucket.order_imagesReading Plan Output
Terraform will perform the following actions: # aws_s3_bucket.order_images will be created + resource "aws_s3_bucket" "order_images" { # + means CREATE + bucket = "swiggy-order-images-prod" + region = (known after apply) # only known once created } # aws_instance.web will be updated in-place ~ resource "aws_instance" "web" { # ~ means UPDATE ~ instance_type = "t3.small" -> "t3.medium" # old -> new id = "i-0a1b2c3d4e5f" } # aws_db_instance.payments must be replaced -/+ resource "aws_db_instance" "payments" { # -/+ means DESTROY then CREATE ~ engine_version = "13.4" -> "14.0" # forces replacement - identifier = "payments-prod" # - means attribute removed } # aws_s3_bucket.old_bucket will be destroyed - resource "aws_s3_bucket" "old_bucket" { # - means DESTROY - bucket = "swiggy-old-data" } Plan: 1 to add, 1 to change, 1 to destroy.Plan Symbol Reference
| Symbol | Meaning | Risk |
|---|---|---|
+ |
Resource will be created | Low — new resource |
~ |
Resource will be updated in-place | Low — no recreation |
-/+ |
Resource will be destroyed and recreated | High — downtime possible |
- |
Resource will be destroyed | High — data loss risk |
<= |
Data source will be read | None — read-only |
Saving and Using Plan Files
# In CI/CD — save plan during PR checkterraform plan -out=tfplan.binary # Show the saved plan in human-readable formterraform show tfplan.binary # Show the saved plan as JSON (for cost estimation tools)terraform show -json tfplan.binary > tfplan.json # Apply exactly what was planned — no re-evaluation, no surprisesterraform apply tfplan.binaryTipAlways use
-outin CI/CD pipelines. Without it, the apply stage re-evaluates the plan, which can differ from what was reviewed if infrastructure changed between the PR check and the merge.
What Plan Does NOT Show
# Plan does not detect changes made outside Terraform by default# If someone changed an EC2 instance type in the console, plan may not show it# Use -refresh=true (default) or apply -refresh-only to sync state firstterraform plan -refresh=trueTroubleshooting Plan
| Error | Cause | Fix |
|---|---|---|
Error: No configuration files |
Running plan in wrong directory | cd to directory containing .tf files |
Error: Backend configuration changed |
Backend block modified | Run terraform init -reconfigure |
Error acquiring the state lock |
Another apply running | Wait or run terraform force-unlock <ID> |
| Plan shows -/+ unexpectedly | Argument forces replacement | Check provider docs — some changes always recreate |
Common MistakeSeeing a
-/+ replacefor a database and applying without reading why. Some changes — like changing an RDS engine version — force Terraform to destroy and recreate the instance. Always read the reason shown in parentheses after the replacement symbol.
Frequently Asked Questions
Can terraform plan be wrong about what will actually happen on apply?
Yes — plan is a best-effort prediction based on the current state and provider API responses at plan time, but if real infrastructure changes between plan and apply (someone else applies a change, or a cloud provider modifies a computed value), the apply can diverge from what plan showed. Some resource attributes are also only 'known after apply' (like an auto-generated ID), which plan shows as `(known after apply)` rather than a concrete value, since the provider can't predict it in advance.
What's a best practice for using terraform plan safely in a team workflow?
Save the plan to a file with `terraform plan -out=tfplan`, have it reviewed (in a PR or by a teammate), then apply that exact saved file rather than re-running plan implicitly at apply time — this guarantees what was reviewed is what gets executed, closing the gap where state could shift between review and execution. Never treat a plan review as optional just because the diff 'looks small'; small diffs on a security group or IAM policy can still be high-impact.