- Organize local modules on disk
- Pass inputs and outputs between modules
- Call the same module multiple times from the parent
- Keep modules small, focused, and reusable
Design modules to be small, focused, and configurable. Expose required values via input variables and useful computed values via outputs so parent modules (or other teams) can compose them easily.
Project layout
Create a repository root (for example,terraform/) and a modules/ directory. For this lesson we build three local modules:
modules/vpc— creates a VPCmodules/subnet— creates a subnet and its public networking (IGW, route table, association)modules/ec2— creates a security group and an EC2 instance
Below are suggested file contents for each module and the parent configuration. Adjust names, regions, and AMIs for your environment.
Module: vpc
This module creates a VPC and exports its ID. It demonstrates a common module file arrangement:main.tf, variables.tf, and outputs.tf.
modules/vpc/main.tf
Module: subnet
The subnet module creates a subnet and a simple public network path by provisioning an Internet Gateway, a route table, and a route table association. modules/subnet/main.tfThis subnet module creates an Internet Gateway (IGW) and attaches it to the VPC. Because a VPC can have only one IGW, avoid calling this subnet module multiple times for the same VPC unless you protect or extract the IGW/route-table resources. For multi-subnet designs, consider creating the IGW and shared public route table in the VPC module or in a dedicated networking module.
Module: ec2
A concise EC2 module that creates a security group and an EC2 instance. The security group is kept inside the module for simplicity; for larger deployments you may choose to externalize security groups. modules/ec2/main.tfParent module (calls the local modules)
At the repository root createproviders.tf and main.tf (or similar) to call the child modules.
providers.tf
module.vpc.vpc_idreferences thevpc_idoutput declared by the VPC module.module.subnet_module.subnet_idreferences thesubnet_idoutput declared by the Subnet module.- The same module can be invoked multiple times with different inputs (e.g., to create multiple subnets or instance flavors). Be mindful of any resources inside a module that must be unique per VPC (IGW, for example).
Initialize and run
From the parent module directory (whereproviders.tf and main.tf live) run:
Reuse and iteration
- Call the same module multiple times by adding more
moduleblocks, or usefor_each/counton amoduleblock for dynamic creation. - Keep modules parameterized and export only the inputs/outputs needed by callers to reduce coupling.
- Use sensible defaults in
variables.tfand clear descriptions in bothvariables.tfandoutputs.tfto make modules easier to reuse.
Include helpful
description fields for variables and outputs. Consumers of your modules will thank you — clear descriptions and small well-documented modules reduce surprises and improve reusability across teams.Links and references
- Terraform documentation: https://www.terraform.io/docs
- AWS provider for Terraform: https://registry.terraform.io/providers/hashicorp/aws
- AWS VPC concepts: https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html