Skip to main content
In this lesson you’ll create local Terraform modules and consume them from a parent configuration to provision AWS resources. This demonstrates how to:
  • 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
While the examples use AWS resources (VPC, subnet, EC2), the patterns shown are provider-agnostic and apply to any Terraform-supported provider.
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 VPC
  • modules/subnet — creates a subnet and its public networking (IGW, route table, association)
  • modules/ec2 — creates a security group and an EC2 instance
Top-level files in the repo will call these modules from the parent configuration. Example directory structure:
Summary of modules and responsibilities: 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
modules/vpc/variables.tf
modules/vpc/outputs.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.tf
modules/subnet/variables.tf
modules/subnet/outputs.tf
This module is an example of grouping related resources inside a module rather than limiting a module to a single resource.
This 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.tf
modules/ec2/variables.tf
modules/ec2/outputs.tf

Parent module (calls the local modules)

At the repository root create providers.tf and main.tf (or similar) to call the child modules. providers.tf
main.tf (parent module — calling the local modules)
Notes:
  • module.vpc.vpc_id references the vpc_id output declared by the VPC module.
  • module.subnet_module.subnet_id references the subnet_id output 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 (where providers.tf and main.tf live) run:
Example output header (your output may vary):
Then plan and apply:
Terraform creates resources in dependency order because inputs/outputs express the graph (for example, the VPC is created before the subnet that needs its ID).

Reuse and iteration

  • Call the same module multiple times by adding more module blocks, or use for_each/count on a module block for dynamic creation.
  • Keep modules parameterized and export only the inputs/outputs needed by callers to reduce coupling.
  • Use sensible defaults in variables.tf and clear descriptions in both variables.tf and outputs.tf to 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.

That covers a simple example of local modules (VPC, subnet, EC2) and composing them from a parent configuration. Use these patterns to encapsulate repeated infrastructure patterns, keep configurations DRY, and make your infra easier to maintain and share.

Watch Video

Practice Lab