Terraform 模块组合 #

模块组合概述 #

模块组合是将多个模块组织在一起,构建复杂基础设施架构的方式。通过组合模块,可以实现更高层次的抽象和复用。

text
┌─────────────────────────────────────────────────────────────┐
│                    模块组合架构                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│                    ┌─────────────┐                          │
│                    │  根模块     │                          │
│                    └──────┬──────┘                          │
│                           │                                 │
│          ┌────────────────┼────────────────┐               │
│          │                │                │               │
│          ▼                ▼                ▼               │
│    ┌──────────┐    ┌──────────┐    ┌──────────┐           │
│    │ VPC 模块  │    │ EC2 模块  │    │ RDS 模块  │           │
│    └──────────┘    └──────────┘    └──────────┘           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

模块间数据传递 #

输出传递 #

hcl
module "vpc" {
  source = "./modules/vpc"
  
  vpc_cidr = "10.0.0.0/16"
}

module "ec2" {
  source = "./modules/ec2"
  
  subnet_ids = module.vpc.public_subnet_ids
  vpc_id     = module.vpc.vpc_id
}

module "rds" {
  source = "./modules/rds"
  
  subnet_ids = module.vpc.private_subnet_ids
  vpc_id     = module.vpc.vpc_id
}

依赖链 #

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

module "security_group" {
  source = "./modules/security-group"
  
  vpc_id = module.vpc.vpc_id
}

module "ec2" {
  source = "./modules/ec2"
  
  subnet_id         = module.vpc.public_subnet_ids[0]
  security_group_id = module.security_group.id
}

module "alb" {
  source = "./modules/alb"
  
  subnet_ids         = module.vpc.public_subnet_ids
  security_group_id  = module.security_group.id
  target_instance_id = module.ec2.instance_id
}

嵌套模块 #

模块嵌套结构 #

text
modules/
├── networking/
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│   └── modules/
│       ├── vpc/
│       └── subnets/
├── compute/
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│   └── modules/
│       ├── ec2/
│       └── asg/
└── database/
    ├── main.tf
    ├── variables.tf
    ├── outputs.tf
    └── modules/
        └── rds/

嵌套模块调用 #

hcl
module "networking" {
  source = "./modules/networking"
  
  vpc_cidr    = "10.0.0.0/16"
  environment = "production"
}

module "vpc" {
  source = "./modules/networking/modules/vpc"
  
  cidr_block = var.vpc_cidr
}

module "subnets" {
  source = "./modules/networking/modules/subnets"
  
  vpc_id = module.vpc.id
}

模块设计模式 #

1. 分层架构 #

text
┌─────────────────────────────────────────────────────────────┐
│                    分层架构                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  应用层                                                     │
│  └── 应用配置、环境变量                                    │
│                                                             │
│  服务层                                                     │
│  └── EC2、ECS、Lambda                                      │
│                                                             │
│  数据层                                                     │
│  └── RDS、ElastiCache、S3                                  │
│                                                             │
│  网络层                                                     │
│  └── VPC、Subnet、Security Group                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘
hcl
module "network" {
  source = "./modules/network"
  
  vpc_cidr = var.vpc_cidr
}

module "data" {
  source = "./modules/data"
  
  vpc_id     = module.network.vpc_id
  subnet_ids = module.network.private_subnet_ids
}

module "service" {
  source = "./modules/service"
  
  vpc_id         = module.network.vpc_id
  subnet_ids     = module.network.public_subnet_ids
  db_endpoint    = module.data.db_endpoint
}

module "application" {
  source = "./modules/application"
  
  service_endpoint = module.service.endpoint
}

2. 资源组合模式 #

hcl
module "web_app" {
  source = "./modules/web-app"
  
  vpc_config = {
    vpc_cidr           = "10.0.0.0/16"
    availability_zones = ["us-east-1a", "us-east-1b"]
  }
  
  compute_config = {
    instance_type = "t2.micro"
    min_size      = 2
    max_size      = 4
  }
  
  database_config = {
    engine         = "mysql"
    instance_class = "db.t3.micro"
  }
}

3. 包装器模式 #

hcl
module "vpc" {
  source = "./modules/vpc-wrapper"
  
  environment = var.environment
  project     = var.project_name
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"
  
  name = "${var.environment}-${var.project}-vpc"
  cidr = var.vpc_cidr
  
  azs             = var.availability_zones
  private_subnets = var.private_subnet_cidrs
  public_subnets  = var.public_subnet_cidrs
}

4. 工厂模式 #

hcl
variable "environments" {
  default = {
    dev = {
      instance_type = "t2.micro"
      min_size      = 1
      max_size      = 2
    }
    staging = {
      instance_type = "t2.small"
      min_size      = 2
      max_size      = 4
    }
    prod = {
      instance_type = "t2.medium"
      min_size      = 3
      max_size      = 6
    }
  }
}

module "environment" {
  source   = "./modules/environment"
  for_each = var.environments
  
  environment    = each.key
  instance_type  = each.value.instance_type
  min_size       = each.value.min_size
  max_size       = each.value.max_size
}

复合模块示例 #

Web 应用模块 #

