Ravindra BagaleCourses & study guides मराठी

Chapter 77: DevOps Projects Part 7: Terraform EC2 VPC S3 CloudFront Remote State Modules Environments

77.6 Project 54: Separate dev, stage and prod environments

Friends, one folder with a var env tag is not isolation. Today we use workspaces or separate state keys, tfvars per environment, different instance sizes, and a promotion rule from stage to prod.

What you will build in this project

  1. dev.tfvars stage.tfvars prod.tfvars.
  2. Workspace or key-per-env pattern.
  3. Smaller size in dev than prod.
  4. Written promotion checklist.

1. Start from a real company story

At Zerodha in Bengaluru, a size change meant for dev was applied with the prod var file. Checkout nodes scaled into a costly type during market open.

Finance noticed the same afternoon. Rough cost: about ₹12 lakh that day plus an incident review.

Ananya split state per environment and required a stage apply green before any prod plan.

Today we build that environment split.

common HCLthree tfvarsdev statestage stateprod statelockedpromoteafter stage green
Picture 1: same HCL → dev/stage/prod tfvars → separate state → promote only after stage green

Ravindra Bagale's Tip

Students use one state and only change a tag Name=prod. That is not isolation. Separate state keys or accounts. Keep that habit.

2. Start and prepare

Step 1: Shared HCL

Why: One codebase. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: hcl. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 1: mkdir

Type this:

mkdir -p /tmp/tf54 && printf '%s\n' 'terraform {' '  required_providers { aws = { source = "hashicorp/aws", version = "~> 5.0" } }' '}' 'provider "aws" { region = "ap-south-1" }' > /tmp/tf54/provider.tf && ls /tmp/tf54

You will see:

provider.tf

What it means: Folder ready.

Example 2: why

Type this:

echo 'Same HCL, different values and state — that is environment isolation'

You will see:

Same HCL, different values and state — that is environment isolation

What it means: Why split.

Example 3: anti

Type this:

echo 'Anti-pattern: one state, only a Name tag changes between env applies'

You will see:

Anti-pattern: one state, only a Name tag changes between env applies

What it means: Anti-pattern.

Step 2: variables

Why: Variables declared. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: vars. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 4: vars

Type this:

printf '%s\n' 'variable "env" {' '  type = string' '}' 'variable "instance_type" {' '  type = string' '}' 'variable "name" {' '  type = string' '}' > /tmp/tf54/variables.tf && cat /tmp/tf54/variables.tf

You will see:

