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

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),可能导致输出值在传递时发生类型转换。

解决方法

  1. 修正NAT模块变量类型:在NAT模块的variables.tf中明确target_subnets为列表类型:
variable "target_subnets" {
  type        = list(string)
  description = "目标子网ID列表,用于创建对应数量的NAT网关EIP"
}
  1. 修复依赖关系:将NAT模块的depends_on改为正确的模块名,或直接删除该字段(Terraform会自动推断模块间的依赖关系):
# 修正后
depends_on = [module.vpc]
# 或直接删除depends_on字段
  1. 验证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]
}
  1. 刷新状态并重新规划:执行以下命令确保状态同步,再检查count值:
terraform refresh
terraform plan

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:54:24