Terraform 模块基础 #
什么是模块? #
模块是 Terraform 配置的容器,用于组织、封装和复用相关资源。每个 Terraform 配置至少包含一个模块(根模块),也可以包含多个子模块。
text
┌─────────────────────────────────────────────────────────────┐
│ 模块的作用 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 代码复用 │ │ 封装抽象 │ │ 组织管理 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ - 相同配置多次使用 │
│ - 隐藏实现细节 │
│ - 简化配置 │
│ - 标准化基础设施 │
│ │
└─────────────────────────────────────────────────────────────┘
模块结构 #
基本结构 #
text
modules/
└── vpc/
├── main.tf 主要资源配置
├── variables.tf 输入变量
├── outputs.tf 输出值
└── README.md 模块文档
完整结构 #
text
modules/
└── vpc/
├── main.tf 主要资源配置
├── variables.tf 输入变量定义
├── outputs.tf 输出值定义
├── versions.tf 版本约束
├── providers.tf Provider 配置
├── locals.tf 本地值
├── data.tf 数据源
├── README.md 模块文档
└── examples/
└── complete/
├── main.tf
└── outputs.tf
使用模块 #
模块源 #
hcl
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
}
模块源类型 #
text
┌─────────────────────────────────────────────────────────────┐
│ 模块源类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 本地路径: │
│ source = "./modules/vpc" │
│ │
│ Terraform Registry: │
│ source = "hashicorp/consul/aws" │
│ │
│ GitHub: │
│ source = "github.com/hashicorp/terraform-aws-consul" │
│ │
│ Git: │
│ source = "git::https://example.com/vpc.git" │
│ │
│ S3: │
│ source = "s3::https://s3.amazonaws.com/bucket/module.zip" │
│ │
│ GCS: │
│ source = "gcs::https://www.googleapis.com/storage/v1/..." │
│ │
└─────────────────────────────────────────────────────────────┘
本地模块 #
hcl
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
environment = "production"
project_name = "my-project"
}
Registry 模块 #
hcl
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
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"]
}
GitHub 模块 #
hcl
module "consul" {
source = "github.com/hashicorp/terraform-aws-consul"
cluster_name = "my-consul"
}
Git 模块 #
hcl
module "vpc" {
source = "git::https://example.com/terraform-modules/vpc.git"
vpc_cidr = "10.0.0.0/16"
}
module "vpc" {
source = "git::https://example.com/terraform-modules.git//vpc"
vpc_cidr = "10.0.0.0/16"
}
module "vpc" {
source = "git::https://example.com/terraform-modules.git//vpc?ref=v1.0.0"
vpc_cidr = "10.0.0.0/16"
}
S3 模块 #
hcl
module "vpc" {
source = "s3::https://s3.amazonaws.com/my-modules/vpc.zip"
vpc_cidr = "10.0.0.0/16"
}
模块版本 #
版本约束 #
hcl
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = ">= 5.0.0, < 6.0.0"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
}
版本约束语法 #
text
┌─────────────────────────────────────────────────────────────┐
│ 版本约束语法 │
├─────────────────────────────────────────────────────────────┤
│ │
│ "1.0.0" 精确版本 │
│ "!= 1.0.0" 排除特定版本 │
│ "> 1.0.0" 大于 │
│ "< 1.0.0" 小于 │
│ ">= 1.0.0" 大于等于 │
│ "<= 1.0.0" 小于等于 │
│ "~> 1.0" 1.x.x │
│ "~> 1.0.0" 1.0.x │
│ │
└─────────────────────────────────────────────────────────────┘
创建模块 #
模块文件 #
variables.tf #
hcl
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16"
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
}
variable "public_subnet_cidrs" {
description = "CIDR blocks for public subnets"
type = list(string)
}
variable "private_subnet_cidrs" {
description = "CIDR blocks for private subnets"
type = list(string)
default = []
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
main.tf #
hcl
locals {
name_prefix = "${var.environment}-vpc"
common_tags = merge(var.tags, {
Environment = var.environment
ManagedBy = "terraform"
})
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = merge(local.common_tags, {
Name = local.name_prefix
})
}
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-public-${count.index + 1}"
Tier = "public"
})
}
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-private-${count.index + 1}"
Tier = "private"
})
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-igw"
})
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-public-rt"
})
}
resource "aws_route_table_association" "public" {
count = length(aws_subnet.public)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
outputs.tf #
hcl
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.main.id
}
output "vpc_cidr_block" {
description = "The CIDR block of the VPC"
value = aws_vpc.main.cidr_block
}
output "public_subnet_ids" {
description = "List of public subnet IDs"
value = aws_subnet.public[*].id
}
output "private_subnet_ids" {
description = "List of private subnet IDs"
value = aws_subnet.private[*].id
}
output "internet_gateway_id" {
description = "The ID of the Internet Gateway"
value = aws_internet_gateway.main.id
}
模块输入 #
传递输入变量 #
hcl
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"]
environment = "production"
tags = {
Project = "my-project"
}
}
使用变量传递 #
hcl
variable "vpc_config" {
type = object({
vpc_cidr = string
availability_zones = list(string)
public_subnet_cidrs = list(string)
private_subnet_cidrs = list(string)
})
}
module "vpc" {
source = "./modules/vpc"
vpc_cidr = var.vpc_config.vpc_cidr
availability_zones = var.vpc_config.availability_zones
public_subnet_cidrs = var.vpc_config.public_subnet_cidrs
private_subnet_cidrs = var.vpc_config.private_subnet_cidrs
}
模块输出 #
访问模块输出 #
hcl
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
}
resource "aws_instance" "web" {
subnet_id = module.vpc.public_subnet_ids[0]
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
output "network_info" {
value = {
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.public_subnet_ids
}
}
模块初始化 #
初始化模块 #
bash
terraform init
更新模块 #
bash
terraform init -upgrade
获取模块 #
bash
terraform get
terraform get -update
模块最佳实践 #
1. 标准文件结构 #
text
modules/
└── vpc/
├── main.tf
├── variables.tf
├── outputs.tf
├── README.md
└── examples/
└── complete/
└── main.tf
2. 添加描述 #
hcl
variable "vpc_cidr" {
description = "CIDR block for the VPC. Must be a valid IPv4 CIDR."
type = string
validation {
condition = can(cidrhost(var.vpc_cidr, 0))
error_message = "Must be a valid IPv4 CIDR block."
}
}
3. 提供默认值 #
hcl
variable "enable_dns_hostnames" {
description = "Enable DNS hostnames in the VPC"
type = bool
default = true
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
4. 使用版本约束 #
hcl
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0.0"
}
}
}
5. 编写文档 #
markdown
# VPC Module
## Description
This module creates a VPC with public and private subnets.
## Usage
```hcl
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
}
Inputs #
| Name | Description | Type | Default |
|---|---|---|---|
| vpc_cidr | CIDR block for VPC | string | “10.0.0.0/16” |
Outputs #
| Name | Description |
|---|---|
| vpc_id | The ID of the VPC |
text
## 下一步
掌握了模块基础后,接下来学习 [模块组合](/docs/terraform/modules/module-composition),了解如何组合多个模块构建复杂架构!
最后更新:2026-03-29