Terraform Tutorial — Why Modules?

1 minute read

As your infrastructure grows, you’ll find yourself repeating the same patterns — VPCs, security groups, EC2 instances — across multiple environments. Modules solve this problem.


The Problem: Copy-Paste Infrastructure

Without modules:

environments/
├── dev/
│   ├── main.tf          ← VPC + EC2 + S3 (dev values)
│   └── variables.tf
├── staging/
│   ├── main.tf          ← VPC + EC2 + S3 (staging values, copy-pasted!)
│   └── variables.tf
└── prod/
    ├── main.tf          ← VPC + EC2 + S3 (prod values, copy-pasted!)
    └── variables.tf

Problems:

  • Bug fix requires updating three files
  • Configurations drift apart over time
  • No guarantee environments are consistent

The Solution: Modules

With modules:

modules/
├── vpc/
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
└── app/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf

environments/
├── dev/main.tf          ← calls module "vpc" + module "app" with dev values
├── staging/main.tf      ← calls module "vpc" + module "app" with staging values
└── prod/main.tf         ← calls module "vpc" + module "app" with prod values

Benefits of Modules

Benefit Description
DRY Write once, use everywhere
Consistency Same infrastructure pattern across environments
Encapsulation Hide complexity behind a simple interface
Testability Test the module once, trust it in all environments
Versioning Pin module versions for stability
Team collaboration One team maintains the module, others consume it

Module Types

Type Source Example
Local File path source = "./modules/vpc"
Registry Terraform Registry source = "terraform-aws-modules/vpc/aws"
Git Git repository source = "git::https://github.com/org/module.git"
S3 S3 bucket source = "s3::https://bucket.s3.amazonaws.com/module.zip"

What’s Next?

Let’s look at the standard structure of a Terraform module.


← Modules Hub Module Structure →