What is Terraform Module
A Terraform module is a collection of Terraform resources, variables, and outputs that are organized within a single directory. Each module can be used to encapsulate a specific piece of functionality, such as provisioning a virtual machine, creating a database, or configuring a load balancer. By creating modules, you can define reusable building blocks for your infrastructure and share them across different projects, teams, or even the broader Terraform community.
Advantage and Disadvantage of Terraform Modules
In this chapter, I will discuss the advantages and disadvantages of using Terraform modules, which will help you make informed decisions when deciding whether or not to use them in your infrastructure projects.
Advantages of Terraform Modules
-
Modularity
Modules promote modularity in your infrastructure code, making it easier to understand, maintain, and scale. -
Reusability
Modules can be reused across multiple projects, reducing code duplication and promoting consistency. -
Collaboration
Modules facilitate collaboration by allowing teams to share and contribute to standardized infrastructure components. -
Abstraction
Modules encapsulate complex infrastructure patterns, simplifying the user's interaction with resources. -
Community
The Terraform community provides numerous open-source modules, enabling you to leverage existing solutions and reduce development time.
Disadvantages of Terraform Modules
-
Complexity
Introducing modules can increase the complexity of your infrastructure code, especially when dealing with nested modules or intricate dependencies. -
Versioning
Managing module versions can be challenging, particularly when dealing with breaking changes or rapidly evolving infrastructure components. -
Debugging
Debugging issues within a module can be more difficult due to the additional layer of abstraction. -
Customization
Modules may limit customization options, especially if they are designed to enforce specific patterns or practices. -
Learning curve
Using advanced module techniques may require additional knowledge and experience with Terraform.
Creating and Using Terraform Modules
In this chapter, I'll explore the process of creating and using Terraform modules in your infrastructure projects. We will cover module structure and conventions, defining input and output variables, and working with module versioning and consumption.
Module Structure and Conventions
A Terraform module is organized within a single directory that contains a set of Terraform configuration files (.tf
). These files define resources, variables, outputs, and other elements required to describe the module's functionality. A typical module directory structure may look like the following:
my_module/
├── main.tf
├── variables.tf
├── outputs.tf
├── README.md
└── LICENSE
main.tf
: Contains the primary module resources and is often the entry point for module consumers.variables.tf
: Defines input variables that users can set when consuming the module.outputs.tf
: Specifies output variables that the module exposes, allowing users to access information about the resources created within the module.README.md
: Provides documentation about the module's purpose, usage, and configuration options.LICENSE
: Specifies the license for the module's code, which is important if you plan to share it with others.
Defining Input and Output Variables
Input variables allow module users to customize the behavior of your module according to their needs. To define an input variable, use the variable
block in your variables.tf
file:
variable "instance_type" {
description = "The instance type for the virtual machine"
type = string
default = "t2.micro"
}
Output variables enable users to access information about the resources created within the module. To define an output variable, use the output
block in your outputs.tf
file:
output "instance_public_ip" {
description = "The public IP address of the virtual machine"
value = aws_instance.example.public_ip
}
Versioning and Publishing Modules
Using versioning with your Terraform modules helps ensure that consumers can rely on a stable, tested version of your module. Semantic versioning (e.g., "1.2.3") is a common approach for managing module versions. When publishing a module, you can use a Git repository or the Terraform Registry as the distribution mechanism.
Importing and Consuming Modules
To use a module in your Terraform configuration, declare a module
block and specify the source of the module. The source
attribute can be a local path, a Git repository, or a Terraform Registry URL:
module "virtual_machine" {
source = "git::https://example.com/my_module.git?ref=v1.2.3"
instance_type = "t2.small"
}
With the module imported, you can now access its output variables using the module.<MODULE_NAME>.<OUTPUT_NAME>
syntax:
output "vm_public_ip" {
value = module.virtual_machine.instance_public_ip
}
By creating and using Terraform modules, you can improve the organization, reusability, and maintainability of your infrastructure code.
AWS VPC Terraform Module
In this chapter, I will explore a real-world example of using a Terraform module to create an Amazon Web Services (AWS) Virtual Private Cloud (VPC).
The AWS VPC module is a popular community-contributed module that simplifies the creation of a VPC with public and private subnets. The module creates various resources, including VPC, subnets, route tables, and network access control lists (ACLs).
You can find the AWS VPC module in the Terraform Registry:
To use the AWS VPC module in your Terraform configuration, declare a module block and specify the module source from the Terraform Registry:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["us-west-2a", "us-west-2b", "us-west-2c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = false
enable_dns_hostnames = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
In this example, the AWS VPC module is used to create a VPC with three public and three private subnets distributed across three availability zones. The VPC is configured with NAT gateways and DNS hostnames enabled. Additionally, custom tags are applied to the resources created by the module.
The AWS VPC module provides various output variables that allow you to access information about the created resources. In this example, we access the VPC ID and the private subnet IDs:
output "vpc_id" {
description = "The ID of the created VPC"
value = module.vpc.vpc_id
}
output "private_subnet_ids" {
description = "The IDs of the created private subnets"
value = module.vpc.private_subnets
}
These outputs can be used in other parts of your Terraform configuration or passed to other modules as inputs.
References