How to Use Terraform Modules

Introduction Terraform modules are an essential feature for managing infrastructure as code efficiently and at scale. They allow you to group multiple resources and configuration files into reusable, maintainable units. Using modules simplifies your Terraform code, promotes best practices, and enhances collaboration across teams. This tutorial provides a comprehensive guide on how to use Terraform

Nov 17, 2025 - 10:59
Nov 17, 2025 - 10:59
 2

Introduction

Terraform modules are an essential feature for managing infrastructure as code efficiently and at scale. They allow you to group multiple resources and configuration files into reusable, maintainable units. Using modules simplifies your Terraform code, promotes best practices, and enhances collaboration across teams.

This tutorial provides a comprehensive guide on how to use Terraform modules, covering everything from creating your first module to integrating community modules and optimizing your infrastructure deployments. Whether you are a beginner or an experienced user, mastering modules will improve your Terraform workflow and infrastructure management.

Step-by-Step Guide

1. Understanding Terraform Modules

A Terraform module is a container for multiple resources that are used together. Every Terraform configuration has at least one module, known as the root module, which consists of the resources defined in the main configuration files. Additional modules can be called from the root module to encapsulate reusable logic.

2. Creating a Basic Module

To create your own module, follow these steps:

  1. Create a directory for your module, e.g., modules/network.
  2. Inside the directory, add Terraform configuration files like main.tf, variables.tf, and outputs.tf.
  3. Define your resources in main.tf. For example, create a VPC or subnet resources.
  4. Declare input variables in variables.tf to parameterize the module.
  5. Define outputs in outputs.tf to expose useful information to the calling module.

3. Using a Module in Your Root Configuration

Once your module is ready, use it in your root configuration as follows:

module "network" {

source = "./modules/network"

vpc_cidr = "10.0.0.0/16"

public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]

}

The source attribute points to the module path (local directory, Git repo, or Terraform Registry). You then pass the required variables as arguments.

4. Initializing and Applying Terraform

Run these commands in your root configuration directory:

  1. terraform init Initializes the working directory and downloads modules.
  2. terraform plan Shows the changes Terraform will make.
  3. terraform apply Applies the changes to your infrastructure.

5. Using Remote Modules

Terraform supports modules hosted remotely, such as:

  • Terraform Registry: Official and community modules.
  • Git repositories: Public or private repos.
  • HTTP URLs: Tarball archives accessible over HTTP.

Example using a module from Terraform Registry:

module "vpc" {

source = "terraform-aws-modules/vpc/aws"

version = "3.14.0"

name = "my-vpc"

cidr = "10.0.0.0/16"

azs = ["us-west-2a", "us-west-2b"]

public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]

}

6. Versioning and Module Updates

Always specify module versions when using remote sources to prevent unexpected changes. Use the terraform init -upgrade command to update modules safely.

Best Practices

1. Keep Modules Focused and Small

Design modules to perform a single, clear function. This improves reusability and makes testing easier.

2. Use Input Variables and Outputs Effectively

Parameterize your modules with input variables to make them flexible. Use outputs to expose essential data to the root module or other modules.

3. Avoid Hardcoding Values

Hardcoding values reduces flexibility and reusability. Instead, rely on input variables with sensible defaults.

4. Document Your Modules

Include README files explaining module purpose, inputs, outputs, and usage examples. This facilitates onboarding and collaboration.

5. Use Module Versioning

Pin module versions, especially for remote modules, to ensure stability and predictable deployments.

6. Test Modules Independently

Use tools like terraform validate and terraform plan to test modules. Consider automated testing frameworks such as Terratest.

7. Leverage the Terraform Registry

Use community modules from the Terraform Registry where appropriate to save time and leverage best practices.

Tools and Resources

1. Terraform CLI

The primary tool to write, initialize, plan, and apply your Terraform configurations and modules.

2. Terraform Registry

A centralized repository of publicly available modules that can be used directly or customized.

3. Terratest

An automated testing framework for Terraform modules using Go language, enabling integration and unit testing.

4. Visual Studio Code with Terraform Extensions

Popular IDE with extensions that provide syntax highlighting, linting, and autocompletion for Terraform files.

5. GitHub and GitLab

Version control platforms to store and manage your Terraform modules collaboratively.

6. Sentinel

HashiCorps policy as code framework to enforce governance and compliance on Terraform runs.

Real Examples

Example 1: Creating a Reusable AWS VPC Module

modules/vpc/main.tf

resource "aws_vpc" "this" {

cidr_block = var.cidr_block

tags = {

Name = var.name

}

}

resource "aws_subnet" "public" {

count = length(var.public_subnets)

cidr_block = var.public_subnets[count.index]

vpc_id = aws_vpc.this.id

map_public_ip_on_launch = true

tags = {

Name = "${var.name}-public-${count.index}"

}

}

modules/vpc/variables.tf

variable "cidr_block" {

description = "The CIDR block for the VPC"

type = string

}

variable "public_subnets" {

description = "List of public subnet CIDR blocks"

type = list(string)

}

variable "name" {

description = "Name tag for resources"

type = string

}

modules/vpc/outputs.tf

output "vpc_id" {

value = aws_vpc.this.id

}

output "public_subnet_ids" {

value = aws_subnet.public[*].id

}

Root module usage:

module "vpc" {

source = "./modules/vpc"

cidr_block = "10.0.0.0/16"

public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]

name = "my-vpc"

}

output "vpc_id" {

value = module.vpc.vpc_id

}

Example 2: Using a Community Module from Terraform Registry

Using the popular terraform-aws-modules/vpc/aws module:

module "vpc" {

source = "terraform-aws-modules/vpc/aws"

version = "3.14.0"

name = "example-vpc"

cidr = "10.1.0.0/16"

azs = ["us-east-1a", "us-east-1b"]

public_subnets = ["10.1.1.0/24", "10.1.2.0/24"]

enable_nat_gateway = true

single_nat_gateway = true

}

FAQs

Q1: What is the difference between a root module and a child module?

The root module is the directory where Terraform is initially run, containing your main configuration files. Child modules are reusable modules called from the root module or other modules to organize and modularize your code.

Q2: Can I use modules from private Git repositories?

Yes, Terraform supports modules from private Git repositories. You need to configure authentication (SSH keys or HTTPS credentials) to access private repositories.

Q3: How do I pass variables between modules?

You pass variables to modules via input variables defined in the module and set in the calling configuration. Outputs from one module can be passed as inputs to another.

Q4: How do I handle breaking changes in modules?

Pin module versions to avoid unexpected breaking changes. When upgrading, review the changelog and test thoroughly before applying to production.

Q5: Are modules supported in all Terraform providers?

Yes, modules are a core Terraform feature and work with all providers. The resources inside a module depend on the provider used.

Conclusion

Terraform modules are a powerful means to organize, reuse, and scale your infrastructure code. By encapsulating resources into modular units, you can simplify complex configurations, improve collaboration, and enforce best practices. Whether creating custom modules or leveraging community offerings, mastering modules is key to unlocking Terraforms full potential.

Follow the step-by-step guide, adopt best practices, and use available tools to maximize the benefits of Terraform modules in your infrastructure projects. This approach will lead to cleaner, more maintainable, and scalable infrastructure as code deployments.