What is a Module in Terraform? - unix1998/technical_notes GitHub Wiki

In Terraform, a module is indeed a container for multiple resources that are used together. Let's delve into what a module is and how it functions within Terraform.

What is a Module in Terraform?

A module in Terraform is a collection of .tf configuration files in a directory. These files define resources, variables, outputs, and other Terraform components that can be reused and shared. Essentially, a module is a way to encapsulate and reuse configuration blocks, enabling better organization and modularity in your infrastructure as code.

Key Concepts

  1. Root Module:

    • When you run terraform apply or terraform plan, Terraform starts with the configuration files in the directory where you run the command. This directory is considered the root module.
    • The root module can call other modules (referred to as child modules) to help structure and reuse configurations.
  2. Child Modules:

    • These are modules that are called from within another module (including the root module). They are typically located in a separate directory and are referenced by the root module or other modules.
  3. Module Source:

    • You can source modules from different locations:
      • Local Path: Modules stored in a local directory.
      • Version Control: Modules stored in a Git repository.
      • Terraform Registry: Public modules available from the Terraform Registry.
      • URLs: Modules available at a specific URL.

Structure of a Module

A typical module consists of the following files:

  • main.tf: Contains the primary set of configuration for resources.
  • variables.tf: Defines the input variables for the module.
  • outputs.tf: Defines the outputs that the module exports.
  • providers.tf: Specifies provider configurations if needed.
  • README.md (optional): Provides documentation about the module.

Example of Using a Module

Root Module (Main Configuration)

provider "aws" {
  region = "us-west-2"
}

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

  cidr_block = "10.0.0.0/16"
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
}

module "ec2_instances" {
  source = "./modules/ec2"

  instance_count = 2
  instance_type  = "t2.micro"
  vpc_id         = module.vpc.vpc_id
  subnets        = module.vpc.private_subnets
}

VPC Module (./modules/vpc)

main.tf:

resource "aws_vpc" "main" {
  cidr_block = var.cidr_block
}

resource "aws_subnet" "private" {
  count             = length(var.private_subnets)
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnets[count.index]
  availability_zone = element(local.azs, count.index)
}

resource "aws_subnet" "public" {
  count             = length(var.public_subnets)
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnets[count.index]
  availability_zone = element(local.azs, count.index)
}

output "vpc_id" {
  value = aws_vpc.main.id
}

output "private_subnets" {
  value = aws_subnet.private[*].id
}

variables.tf:

variable "cidr_block" {
  type = string
}

variable "private_subnets" {
  type = list(string)
}

variable "public_subnets" {
  type = list(string)
}

EC2 Module (./modules/ec2)

main.tf:

resource "aws_instance" "example" {
  count         = var.instance_count
  instance_type = var.instance_type
  ami           = "ami-0c55b159cbfafe1f0" # Example AMI ID
  subnet_id     = element(var.subnets, count.index)

  tags = {
    Name = "example-instance-${count.index}"
  }
}

output "instance_ids" {
  value = aws_instance.example[*].id
}

variables.tf:

variable "instance_count" {
  type = number
}

variable "instance_type" {
  type = string
}

variable "vpc_id" {
  type = string
}

variable "subnets" {
  type = list(string)
}

Benefits of Using Modules

  • Reusability: Modules allow you to reuse the same configuration code across different parts of your infrastructure or even across different projects.
  • Maintainability: By breaking down your infrastructure into smaller, reusable modules, it becomes easier to manage and update.
  • Encapsulation: Modules encapsulate and abstract away complexity, making your Terraform configurations more readable and organized.

Conclusion

Terraform modules are a powerful feature that enables you to organize your infrastructure as code into reusable and maintainable components. By understanding and leveraging modules, you can create more scalable, modular, and efficient Terraform configurations.