All Products
Search
Document Center

Terraform:What are Terraform modules?

Last Updated:Apr 08, 2025

This topic introduces Terraform modules.

What are Terraform modules?

Terraform modules are one of the key and basic unit in the Infrastructure as code (IaC) ecosystem of Terraform for organizing and reusing Terraform code. As the cloud infrastructure scales out, it becomes a great challenge to maintain and manage all infrastructure configurations in a single Terraform file. To facilitate reading and management, Terraform modules allow you to encapsulate infrastructure configurations into a reusable component that can be shared with other users. Modulization is the foundation for building maintainable, scalable, and standardized infrastructure code. It is suitable for cloud infrastructure management scenarios, especially for large-scale, multi-environment, and team collaboration.

A Terraform module is a collection of resources that can be regarded as the functions of the infrastructure code. Terraform modules provide an abstraction mechanism by defining input variables, output values, and resource configurations. This mechanism allows you to reuse complex infrastructure components in a simplified approach. It not only increases the code reuse rate and reduces the maintenance cost, but also promotes the implementation of standard and best practices within your organization.

Why Terraform modules?

When you use Terraform to manage Alibaba Cloud infrastructures, you may need to repeatedly deploy similar resources. For example, you may need to create multiple Elastic Compute Service (ECS) instances in a custom network and each ECS instance contains the following attributes:

  1. Instance type (instance_type)

  2. Disk specification (system_disk_category and data_disks)

  3. Elastic IP Address (EIP)

  4. Image ID

  5. ...

If you do not use Terraform modules, you may need to repeatedly write the same code:

resource "alicloud_instance" "web_server" {
  instance_type        = "ecs.g6.large"
  system_disk_category = "cloud_essd"
  security_groups      = ["sg-12sfew2"]
  instance_name        = "web-server"
  vswitch_id           = "vsw-12345"
  image_id             = "ubuntu_18_04_64_20G_alibase_20190624.vhd"
}

resource "alicloud_eip_address" "web_server" {
  bandwidth            = "5"
  internet_charge_type = "PayByBandwidth"
}

resource "alicloud_eip_association" "web_server" {
  instance_id   = alicloud_instance.web_server.id
  allocation_id = alicloud_eip_address.web_server.id
}

This method raises the following issues:

  1. Duplicate code increases the maintenance difficulty.

  2. Multiple modifications are required in cases of configuration updates.

  3. User errors may be made.

  4. Poor code readability.

However, a Terraform module is a collection of configuration files in the same directory. Terraform modules provide the following benefits:

  1. Classify reusable code into the same category.

  2. Manage code as a module.

  3. Improve the code maintainability and reusability.

Terraform module types

Terraform provides two module types:

1. Root module

The root module is the main entrance for module configurations. It calls and organizes other modules.

# Root Module (main.tf)
# Note that if you want to publish the module or allow the module to be called by other modules, 
#we recommend that you do not define the provider block in the current code block, but define the provider block when you call the module. 
# In addition, use providers to pass the metadata. 
provider "alicloud" {
  region = "cn-hangzhou"
}

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

module "ecs" {
  source = "./modules/ecs"
  depends_on = [module.vpc]
}

2. Child modules

Child modules are called by the root module or other modules. Child modules are designed for specific features and can be repeatedly reused.

# Child Module (modules/vpc/main.tf)
resource "alicloud_vpc" "vpc" {
  vpc_name   = var.vpc_name
  cidr_block = var.vpc_cidr
}

# Call the module in the root module
module "vpc" {
  source = "./modules/vpc"
  vpc_name = "my-vpc"
  vpc_cidr = "172.16.0.0/16"
}

Example: Create a module

This example demonstrate how to create module for Alibaba Cloud resources. The module contains the network and server modules.

4.1 Directory structure

In this example, the following directory structure is used:

.
├── main.tf
├── modules
 ├── network
 │ ├── main.tf
 │ ├── variables.tf
 │ └── outputs.tf
 └── server
   ├── main.tf
   ├── variables.tf
   └── outputs.tf

4.2 Sample network module

# modules/network/main.tf

resource "alicloud_vpc" "vpc" {
  vpc_name   = var.vpc_name
  cidr_block = var.vpc_cidr
}

resource "alicloud_vswitch" "vsw" {
  vswitch_name = var.vswitch_name
  vpc_id       = alicloud_vpc.vpc.id
  cidr_block   = var.vswitch_cidr
  zone_id      = var.zone_id
}

