Terraform引用模块输出作为另一模块输入时count始终为0的问题
Terraform引用模块输出作为count值始终为0的问题
问题背景
使用Terraform v1.2.6及AWS provider v4.24.0,VPC模块输出包含3个可用区子网ID的列表protected_subnet_ids,将其传入NAT模块的target_subnets变量,并用length(var.target_subnets)作为aws_eip资源的count值,但count始终为0。在terraform console中能确认module.vpc.protected_subnet_ids确实有3个元素。
相关代码片段
VPC模块调用代码
module "vpc" { source = "sre-iac-modules/network/vpc" region_id = var.region_id env = var.env service_code = var.service_code common_tag = { CreatedBy = var.common_tag.CreatedBy, PeriodFrom = var.common_tag.PeriodFrom, PeriodTo = var.common_tag.PeriodTo, CostCenter = var.common_tag.CostCenter, Project = var.common_tag.Project } vpc = { cidr_block = var.vpc.cidr_block, protected_subnet_a_cidr = var.vpc.protected_subnet_a_cidr, protected_subnet_b_cidr = var.vpc.protected_subnet_b_cidr, protected_subnet_c_cidr = var.vpc.protected_subnet_c_cidr, tgw_subnet_a_cidr = var.vpc.tgw_subnet_a_cidr, tgw_subnet_b_cidr = var.vpc.tgw_subnet_b_cidr, tgw_subnet_c_cidr = var.vpc.tgw_subnet_c_cidr, workload_subnet_a_cidr = var.vpc.workload_subnet_a_cidr, workload_subnet_b_cidr = var.vpc.workload_subnet_b_cidr, workload_subnet_c_cidr = var.vpc.workload_subnet_c_cidr, redis_subnet_a_cidr = var.vpc.redis_subnet_a_cidr, redis_subnet_b_cidr = var.vpc.redis_subnet_b_cidr, redis_subnet_c_cidr = var.vpc.redis_subnet_c_cidr, db_subnet_a_cidr = var.vpc.db_subnet_a_cidr, db_subnet_b_cidr = var.vpc.db_subnet_b_cidr, db_subnet_c_cidr = var.vpc.db_subnet_c_cidr } } module "nat" { source = "sre-iac-modules/network/nat" region_id = var.region_id env = var.env service_code = var.service_code target_subnets = module.vpc.protected_subnet_ids use_managed_nat = true depends_on = [module.wink_vpc] }
Terraform Console输出
❯ terraform console > module.vpc { "db_subnet_ids" = [ "subnet-036b19638fd57d03b", "subnet-0989e9ecb9ca2a146", "subnet-060db32b53559ecfb", ] "protected_subnet_ids" = [ "subnet-0ac643148503ed0b5", "subnet-039f527ad5e194b01", "subnet-07523fedcb50084a3", ] # 其他输出省略 } > module.vpc.protected_subnet_ids [ "subnet-0ac643148503ed0b5", "subnet-039f527ad5e194b01", "subnet-07523fedcb50084a3", ]
NAT模块中aws_eip资源代码
resource "aws_eip" "nat-gw-eip" { count = length(var.target_subnets) vpc = true }
原因分析
- 变量类型不匹配:NAT模块中
target_subnets变量的类型定义可能不是list(string),若定义为string,传入的列表会被隐式转换,导致length()计算结果为0。 - 依赖关系错误:NAT模块中
depends_on引用的是module.wink_vpc,但实际VPC模块名为module.vpc,错误的依赖会导致Terraform提前计算count值时,VPC模块的输出还未生成。 - VPC模块输出定义问题:VPC模块的
protected_subnet_ids输出若未明确指定类型为list(string),可能导致输出值在传递时发生类型转换。
解决方法
- 修正NAT模块变量类型:在NAT模块的
variables.tf中明确target_subnets为列表类型:
variable "target_subnets" { type = list(string) description = "目标子网ID列表,用于创建对应数量的NAT网关EIP" }
- 修复依赖关系:将NAT模块的
depends_on改为正确的模块名,或直接删除该字段(Terraform会自动推断模块间的依赖关系):
# 修正后 depends_on = [module.vpc] # 或直接删除depends_on字段
- 验证VPC模块输出定义:确保VPC模块的
outputs.tf中正确定义输出类型:
output "protected_subnet_ids" { type = list(string) description = "受保护子网ID列表" value = [aws_subnet.protected_a.id, aws_subnet.protected_b.id, aws_subnet.protected_c.id] }
- 刷新状态并重新规划:执行以下命令确保状态同步,再检查
count值:
terraform refresh terraform plan
内容的提问来源于stack exchange,提问作者Sungshik Jou
相关产品推荐
相关产品推荐

