DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Terraform Modules Lab (Beginner Intermediate Real-world)

Objective

Build reusable Terraform modules and deploy infrastructure using them.

You will:

  • Create a VPC module
  • Create an EC2 module
  • Reuse modules
  • Understand module inputs, outputs, and structure

Part 1 – Project Structure (Real-world layout)

terraform-modules-lab/
│
├── modules/
│   ├── vpc/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   │
│   └── ec2/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
│
├── env/
│   └── dev/
│       ├── main.tf
│       ├── variables.tf
│       └── terraform.tfvars
Enter fullscreen mode Exit fullscreen mode

Part 2 – Create VPC Module

modules/vpc/main.tf

resource "aws_vpc" "main" {
  cidr_block = var.cidr_block

  tags = {
    Name = var.name
  }
}

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.subnet_cidr
  availability_zone = var.az

  tags = {
    Name = "${var.name}-subnet"
  }
}
Enter fullscreen mode Exit fullscreen mode

modules/vpc/variables.tf

variable "cidr_block" {}
variable "subnet_cidr" {}
variable "az" {}
variable "name" {}
Enter fullscreen mode Exit fullscreen mode

modules/vpc/outputs.tf

output "vpc_id" {
  value = aws_vpc.main.id
}

output "subnet_id" {
  value = aws_subnet.public.id
}
Enter fullscreen mode Exit fullscreen mode

Part 3 – Create EC2 Module

modules/ec2/main.tf

resource "aws_instance" "web" {
  ami           = var.ami
  instance_type = var.instance_type
  subnet_id     = var.subnet_id

  tags = {
    Name = var.name
  }
}
Enter fullscreen mode Exit fullscreen mode

modules/ec2/variables.tf

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

modules/ec2/outputs.tf

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

Part 4 – Use Modules (Dev Environment)

env/dev/main.tf

provider "aws" {
  region = "us-east-1"
}

module "vpc" {
  source       = "../../modules/vpc"
  cidr_block   = "10.0.0.0/16"
  subnet_cidr  = "10.0.1.0/24"
  az           = "us-east-1a"
  name         = "dev-vpc"
}

module "ec2" {
  source         = "../../modules/ec2"
  ami            = "ami-0c55b159cbfafe1f0" # update for your region
  instance_type  = "t2.micro"
  subnet_id      = module.vpc.subnet_id
  name           = "dev-server"
}
Enter fullscreen mode Exit fullscreen mode

env/dev/terraform.tfvars

# optional for extension later
Enter fullscreen mode Exit fullscreen mode

Part 5 – Run the Lab

cd env/dev

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

Expected Result

You should get:

  • 1 VPC
  • 1 Subnet
  • 1 EC2 instance inside that subnet

Part 6 – Important Concepts (Interview + Real-world)

1. What is a module?

A module is:

A reusable Terraform configuration block


2. Module Flow

Root Module (env/dev)
        ↓
Calls Module (vpc, ec2)
        ↓
Creates Resources
Enter fullscreen mode Exit fullscreen mode

3. How data flows

  • Input → variables
  • Output → used by other modules

Example:

subnet_id = module.vpc.subnet_id
Enter fullscreen mode Exit fullscreen mode

Part 7 – Advanced Tasks

Task 1 – Add Security Group Module

Create:

modules/security-group
Enter fullscreen mode Exit fullscreen mode
  • Allow port 22
  • Allow port 80
  • Attach to EC2

Task 2 – Multiple EC2 Instances

Update EC2 module:

count = var.instance_count
Enter fullscreen mode Exit fullscreen mode

Task 3 – Multi-environment

Create:

env/
  dev/
  stage/
  prod/
Enter fullscreen mode Exit fullscreen mode

Each with different:

  • instance size
  • CIDR block

Task 4 – Remote Module (REAL DevOps)

Push module to GitHub:

source = "git::https://github.com/your-repo/vpc-module.git"
Enter fullscreen mode Exit fullscreen mode

Part 8 – Production Best Practices

DO:

  • Use modules for reusable components
  • Separate env (dev/stage/prod)
  • Use outputs between modules
  • Keep modules small and focused

DON'T:

  • Hardcode values
  • Mix everything in one file
  • Create giant modules

Part 9 – Real Interview Questions

  1. What is the difference between root module and child module?
  2. How do modules communicate?
  3. Can modules call other modules?
  4. How do you version modules in production?
  5. What is the difference between local module and remote module?

Part 10 – Real Production Insight (Very Important)

In real companies:

You will see:

  • terraform-modules repo (reusable)
  • terraform-live repo (env-specific)

Example:

infra-modules/
infra-live/
Enter fullscreen mode Exit fullscreen mode

Top comments (0)