2023-03-10

Terraform Module

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:

tf
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:

tf
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:

tf
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:

tf
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:

https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest

To use the AWS VPC module in your Terraform configuration, declare a module block and specify the module source from the Terraform Registry:

tf
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:

tf
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

https://developer.hashicorp.com/terraform/language/modules
https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!