You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建Terraform子模块:AWS资源管理场景下的子模块实现与按需执行需求求助

没问题,我给你一个实操性很强的示例来实现这个需求,咱们一步步拆解:

第一步:调整目录结构

先把原来的单模块结构拆分成「主模块 + 子模块AB」的形式,假设你原来的目录是这样:

my-terraform-module/
├── main.tf
├── variables.tf
├── outputs.tf
├── A.tf
├── B.tf
└── other-resources.tf  # 其他不需要归入子模块的资源文件

现在调整为:

my-terraform-module/
├── main.tf
├── variables.tf
├── outputs.tf
├── other-resources.tf
└── sub-module-ab/  # 专门存放A.tf和B.tf资源的子模块
    ├── main.tf
    ├── variables.tf
    └── outputs.tf
第二步:重构子模块内容

把原来A.tf和B.tf里的所有资源代码,移动到sub-module-ab/main.tf中。举个具体例子,假设A.tf是S3桶、B.tf是IAM角色:

# sub-module-ab/main.tf
# 原A.tf的S3桶资源
resource "aws_s3_bucket" "ab_bucket" {
  bucket = var.bucket_name
  tags   = var.resource_tags
}

# 原B.tf的IAM角色资源
resource "aws_iam_role" "ab_role" {
  name = var.role_name

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      }
    ]
  })
}

然后给子模块定义所需的变量(sub-module-ab/variables.tf):

variable "bucket_name" {
  type        = string
  description = "Name for the S3 bucket in sub-module AB"
}

variable "role_name" {
  type        = string
  description = "Name for the IAM role in sub-module AB"
}

variable "resource_tags" {
  type        = map(string)
  description = "Tags to attach to sub-module resources"
  default     = {}
}

如果需要把亚模块的资源属性暴露给主模块使用,就加一个输出文件(sub-module-ab/outputs.tf):

output "bucket_arn" {
  type        = string
  description = "ARN of the S3 bucket from sub-module AB"
  value       = aws_s3_bucket.ab_bucket.arn
}

output "role_arn" {
  type        = string
  description = "ARN of the IAM role from sub-module AB"
  value       = aws_iam_role.ab_role.arn
}
第三步:在主模块中调用子模块

在主模块的main.tf里,添加对子模块AB的调用,把需要的变量传递进去:

# my-terraform-module/main.tf
# 调用子模块AB
module "ab" {
  source = "./sub-module-ab"  # 指向子模块的相对路径

  bucket_name   = var.sub_ab_bucket_name
  role_name     = var.sub_ab_role_name
  resource_tags = var.common_tags
}

# 主模块原有的其他资源(比如EC2实例)
resource "aws_instance" "main_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags          = var.common_tags
}

同时在主模块的variables.tf里补充子模块所需的变量定义:

variable "sub_ab_bucket_name" {
  type        = string
  description = "Bucket name for sub-module AB"
}

variable "sub_ab_role_name" {
  type        = string
  description = "Role name for sub-module AB"
}

variable "common_tags" {
  type        = map(string)
  description = "Shared tags for all resources"
  default     = {}
}
第四步:只部署子模块的资源

现在如果只想创建子模块AB里的资源,直接用-target参数指定子模块的地址即可:

terraform apply -target=module.ab

这个命令会让Terraform只处理module.ab下的所有资源,完全不会触碰主模块里的其他资源(比如上面的EC2实例)。

如果需要更精准,只想部署子模块里的某一个资源(比如S3桶),可以指定具体的资源地址:

terraform apply -target=module.ab.aws_s3_bucket.ab_bucket
一些注意点
  • 尽量保证子模块的资源是独立的,不要依赖主模块中未被指定的资源,否则用-target时可能会出现依赖缺失的报错
  • 后续如果要部署所有资源,直接运行terraform apply即可,不需要额外调整配置
  • 子模块的变量和输出要和主模块做好衔接,避免出现参数传递错误

内容的提问来源于stack exchange,提问作者wawawa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:57:29