Module介绍

更新时间:2025-03-21 03:14:56

Terraform Module 介绍

什么是 Terraform Module?

Terraform Module(模块)是 Terraform 基础设施即代码(IaC)生态系统中的核心概念,用于组织和重用 Terraform 代码的基本单位。随着云基础设施规模的扩大,将所有基础设施配置都放在单个 Terraform 文件中会变得难以维护和管理。模块允许用户将基础设施配置封装为可重用、可共享的组件,使其更易于阅读和管理。模块化设计是构建可维护、可扩展和标准化基础设施代码的基础,特别适合于大规模、多环境或团队协作的云基础设施管理场景。

Terraform 模块本质上是一组相关资源的集合,可以将其视为基础设施代码的“函数”。通过定义输入变量、输出值和资源配置,模块提供了一种抽象机制,使复杂的基础设施组件可以以一致且简化的方式被重复部署。这不仅提高了代码重用率,降低了维护成本,还促进了组织内部的标准化实践和最佳实践的实施。

为什么需要 Terraform Module?

在使用 Terraform 管理阿里云基础设施时,我们经常会遇到需要重复创建相似资源的场景。例如,假设我们需要在自定义网络中创建多个 ECS 实例,每个实例都包含以下属性:

  1. 实例规格(instance_type)

  2. 磁盘配置(system_disk_category, data_disks)

  3. 弹性公网 IP

  4. 镜像 ID

  5. ...

如果不使用 Module,我们可能需要重复编写类似的代码:

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
}

使用这种方式存在以下问题:

  1. 代码重复,维护困难

  2. 更新配置需要修改多处

  3. 容易出现人为错误

  4. 代码可读性差

而 Terraform Module 是一组放置在同一目录下的 Terraform 配置文件的集合。它能够:

  1. 将可重用的代码组织在一起

  2. 实现代码的模块化管理

  3. 提高代码的可维护性和复用性

Module 的类型

在 Terraform 中,有两种主要的 Module 类型:

1. Root Module(根模块)

是 Module 配置的主入口,负责调用和组织其他模块

# Root Module (main.tf)
# 需要注意的是,如果这个 Module 要对外发布或者会被其他 Module 调用,
# 不建议在此处显示定义 provider 块,而是在调用此 Module 时进行定义,
# 并通过 providers 元数据进行传递。
provider "alicloud" {
  region = "cn-hangzhou"
}

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

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

2. Child Module(子模块)

被 Root Module 或其他模块调用的模块,专注于特定功能,可被多次重用

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

# 在 Root Module 中调用
module "vpc" {
  source = "./modules/vpc"
  vpc_name = "my-vpc"
  vpc_cidr = "172.16.0.0/16"
}

创建 Module 示例

让我们创建一个面向阿里云资源的 Module 示例,包含网络和服务器两个 Module:

4.1 目录结构

本示例中,Module 的目录结构如下所示:

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

4.2 网络模块示例(network)

# 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" # 请根据您的实际区域修改这个值
}

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 服务器模块示例(server)

# 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" # 根据需要选择合适的实例规格
}

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" # 默认使用 Ubuntu 18.04
}   
# 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 调用模块

在 Root Module(根目录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"
}

通过使用 Terraform Module,我们可以更好地管理阿里云基础设施代码,提高代码复用性和可维护性。

  • 本页导读 (1)
  • 什么是 Terraform Module?
  • 为什么需要 Terraform Module?
  • Module 的类型
  • 1. Root Module(根模块)
  • 2. Child Module(子模块)
  • 创建 Module 示例
  • 4.1 目录结构
  • 4.2 网络模块示例(network)
  • 4.3 服务器模块示例(server)
  • 4.4 调用模块