In real companies:
-
You have multiple environments
- dev
- stage
- prod
β BAD:
terraform apply (same folder)
β prod overwrites dev
β
GOOD (Production):
Separate state per environment
Separate execution per environment
Shared reusable modules
π· PART 2 β Final Architecture
terraform-prod-lab/
β
βββ modules/ # LOCAL modules
β βββ ec2/
β βββ main.tf
β βββ variables.tf
β βββ outputs.tf
β
βββ envs/
β βββ dev/
β β βββ main.tf
β β βββ backend.tf
β β
β βββ prod/
β βββ main.tf
β βββ backend.tf
β
βββ README.md
π· PART 3 β LOCAL MODULE (modules/ec2)
modules/ec2/main.tf
resource "aws_instance" "this" {
ami = var.ami
instance_type = var.instance_type
tags = {
Name = var.name
Env = var.env
}
}
modules/ec2/variables.tf
variable "ami" {}
variable "instance_type" {}
variable "name" {}
variable "env" {}
modules/ec2/outputs.tf
output "instance_id" {
value = aws_instance.this.id
}
π· PART 4 β DEV ENV (LOCAL MODULE CALL)
envs/dev/main.tf
provider "aws" {
region = "us-east-2"
}
module "ec2_dev" {
source = "../../modules/ec2"
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
name = "dev-server"
env = "dev"
}
envs/dev/backend.tf
terraform {
backend "local" {
path = "dev.tfstate"
}
}
π· PART 5 β PROD ENV (GITHUB MODULE)
Now simulate production module reuse from GitHub
envs/prod/main.tf
provider "aws" {
region = "us-east-2"
}
module "ec2_prod" {
source = "git::https://github.com/your-username/terraform-ec2-module.git"
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
name = "prod-server"
env = "prod"
}
envs/prod/backend.tf
terraform {
backend "local" {
path = "prod.tfstate"
}
}
π· PART 6 β REGISTRY MODULE (ADD S3)
Add real-world registry usage
envs/dev/main.tf (ADD THIS)
module "s3" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 3.0"
bucket = "jumptotech-dev-bucket-12345"
}
envs/prod/main.tf (ADD THIS)
module "s3" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 3.0"
bucket = "jumptotech-prod-bucket-12345"
}
π· PART 7 β RUNNING (CRITICAL PART)
β Deploy DEV
cd envs/dev
terraform init
terraform plan
terraform apply
β Deploy PROD
cd ../prod
terraform init
terraform plan
terraform apply
π₯ IMPORTANT RESULT
| Action | What Happens |
|---|---|
| Apply dev | Only dev created |
| Apply prod | Only prod created |
| Destroy prod | Dev stays SAFE |
| Destroy dev | Prod stays SAFE |
π Because:
Separate state files
Separate folders
Separate execution
π· PART 8 β WHY THIS IS PRODUCTION STANDARD
Key Concepts
1. State Isolation
Each environment has:
dev.tfstate
prod.tfstate
So Terraform does NOT mix resources.
2. Module Reuse
| Type | Example |
|---|---|
| Local | ../../modules/ec2 |
| GitHub | git::https://... |
| Registry | terraform-aws-modules |
3. No Cross-Environment Impact
Terraform ONLY manages what is in:
current state file
π· PART 9 β INTERVIEW QUESTIONS
Q1: How do you prevent dev destroying prod?
Answer:
Separate state files per environment
Separate folders or workspaces
Q2: Where do modules come from?
Local filesystem
Git repositories
Terraform Registry
Q3: Why use GitHub modules?
Version control
Team sharing
Reusable infrastructure
Q4: What is best practice?
Separate repo for modules
Separate repo for environments (infra-live)
π· PART 10 β REAL COMPANY STRUCTURE (VERY IMPORTANT)
infra-modules/ (GitHub repo)
βββ ec2
βββ vpc
βββ rds
infra-live/ (GitHub repo)
βββ dev
βββ stage
βββ prod
π₯ BONUS β WHAT STUDENTS MUST UNDERSTAND
If they remember ONLY ONE thing:
π Terraform manages STATE, not resources
π· PART 11 β ADVANCED (OPTIONAL)
Production improvement:
- Use S3 backend instead of local
- Add DynamoDB locking
- Add versions for Git modules
Example:
source = "git::https://github.com/org/module.git?ref=v1.0.0"
β FINAL RESULT
- Real module usage (ALL 3 types)
- Production environment separation
- State isolation
- GitHub module usage
- Registry usage
- Why Terraform does NOT destroy everything
Top comments (0)