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.binaryPLACEMENT PRO TIP**Tip:** Always use `-out` in 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 MISTAKE / WARNING**Common Mistake:** Seeing a `-/+ replace` for 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.