Modules & Workflow
Reusable building blocks and the day-to-day workflow that keeps infrastructure safe.
Copy-pasting the same 50 lines of Terraform for every environment is a trap. Modules let you package infrastructure into reusable components. Combined with a disciplined workflow, theyβre how professional teams manage large systems safely.
π― Learning Objectives
By the end of this lesson you will:
- Understand what a Terraform module is
- Write and call your own module
- Use modules from the public registry
- Follow the professional Terraform workflow
What is a Module?
A module is just a folder of .tf files that can be reused with different inputs. In fact, your root configuration is already a module β modules simply let you call one from another.
modules/
webserver/
main.tf # the resources
variables.tf # inputs
outputs.tf # outputs
environments/
prod/
main.tf # calls the webserver moduleπ‘ Think functions
A module is like a function: it takes inputs (variables), does work (creates resources), and returns outputs. Call it many times with different arguments to build many similar things.
Writing a Module
The module (modules/webserver/main.tf) declares inputs and resources:
variable "name" { type = string }
variable "instance_type" { type = string, default = "t3.micro" }
resource "aws_instance" "this" {
ami = "ami-0abc123"
instance_type = var.instance_type
tags = { Name = var.name }
}
output "id" {
value = aws_instance.this.id
}Calling a Module
From your environment config, call the module and pass inputs:
module "web" {
source = "../../modules/webserver"
name = "prod-web"
instance_type = "t3.large"
}
module "api" {
source = "../../modules/webserver"
name = "prod-api"
}
output "web_id" {
value = module.web.id
}One module, called twice, builds two servers with different settings β no duplication.
Using Registry Modules
You donβt have to write everything. The Terraform Registry has battle-tested modules for common infrastructure:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.5.0"
name = "prod-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
}β Always pin module versions
Pin version on registry modules. An unpinned module can silently pull a breaking change on your next init, altering infrastructure unexpectedly.
The Professional Workflow
Real teams follow a consistent cycle, usually automated in CI/CD:
terraform fmt # format code consistently
terraform validate # check syntax and basic correctness
terraform plan -out=tfplan # produce a reviewable plan
# β open a pull request, review the plan
terraform apply tfplan # apply exactly what was reviewed| Step | Why it matters |
|---|---|
fmt |
Consistent style, clean diffs |
validate |
Catch errors before planning |
plan -out |
Save the exact plan for review |
| Peer review | Infrastructure changes get a second pair of eyes |
apply saved plan |
Apply precisely what was approved, no drift |
π‘ Plan in CI, apply on merge
A common setup: plan runs automatically on every pull request so reviewers see the impact, and apply runs only after the PR is merged. Infrastructure changes get the same rigor as code.
π§ͺ Hands-on Lab
Build and Reuse a Module
- Create a module that produces a
local_filefrom anameandcontentvariable - Call it twice from your root config with different inputs
- Run
fmt,validate,plan, thenapply
π§ Knowledge Check
What is a Terraform module?
Why should you pin the version of a registry module?
πΌ Interview Preparation
Describe a safe Terraform workflow for a team managing production.
Summary
Youβve completed the Terraform track: Infrastructure as Code, configuration and variables, state and remote backends, and now modules and the professional workflow. You can build, share, and safely operate infrastructure as code. Next, we automate builds and deployments with Jenkins.