DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

LAB: Production Terraform Modules (Local + GitHub + Registry + Multi-Env)

In real companies:

  • You have multiple environments

    • dev
    • stage
    • prod

❌ BAD:

terraform apply (same folder)
→ prod overwrites dev
Enter fullscreen mode Exit fullscreen mode

✅ GOOD (Production):

Separate state per environment
Separate execution per environment
Shared reusable modules
Enter fullscreen mode Exit fullscreen mode

🔷 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
Enter fullscreen mode Exit fullscreen mode

🔷 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
  }
}
Enter fullscreen mode Exit fullscreen mode

modules/ec2/variables.tf

variable "ami" {}
variable "instance_type" {}
variable "name" {}
variable "env" {}
Enter fullscreen mode Exit fullscreen mode

modules/ec2/outputs.tf

output "instance_id" {
  value = aws_instance.this.id
}
Enter fullscreen mode Exit fullscreen mode

🔷 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"
}
Enter fullscreen mode Exit fullscreen mode

envs/dev/backend.tf

terraform {
  backend "local" {
    path = "dev.tfstate"
  }
}
Enter fullscreen mode Exit fullscreen mode

🔷 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"
}
Enter fullscreen mode Exit fullscreen mode

envs/prod/backend.tf

terraform {
  backend "local" {
    path = "prod.tfstate"
  }
}
Enter fullscreen mode Exit fullscreen mode

🔷 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"
}
Enter fullscreen mode Exit fullscreen mode

envs/prod/main.tf (ADD THIS)

module "s3" {
  source  = "terraform-aws-modules/s3-bucket/aws"
  version = "~> 3.0"

  bucket = "jumptotech-prod-bucket-12345"
}
Enter fullscreen mode Exit fullscreen mode

🔷 PART 7 — RUNNING (CRITICAL PART)

✅ Deploy DEV

cd envs/dev

terraform init
terraform plan
terraform apply
Enter fullscreen mode Exit fullscreen mode

✅ Deploy PROD

cd ../prod

terraform init
terraform plan
terraform apply
Enter fullscreen mode Exit fullscreen mode

🔥 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
Enter fullscreen mode Exit fullscreen mode

🔷 PART 8 — WHY THIS IS PRODUCTION STANDARD

Key Concepts

1. State Isolation

Each environment has:

dev.tfstate
prod.tfstate
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

🔷 PART 9 — INTERVIEW QUESTIONS

Q1: How do you prevent dev destroying prod?

Answer:

Separate state files per environment
Separate folders or workspaces
Enter fullscreen mode Exit fullscreen mode

Q2: Where do modules come from?

Local filesystem
Git repositories
Terraform Registry
Enter fullscreen mode Exit fullscreen mode

Q3: Why use GitHub modules?

Version control
Team sharing
Reusable infrastructure
Enter fullscreen mode Exit fullscreen mode

Q4: What is best practice?

Separate repo for modules
Separate repo for environments (infra-live)
Enter fullscreen mode Exit fullscreen mode

🔷 PART 10 — REAL COMPANY STRUCTURE (VERY IMPORTANT)

infra-modules/        (GitHub repo)
   ├── ec2
   ├── vpc
   └── rds

infra-live/           (GitHub repo)
   ├── dev
   ├── stage
   └── prod
Enter fullscreen mode Exit fullscreen mode

🔥 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"
Enter fullscreen mode Exit fullscreen mode

✅ 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)