resource "alicloud_security_group" "default" {
  security_group_name = var.security_group_name
  vpc_id              = alicloud_vpc.vpc.id
}
# modules/network/variables.tf

variable "vpc_name" {
  type        = string
  description = "Name of the VPC"
  default     = "terraform-vpc"
}

variable "vpc_cidr" {
  type        = string
  description = "CIDR block for the VPC"
  default     = "172.16.0.0/16"
}

variable "vswitch_name" {
  type        = string
  description = "Name of the VSwitch"
  default     = "terraform-vswitch"
}

variable "vswitch_cidr" {
  type        = string
  description = "CIDR block for the VSwitch"
  default     = "172.16.0.0/24"
}

variable "zone_id" {
  type        = string
  description = "Zone ID for the VSwitch"
  default     = "cn-hangzhou-i" # Replace the value with the region ID that you use.
}

variable "security_group_name" {
  type        = string
  description = "Name of the security group"
  default     = "terraform-security-group"
}
# modules/network/outputs.tf

output "security_group_id" {
  value       = alicloud_security_group.default.id
  description = "The ID of the security group"
}

output "vswitch_id" {
  value       = alicloud_vswitch.vsw.id
  description = "The ID of the vswitch"
}

output "vpc_id" {
  value       = alicloud_vpc.vpc.id
  description = "The ID of the VPC"
} 

4.3 Sample server module

# modules/server/main.tf

resource "alicloud_instance" "web" {
  instance_name        = var.instance_name
  instance_type        = var.instance_type
  security_groups      = [var.security_group_id]
  vswitch_id           = var.vswitch_id
  system_disk_category = var.disk_category
  image_id             = var.image_id
}

resource "alicloud_eip_address" "web" {
  bandwidth            = var.eip_bandwidth
  internet_charge_type = var.internet_charge_type
}

resource "alicloud_eip_association" "web" {
  instance_id   = alicloud_instance.web.id
  allocation_id = alicloud_eip_address.web.id
}
# modules/server/variables.tf

variable "instance_name" {
  type        = string
  description = "Name of the ECS instance"
  default     = "terraform-ecs"
}

variable "instance_type" {
  type        = string
  description = "Type of the ECS instance"
  default     = "ecs.n1.small" # Select an instance type based on your actual business requirements.
}

variable "security_group_id" {
  type        = string
  description = "ID of the security group"
}

variable "vswitch_id" {
  type        = string
  description = "ID of the vswitch"
}

variable "disk_category" {
  type        = string
  description = "Category of the system disk"
  default     = "cloud_efficiency"
}

variable "eip_bandwidth" {
  type        = number
  description = "Bandwidth for the EIP in Mbps"
  default     = 5
}

variable "internet_charge_type" {
  type        = string
  description = "Internet charge type for EIP"
  default     = "PayByTraffic"
}

variable "image_id" {
  type        = string
  description = "ID of the ECS image"
  default     = "ubuntu_18_04_64_20G_alibase_20190624.vhd" # By default, Ubuntu 18.04 is used.
}   
# modules/server/outputs.tf
output "server_id" {
  description = "The ID of the ECS instance"
  value       = alicloud_instance.web.id
}

output "server_ip" {
  description = "The public IP address of the server"
  value       = alicloud_eip_address.web.ip_address
}

4.4 Call the modules

Call the preceding modules in the root module, which is in the root directory main.tf.

provider "alicloud" {
  region = "cn-hangzhou"
}
module "network" {
  source = "./modules/network"

  vpc_name            = "my-vpc"
  vpc_cidr            = "10.0.0.0/16"
  vswitch_name        = "my-vsw"
  vswitch_cidr        = "10.0.1.0/24"
  zone_id             = "cn-hangzhou-i"
  security_group_name = "my-sg"
}

module "web_server" {
  source = "./modules/server"

  instance_name        = "web-server"
  instance_type        = "ecs.g6.large"
  security_group_id    = module.network.security_group_id
  vswitch_id           = module.network.vswitch_id
  disk_category        = "cloud_essd"
  eip_bandwidth        = "5"
  internet_charge_type = "PayByBandwidth"
}

As shown in the preceding example, Terraform modules facilitate the management of Alibaba Cloud infrastructure code and improve the code reusability and maintainability.