hcl
module "web_app" {
  source = "./modules/web-app"
  
  environment  = var.environment
  project_name = var.project_name
  
  vpc_cidr             = var.vpc_cidr
  availability_zones   = var.availability_zones
  public_subnet_cidrs  = var.public_subnet_cidrs
  private_subnet_cidrs = var.private_subnet_cidrs
  
  instance_type = var.instance_type
  min_size      = var.min_size
  max_size      = var.max_size
  
  db_engine         = var.db_engine
  db_instance_class = var.db_instance_class
  db_name           = var.db_name
  
  domain_name = var.domain_name
  
  tags = var.tags
}

modules/web-app/main.tf #

hcl
module "vpc" {
  source = "../vpc"
  
  vpc_cidr             = var.vpc_cidr
  availability_zones   = var.availability_zones
  public_subnet_cidrs  = var.public_subnet_cidrs
  private_subnet_cidrs = var.private_subnet_cidrs
  environment          = var.environment
  tags                 = var.tags
}

module "security_groups" {
  source = "../security-groups"
  
  vpc_id      = module.vpc.vpc_id
  vpc_cidr    = module.vpc.vpc_cidr_block
  environment = var.environment
  tags        = var.tags
}

module "alb" {
  source = "../alb"
  
  vpc_id             = module.vpc.vpc_id
  subnet_ids         = module.vpc.public_subnet_ids
  security_group_ids = [module.security_groups.alb_id]
  environment        = var.environment
  tags               = var.tags
}

module "asg" {
  source = "../asg"
  
  vpc_id             = module.vpc.vpc_id
  subnet_ids         = module.vpc.private_subnet_ids
  security_group_ids = [module.security_groups.web_id]
  target_group_arn   = module.alb.target_group_arn
  instance_type      = var.instance_type
  min_size           = var.min_size
  max_size           = var.max_size
  environment        = var.environment
  tags               = var.tags
}

module "rds" {
  source = "../rds"
  
  vpc_id             = module.vpc.vpc_id
  subnet_ids         = module.vpc.private_subnet_ids
  security_group_ids = [module.security_groups.db_id]
  engine             = var.db_engine
  instance_class     = var.db_instance_class
  db_name            = var.db_name
  environment        = var.environment
  tags               = var.tags
}

三层架构 #

hcl
module "three_tier" {
  source = "./modules/three-tier"
  
  environment = var.environment
  
  web_config = {
    instance_type = "t2.micro"
    min_size      = 2
    max_size      = 4
  }
  
  app_config = {
    instance_type = "t2.small"
    min_size      = 2
    max_size      = 6
  }
  
  db_config = {
    engine         = "mysql"
    instance_class = "db.t3.small"
    multi_az       = true
  }
}

模块依赖管理 #

隐式依赖 #

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

module "ec2" {
  source = "./modules/ec2"
  
  subnet_id = module.vpc.public_subnet_ids[0]
}

显式依赖 #

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

module "ec2" {
  source = "./modules/ec2"
  
  subnet_id = module.vpc.public_subnet_ids[0]
  
  depends_on = [module.vpc]
}

模块组合最佳实践 #

1. 单一职责 #

text
┌─────────────────────────────────────────────────────────────┐
│                    单一职责原则                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  好的设计:                                                 │
│  ├── vpc 模块 - 只负责 VPC                                 │
│  ├── subnet 模块 - 只负责子网                              │
│  └── security-group 模块 - 只负责安全组                    │
│                                                             │
│  不好的设计:                                               │
│  └── network 模块 - 包含 VPC、子网、安全组、NAT 网关...    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 清晰的接口 #

hcl
variable "vpc_id" {
  description = "The ID of the VPC where resources will be created"
  type        = string
}

variable "subnet_ids" {
  description = "List of subnet IDs for the load balancer"
  type        = list(string)
}

variable "security_group_ids" {
  description = "List of security group IDs to attach to the load balancer"
  type        = list(string)
}

3. 合理的抽象层次 #

hcl
module "network" {
  source = "./modules/network"
  
  cidr_block = "10.0.0.0/16"
}

module "network" {
  source = "./modules/network"
  
  config = {
    vpc_cidr           = "10.0.0.0/16"
    availability_zones = ["us-east-1a", "us-east-1b"]
    public_subnets     = ["10.0.1.0/24", "10.0.2.0/24"]
    private_subnets    = ["10.0.11.0/24", "10.0.12.0/24"]
  }
}

4. 文档化 #

hcl
variable "instance_config" {
  description = <<-EOT
    Configuration for EC2 instances.
    
    - instance_type: EC2 instance type (e.g., t2.micro)
    - min_size: Minimum number of instances
    - max_size: Maximum number of instances
    - desired_size: Desired number of instances
    
    Example:
    ```
    instance_config = {
      instance_type = "t2.micro"
      min_size      = 1
      max_size      = 3
      desired_size  = 2
    }
    ```
  EOT
  type = object({
    instance_type = string
    min_size      = number
    max_size      = number
    desired_size  = number
  })
}

下一步 #

掌握了模块组合后,接下来学习 模块最佳实践,了解如何设计高质量、可维护的模块!

最后更新:2026-03-29