Terraform Associate: Modules Overview

Chintan BogharaChintan Boghara
6 min read

Terraform modules are one of the most powerful features of HashiCorp's Terraform, allowing you to build and maintain your infrastructure as code in a modular, reusable, and organized manner. In this post, we'll explore what Terraform modules are, why they are essential, and how to structure and use them effectively in your projects.

What is a Terraform Module?

A Terraform module is a self-contained configuration that encapsulates a group of related resources. Think of it as a building block for your infrastructure—each module handles a specific piece of functionality, making your overall codebase more modular and easier to manage. By using modules, you can:

  • Promote Code Reuse: Write your configuration once and reuse it in different parts of your infrastructure.

  • Simplify Complex Deployments: Break down large configurations into smaller, more manageable pieces.

  • Ensure Consistency: Standardize infrastructure across various environments.

  • Enhance Maintainability: Simplify updates and foster collaboration among teams.

Why Use Terraform Modules?

Reusability

By encapsulating common patterns into modules, you only need to write the code once. This modular approach saves time and reduces the likelihood of errors when deploying similar resources in multiple environments.

Simplification

Large, monolithic Terraform configurations can be challenging to understand and maintain. Modules allow you to break these configurations into bite-sized pieces, making it easier to navigate and manage the code.

Consistency

Using modules ensures that best practices are consistently applied across your infrastructure. This is crucial in preventing configuration drift and ensuring that every environment is set up in a standardized way.

Maintainability

Modules make it easier to update and collaborate on infrastructure. If a particular component needs an update, you can modify the module, and the changes propagate wherever the module is used.

Module Structure

A typical Terraform module contains several key files:

  • main.tf – This file contains the primary resource definitions.

  • variables.tf – This file defines the input variables that allow customization of the module.

  • outputs.tf – This file specifies the outputs, exposing essential information about the resources created.

Directory Structure Example

my-module/
│── main.tf        # Defines resources
│── variables.tf   # Defines input variables
│── outputs.tf     # Defines output values

Building a Simple EC2 Module

Let’s walk through a simple example of an EC2 module.

1. Resource Definition (main.tf)

In this file, you define the resources that the module will create. For example, creating an AWS EC2 instance:

resource "aws_instance" "web" {
  ami           = var.ami
  instance_type = var.instance_type
}

2. Defining Input Variables (variables.tf)

To make the module reusable, you define variables that allow customization of key parameters:

variable "ami" {}
variable "instance_type" {}

3. Specifying Outputs (outputs.tf)

Expose important values, such as the instance ID, so they can be referenced in the parent configuration:

output "instance_id" {
  value = aws_instance.web.id
}

Using a Module in Your Terraform Configuration

Modules are invoked using the module block in your main configuration file. Here’s how you can call the EC2 module we just defined:

Local Module Example

module "web_server" {
  source        = "./my-module"
  ami           = "ami-12345678"
  instance_type = "t3.micro"
}

Remote Module Example

Terraform also supports using modules from remote sources like public or private repositories, or directly from the Terraform Registry. For instance, to use a VPC module from the Terraform Registry:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.14.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"
}

Passing Variables Dynamically

Modules accept input variables which can be passed dynamically. For example, you can pass variables from a terraform.tfvars file:

module "web_server" {
  source        = "./my-module"
  ami           = var.ami_id
  instance_type = var.instance_type
}

And in your terraform.tfvars:

ami_id = "ami-12345678"
instance_type = "t3.micro"

This approach makes your module flexible and adaptable to different environments and use cases.

Module Outputs: Extracting Useful Data

Outputs are essential for sharing information between modules and the root module. For example, after creating an EC2 instance, you might want to capture its instance ID:

output "web_instance_id" {
  value = module.web_server.instance_id
}

This output can then be used elsewhere in your configuration or for monitoring purposes.

Nested Modules: Building a Hierarchical Infrastructure

Modules can be nested, meaning one module can call another. This hierarchical approach is particularly useful for complex infrastructure setups where different components depend on each other.

Example Directory Structure for Nested Modules

network/
│── main.tf
│── modules/
│   │── vpc/
│   │── subnets/
│   │── security-groups/

Example of Calling a Nested Module

module "vpc" {
  source = "./modules/vpc"
}

module "subnets" {
  source = "./modules/subnets"
  vpc_id = module.vpc.vpc_id
}

In this example, the subnets module is dependent on the output of the vpc module, showcasing how modules can be composed together to build a complete network architecture.

Best Practices for Terraform Modules

When working with Terraform modules, following best practices can significantly improve the quality and maintainability of your infrastructure code:

  1. Consistent Structure: Stick to a standard file structure (main.tf, variables.tf, outputs.tf) for clarity and maintainability.

  2. Meaningful Naming: Use descriptive variable names and add descriptions to clarify their purpose.

  3. Single Responsibility: Keep modules small and focused on a single responsibility to reduce complexity.

  4. Version Control: When using remote modules, specify a version (e.g., version = "x.y.z") to ensure stability and reproducibility.

  5. Expose Key Outputs: Use output variables to expose important values that other modules or configurations might need.

  6. Documentation: Document the purpose, inputs, outputs, and dependencies of your modules so that team members can easily understand and use them.

Conclusion

Terraform modules are a cornerstone of effective infrastructure management, offering reusability, simplification, and consistency across environments. By breaking down your infrastructure into smaller, self-contained modules, you can achieve a more manageable and scalable codebase. Whether you are deploying a simple EC2 instance or building a complex multi-tier application, adopting a modular approach with Terraform can lead to more efficient and maintainable infrastructure as code.

Embrace Terraform modules to enhance your infrastructure management process, ensure consistency, and empower your team to collaborate more effectively on cloud deployments. Happy coding!

Reference

  1. Terraform Language: Modules Documentation
    This official documentation explains what Terraform modules are, how to build them, and why they’re essential for scalable infrastructure.

  2. Terraform Registry - Browse Modules
    The Terraform Registry offers a wide variety of pre-built modules, which you can use as references or directly integrate into your projects.

  3. DigitalOcean Tutorial: How to Use Terraform Modules
    This tutorial provides practical examples and step-by-step guidance on creating and leveraging Terraform modules for your infrastructure.

  4. HashiCorp Blog: Terraform Best Practices
    Explore best practices recommended by HashiCorp for writing, organizing, and maintaining Terraform configurations, including module design tips.

  5. Gruntwork Blog: Best Practices for Terraform Modules
    This guide covers strategies for designing robust and reusable Terraform modules, with a focus on modularity, code reuse, and maintainability.

11
Subscribe to my newsletter

Read articles from Chintan Boghara directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chintan Boghara
Chintan Boghara

Exploring DevOps ♾️, Cloud Computing ☁️, DevSecOps 🔒, Site Reliability Engineering ⚙️, Platform Engineering 🛠️, Machine Learning Operations 🤖, and AIOps 🧠