Skip to main content
Welcome — this lesson covers Terraform modules: what they are, how to structure them, and why they matter. Modules let you package related infrastructure resources into reusable, composable units so you can reduce repetition, enforce standards, and deploy consistently across teams and environments. We’ll cover:
  • Core concepts and benefits
  • How modules are composed and consumed
  • Typical module file layout and usage examples
  • Links and next steps for publishing and versioning modules

What are modules?

A Terraform module is a container for a set of resources that are commonly used together — for example, a VPC with subnets and route tables, a load balancer with its SSL configuration, or everything needed for a database tier. Modules let you encapsulate implementation details and expose only the inputs and outputs consumers need. You’ve already been using the root module (the configuration in your working directory). Modules simply let the root (or other parent modules) call child modules so that you can reuse and compose functionality across multiple stacks and teams.

Benefits of using modules

A purple HashiCorp Terraform slide titled "What are Modules?" defining a module as a container for related resources and noting benefits like improved organization, easier collaboration, and consistent patterns.
When modules are published internally (e.g., in a VCS repo or module registry) or consumed from the public Terraform Registry, teams can adopt standardized components instead of recreating the same infrastructure patterns. This drives consistency and simplifies governance.

Module composition and reuse

Instead of defining every resource for each application directly in the root module, extract common functionality into dedicated modules — for example: TLS certificate, load balancer, message queue, Kubernetes cluster, database. Then reference the modules you need from each root module. A module is called with a module block. Example:
Using module blocks like this makes it easy for different services to compose only the components they require. For example, a marketing app may use a TLS certificate and load balancer module, while another service also consumes message queue and database modules. Breaking an application into modules keeps implementation details encapsulated, reduces duplication, and improves maintainability.

What does a module look like?

A module directory contains the same types of Terraform files you use in the root module. A typical, minimal module layout: This pattern mirrors what you already use in your root module — modules are simply a re-packaging of that configuration into reusable units.
A purple infographic titled "Terraform Building Blocks" showing a left column of example modules (TLS Certificate, Load Balancer, Message Queuing, Kubernetes Cluster, Database Cluster) and a right panel zooming into a single module with files labeled main.tf, variables.tf, and outputs.tf. The HashiCorp Terraform logo and author credit appear at the corners.
The root module is the configuration in your current working directory. When the root uses module blocks it creates child module instances. Each child module is retrieved from a source (local folder, the Terraform Registry, a VCS repo, or an archived release) and exposes inputs/outputs defined in its variables.tf and outputs.tf.

Next steps — best practices & resources

Focus next on:
  • Module inputs/outputs: design stable, minimal interfaces for consumers.
  • Versioning: publish module releases and pin the source with a version constraint.
  • Documentation: include examples and clear variable/output descriptions in the module README.
  • Testing: use tools like terraform validate, tflint, and automated CI to validate module behavior before publishing.
Helpful references: Explore module block details, input/output design, and versioning strategies next so you can build, publish, and consume modules safely across environments.

Watch Video