Skip to main content
Welcome. In this lesson you’ll learn how to create local Terraform modules and compose them in a parent configuration to provision AWS resources. The focus is on module structure, inputs/outputs, and wiring outputs from one module into another so you can reuse infrastructure code across projects and environments.

What you’ll build

  • A parent Terraform configuration that calls local modules.
  • Three local modules: vpc, subnet, and ec2.
  • Data flow that passes outputs from one module into another (e.g., VPC ID -> Subnet -> EC2).

Directory and file layout

Create a top-level Terraform directory (this is the parent module). Inside it add common files and a modules subdirectory with three child modules. Below are cleaned-up module implementations and the parent configuration examples. Keep these modules focused and parameterized so they are reusable across accounts and environments.

VPC module

This module creates a VPC and exposes its ID as an output. modules/vpc/main.tf
modules/vpc/variables.tf
modules/vpc/outputs.tf

Subnet module

This module provisions a subnet and the supporting network resources: an Internet Gateway, a route table, and a route table association. It accepts a vpc_id input and returns the subnet_id. modules/subnet/main.tf
The image shows a code editor with a Terraform script being edited, displaying an autocomplete suggestion for resource configuration. The explorer pane on the left shows a directory structure with Terraform files.
modules/subnet/variables.tf
modules/subnet/outputs.tf

EC2 module

This module creates a security group and an EC2 instance. Inputs include VPC and subnet IDs plus AMI, instance type, and an instance name. Outputs include the instance ID and public IP. modules/ec2/main.tf
modules/ec2/variables.tf
modules/ec2/outputs.tf

Parent configuration

The parent module declares the AWS provider and calls the child modules. Note how we wire outputs into module inputs. providers.tf (parent)
main.tf (parent) — module blocks

Tooling and basic workflow

After you add or change modules, follow this basic workflow.
  1. Initialize the working directory (downloads providers and registers modules)
  1. Format your files
  1. Create and review a plan, then apply
Example of a planned resource created by a child module:
The image shows a Visual Studio Code window with a Terraform configuration file open, displaying code related to module configuration and variables for a cloud infrastructure setup. The left sidebar lists project files, while the main section includes code with autocompletion suggestions.

Notes and best practices

Use module outputs to pass information between modules (for example: module.vpc.vpc_id -> module.subnet_module.vpc_id). Keep modules small, well-documented, and parameterized so they can be reused across environments.
Running terraform apply will create resources in your cloud account and may incur charges. Always review the plan before applying and destroy resources when they are no longer needed.
  • Use descriptive variable names and include description in each variables.tf.
  • Prefer explicit module inputs over relying on implicit defaults in a parent configuration.
  • You can call a module multiple times with different arguments, or use for_each to create multiple instances of a module.
  • Split responsibilities logically (networking, compute, database) to simplify testing and reuse.
  • Consider versioning modules if you extract them to a shared registry.
Recommended links:

Summary

  • You created a local module structure (vpc, subnet, ec2), implemented resources along with variables and outputs, and wired module outputs into parent module inputs.
  • This modular approach reduces duplication and makes it easy to create multiple similar environments by calling the same module with different inputs.

Watch Video