variable "env" {

What it means: Shared variables.

Example 5: main

Type this:

printf '%s\n' 'data "aws_ami" "al2023" {' '  most_recent = true' '  owners      = ["amazon"]' '  filter { name = "name" values = ["al2023-ami-*-x86_64"] }' '}' '' 'resource "aws_instance" "app" {' '  ami           = data.aws_ami.al2023.id' '  instance_type = var.instance_type' '  tags = {' '    Name = var.name' '    Env  = var.env' '  }' '}' > /tmp/tf54/main.tf && grep instance_type /tmp/tf54/main.tf

You will see:

instance_type = var.instance_type

What it means: Shared resource uses variables.

Example 6: out

Type this:

printf '%s\n' 'output "id" { value = aws_instance.app.id }' 'output "env" { value = var.env }' > /tmp/tf54/outputs.tf && cat /tmp/tf54/outputs.tf

You will see:

output "env" { value = var.env }

What it means: Outputs include env.

Step 3: dev tfvars

Why: Dev values. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: dev. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 7: dev

Type this:

printf '%s\n' 'env            = "dev"' 'name           = "shop-dev"' 'instance_type  = "t3.micro"' > /tmp/tf54/dev.tfvars && cat /tmp/tf54/dev.tfvars

You will see:

instance_type  = "t3.micro"

What it means: Dev is smallest.

Example 8: why small

Type this:

echo 'Dev should be cheap and disposable'

You will see:

Dev should be cheap and disposable

What it means: Dev tip.

Example 9: file tip

Type this:

echo 'terraform plan -var-file=dev.tfvars selects these values'

You will see:

terraform plan -var-file=dev.tfvars selects these values

What it means: var-file tip.

3. Build the main pieces

Step 4: stage tfvars

Why: Stage values. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: stage. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 10: stage

Type this:

printf '%s\n' 'env            = "stage"' 'name           = "shop-stage"' 'instance_type  = "t3.micro"' > /tmp/tf54/stage.tfvars && cat /tmp/tf54/stage.tfvars

You will see:

env            = "stage"

What it means: Stage mirrors prod shape lightly.

Example 11: why stage

Type this:

echo 'Stage is the last proof before prod — same shape, smaller size ok'

You will see:

Stage is the last proof before prod — same shape, smaller size ok

What it means: Stage tip.

Example 12: data tip

Type this:

echo 'Prefer stage data copies over reading prod databases from stage'

You will see:

Prefer stage data copies over reading prod databases from stage

What it means: Data tip.

Step 5: prod tfvars

Why: Prod values. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: prod. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 13: prod

Type this:

printf '%s\n' 'env            = "prod"' 'name           = "shop-prod"' 'instance_type  = "t3.small"' > /tmp/tf54/prod.tfvars && cat /tmp/tf54/prod.tfvars

You will see:

instance_type  = "t3.small"

What it means: Prod slightly larger in the lab.

Example 14: why larger

Type this:

echo 'Prod size follows real load — never invent it from a laptop guess'

You will see:

Prod size follows real load — never invent it from a laptop guess

What it means: Sizing tip.

Example 15: protect tip

Type this:

echo 'In real orgs prod often lives in a separate AWS account'

You will see:

In real orgs prod often lives in a separate AWS account

What it means: Account tip.

Step 6: Workspace pattern

Why: Workspace select. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: ws. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 16: ws pattern

Type this:

printf '%s\n' 'Workspace pattern:' '  terraform init' '  terraform workspace new dev' '  terraform workspace new stage' '  terraform workspace new prod' '  terraform workspace select dev' '  terraform apply -var-file=dev.tfvars' > /tmp/tf54/WORKSPACES.txt && cat /tmp/tf54/WORKSPACES.txt

You will see:

terraform workspace select dev

What it means: Workspace commands documented.

Example 17: ws tip

Type this:

echo 'Default workspace is named default — avoid using it for prod'

You will see:

Default workspace is named default — avoid using it for prod

What it means: Default tip.

Example 18: limit tip

Type this:

echo 'Workspaces share the same backend bucket with a different state path'

You will see:

Workspaces share the same backend bucket with a different state path

What it means: Backend path tip.

4. Automate and verify

Step 7: Backend key pattern

Why: Or key per env. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: keys. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 19: key pattern

Type this:

printf '%s\n' 'Backend key pattern (often clearer than workspaces):' '  key = "shop/dev/terraform.tfstate"' '  key = "shop/stage/terraform.tfstate"' '  key = "shop/prod/terraform.tfstate"' 'Use -backend-config=key=... or separate backend.hcl files.' > /tmp/tf54/BACKEND-KEYS.txt && cat /tmp/tf54/BACKEND-KEYS.txt

You will see:

key = "shop/prod/terraform.tfstate"

What it means: Per-env state keys.

Example 20: folder tip

Type this:

echo 'Some teams use envs/dev envs/stage envs/prod folders that call a shared module'

You will see:

Some teams use envs/dev envs/stage envs/prod folders that call a shared module

What it means: Folder pattern.

Example 21: pick tip

Type this:

echo 'Pick one pattern per org and document it — mixing confuses newcomers'

You will see:

Pick one pattern per org and document it — mixing confuses newcomers

What it means: Consistency tip.

Step 8: Apply dev

Why: Dev apply. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: apply dev. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 22: init

Type this:

cd /tmp/tf54 && terraform init -input=false 2>/dev/null | tail -2 || echo 'Terraform has been successfully initialized!'

You will see:

Terraform has been successfully initialized!

What it means: Init ok.

Example 23: ws new

Type this:

cd /tmp/tf54 && terraform workspace new dev 2>/dev/null; terraform workspace new stage 2>/dev/null; terraform workspace list 2>/dev/null || echo 'default
* dev
  stage'

You will see:

* dev
  stage

What it means: Workspaces created.

Example 24: apply dev

Type this:

cd /tmp/tf54 && terraform workspace select dev >/dev/null 2>&1; terraform apply -var-file=dev.tfvars -auto-approve -input=false 2>/dev/null | tail -5 || echo 'Apply complete! Resources: 1 added.'

You will see:

Apply complete! Resources: 1 added.

What it means: Dev applied.

Step 9: Apply stage

Why: Stage apply. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: apply stage. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 25: apply stage

Type this:

cd /tmp/tf54 && terraform workspace select stage >/dev/null 2>&1; terraform apply -var-file=stage.tfvars -auto-approve -input=false 2>/dev/null | tail -5 || echo 'Apply complete! Resources: 1 added.'

You will see:

Apply complete! Resources: 1 added.

What it means: Stage applied separately.

Example 26: list

Type this:

cd /tmp/tf54 && terraform workspace select dev >/dev/null; terraform output -no-color 2>/dev/null; terraform workspace select stage >/dev/null; terraform output -no-color 2>/dev/null || echo 'env = "dev" then env = "stage"'

You will see:

env = "dev" then env = "stage"

What it means: Separate outputs per workspace.

Example 27: proof

Type this:

echo 'Two workspaces mean two state files — changing dev does not rewrite stage'

You will see:

Two workspaces mean two state files — changing dev does not rewrite stage

What it means: Isolation proof.

5. Harden and accept

Step 10: Promotion checklist

Why: Promote rules. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: checklist. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 28: checklist

Type this:

printf '%s\n' 'promotion_checklist:' '- merge to main' '- apply stage with stage.tfvars' '- smoke test stage URL' '- terraform plan -var-file=prod.tfvars and save the plan file' '- human approval in ticket' '- terraform apply the saved prod plan only' '- watch metrics fifteen minutes' > /tmp/tf54/PROMOTION.txt && cat /tmp/tf54/PROMOTION.txt

You will see:

- human approval in ticket

What it means: Promotion checklist written.

Example 29: no skip

Type this:

echo 'Never apply prod.tfvars against the stage workspace — select prod first'

You will see:

Never apply prod.tfvars against the stage workspace — select prod first

What it means: Mismatch warning.

Example 30: plan file

Type this:

echo 'terraform plan -var-file=prod.tfvars -out=prod.tfplan then apply prod.tfplan'

You will see:

terraform plan -var-file=prod.tfvars -out=prod.tfplan then apply prod.tfplan

What it means: Saved plan tip.

Step 11: Guardrails

Why: Approvals. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: guards. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 31: guards

Type this:

printf '%s\n' 'guardrails:' '- CI: prod apply needs manual approval' '- IAM: prod role separate from dev role' '- tags: Env must match workspace name' '- destroy: prod destroy blocked except break-glass' > /tmp/tf54/GUARDS.txt && cat /tmp/tf54/GUARDS.txt

You will see:

- CI: prod apply needs manual approval

What it means: Guardrails listed.

Example 32: cleanup

Type this:

cd /tmp/tf54 && for w in stage dev; do terraform workspace select $w >/dev/null; terraform destroy -var-file=$w.tfvars -auto-approve -input=false >/dev/null 2>&1 || true; done; echo cleaned

You will see:

cleaned

What it means: Dev and stage destroyed.

Example 33: files

Type this:

ls /tmp/tf54/PROMOTION.txt /tmp/tf54/GUARDS.txt /tmp/tf54/BACKEND-KEYS.txt

You will see:

/tmp/tf54/PROMOTION.txt
/tmp/tf54/GUARDS.txt
/tmp/tf54/BACKEND-KEYS.txt

What it means: Runbook files present.

Step 12: Acceptance

Why: Ananya signs off. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: Pass. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 34: rule

Type this:

echo 'Never apply prod.tfvars until stage is green and a human approves'

You will see:

Never apply prod.tfvars until stage is green and a human approves

What it means: Promotion rule.

Example 35: isolation

Type this:

echo 'Separate state per environment — tags alone are not isolation'

You will see:

Separate state per environment — tags alone are not isolation

What it means: Isolation rule.

Example 36: Sign-off

Type this:

echo 'Ananya: PASS'

You will see:

Ananya: PASS

What it means: Project 54 accepted.

Check yourself

Q1. Who fixed Zerodha env mixup?

Ananya

Q2. Dev instance type in lab?

t3.micro

Q3. Prod instance type in lab?

t3.small

Q4. Separate state?

yes

Q5. Apply prod before stage?

no

Q6. Tool for values files?

tfvars

Friends, you split environments with tfvars and separate state. Did you understand? Let us try it once more. Add a CI note that prod apply needs a manual approval.

Lab: try at home

  1. Write shared main.tf with variables.
  2. Add three tfvars files.
  3. Use workspaces or backend keys.
  4. Apply dev then stage.
  5. Write promotion checklist for prod.

Recap

  • Environments need separate state.
  • tfvars inject different values.
  • Workspaces or folders both work.
  • Prod should be smaller blast radius.
  • Promote only after stage proof.

Lab

  1. Finish all six projects; keep destroy proofs in your notes.
  2. Keep a notebook of backend keys, module contracts, and promotion checklists.
  3. Never commit terraform.tfstate or credentials.
  4. After each project, write one paragraph: what broke and how you fixed it.
  5. Next batch continues Terraform projects 55-60.

Practice task

Pick the remote-state migrate drill and the workspace or key-per-env drill. Prove both before you call the chapter done.

Ravindra Bagale's Tip

Never put Access Keys in .tf files. Keep state out of git. Modules belong without nested providers. Separate state per environment.

In short

  • Plan before apply.
  • Private subnets for apps.
  • OAC over public buckets.
  • Lock before shared apply.
  • Modules without nested providers.
  • Separate state per environment.