Ravindra BagaleCourses & study guides मराठी Track your progress

Guides

How to Manage Dev, Stage and Prod with Terraform

Share modules, give each environment its own state key and tfvars, plan with -var-file, and apply prod only from CI with approval.

Friends, three environments means three state keys — not one laptop guessing. Chala mitrano — say the env name before every apply.

Quick answer

Hold this vertical picture:

  1. Layout dev/stage/prod folders.
  2. Separate backend keys.
  3. Write tfvars per env.
  4. plan -var-file.
  5. Prod via CI+approve; tag Environment.

Language: English · मराठी · हिंदी

Shared modulesOne code path dev state keySmall sizes stage state keyProd-like test prod state keyCI + approve Tags EnvironmentCost views
Dev stage prod

Why separate state

One state for three names mixes blast radius.

Why: Destroying "dev" must never touch prod resources. What: Key per env; shared modules. How: Say the env before apply.

Example 1: Folder layout

Type this:

mkdir -p /tmp/tfenvironments/{dev,stage,prod} /tmp/tfenvironments/modules && printf '%s\n' 'dev/' 'stage/' 'prod/' 'modules/' > /tmp/tfenvironments/layout.txt && cat /tmp/tfenvironments/layout.txt

You will see:

dev/
stage/
prod/
modules/

What it means: Each env folder has its own state backend key.

Example 2: Dev tfvars

Type this:

printf '%s\n' 'env = "dev"' 'instance_type = "t3.micro"' 'cidr = "10.0.0.0/16"' > /tmp/tfenvironments/dev/dev.tfvars && cat /tmp/tfenvironments/dev/dev.tfvars

You will see:

env = "dev"

What it means: Small sizes in dev — save INR on labs.

Example 3: Prod tfvars

Type this:

printf '%s\n' 'env = "prod"' 'instance_type = "t3.large"' 'cidr = "10.20.0.0/16"' > /tmp/tfenvironments/prod/prod.tfvars && cat /tmp/tfenvironments/prod/prod.tfvars

You will see:

env = "prod"

What it means: Different CIDR avoids overlapping VPN routes.

Concept 1: tfvars and keys

Different sizes and CIDRs.

Why: Ambient vars hide which env you hit. What: -var-file=dev.tfvars; unique keys. How: Check backend before plan.

Example 4: Backend key per env

Type this:

printf '%s\n' 'key = "prod/network/terraform.tfstate"'

You will see:

key = "prod/network/terraform.tfstate"

What it means: Never share one state file across env names.

Example 5: Plan with var-file

Type this:

printf '%s\n' 'terraform plan -var-file=dev.tfvars'

You will see:

terraform plan -var-file=dev.tfvars

What it means: Explicit file beats ambient env vars for clarity.

Example 8: Check which state

Type this:

printf '%s\n' 'terraform workspace show; head -5 backend.tf'

You will see:

terraform workspace show; head -5 backend.tf

What it means: Say the env name out loud before apply.

Concept 2: Guard prod

CI + approval; no casual destroy.

Why: Laptop prod apply is an incident pattern. What: Approval gate; ticket for destroy. How: Workspaces optional.

Example 6: Workspace alternative

Type this:

printf '%s\n' 'terraform workspace select dev || terraform workspace new dev'

You will see:

terraform workspace select dev || terraform workspace new dev

What it means: Workspaces share code; many teams still prefer folders.

Example 7: Protect prod apply

Type this:

printf '%s\n' 'ok: prod apply only from CI with approval gate'

You will see:

ok: prod apply only from CI with approval gate

What it means: Laptop prod apply is how Friday outages start.

Example 12: Destroy only non-prod casually

Type this:

printf '%s\n' 'terraform destroy -var-file=dev.tfvars  # never muscle-memory this on prod'

You will see:

terraform destroy -var-file=dev.tfvars  # never muscle-memory this on prod

What it means: Prod destroy needs a ticket and two humans.

Concept 3: Promote with tags

Stage rehearses; tags show cost.

Why: Untagged prod hides bills. What: Same module version; Environment tag. How: Promote intentionally.

Example 9: Shared modules path

Type this:

printf '%s\n' 'source = "../../modules/vpc"'

You will see:

source = "../../modules/vpc"

What it means: One modules tree; three env callers.

Example 10: Tag everything

Type this:

printf '%s\n' 'tags = { Environment = var.env, Owner = "payments" }'

You will see:

tags = { Environment = var.env, Owner = "payments" }

What it means: Cost explorer filters by Environment tag.

Example 11: Drift between envs

Type this:

printf '%s\n' 'Same module version in stage and prod; promote intentionally'

You will see:

Same module version in stage and prod; promote intentionally

What it means: Stage is the dress rehearsal.

Env card

1 Folders or workspaces 2 Separate backend keys 3 tfvars per env 4 Shared modules 5 Prod only via CI+approve 6 Tag Environment

Suppose: Applied to wrong env

Stop; compare state key; restore from versioned state if needed.

Suppose: CIDR clash

Give each env its own CIDR plan.

Ravindra Bagale's Tip

At TCS, prod Terraform applies go through CI with a manual approval. Reviewers ask how you stop a laptop from pointing at prod state.

Check yourself (quiz)

Q1. One state for all envs?

No — separate keys

Q2. How to pass env values?

-var-file

Q3. Prod apply from?

CI with approval

Q4. Why tags?

Cost and ownership

Q5. Shared what?

Modules code

Q6. Wrong env apply?

Stop; verify state key

Reading tracking

Mark this guide when you finish. Your browser remembers it on this device.

modules → per-env state → tfvars → plan → guarded apply. Did you understand? Let us try it once more.

Frequently asked questions

Folders or workspaces?

Folders are clearer for many Indian MNC teams; workspaces also work.

Same CIDR?

Prefer unique CIDRs per env.

Promote how?

Same module version after stage succeeds.

Who applies prod?

CI role after human approve.

Destroy prod?

Ticket + two people.

State bucket?

Often one bucket, many keys.