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

Terraform遍历子网ID报错:EFS挂载目标无法索引子网

Terraform EFS挂载目标创建错误:var.private_subnet为字符串无法索引

我通过VPC模块使用for_each创建私有子网aws_subnet.private,并将该资源作为output输出。在创建EFS模块时,尝试为每个私有子网创建挂载目标,使用count遍历传入的var.private_subnet时出现错误,提示var.private_subnet为字符串类型,无法使用索引。

VPC模块子网资源代码

resource "aws_subnet" "private" {
  for_each          = { for index, az_name in local.az_names : index => az_name }
  vpc_id            = aws_vpc.network.id
  cidr_block        = cidrsubnet(aws_vpc.network.cidr_block, 8, each.key + 11)
  availability_zone = local.az_names[each.key]
  tags = {
    Name        = "${var.env}-private-${local.az_names[each.key]}"
    Description = local.az_names[each.key]
    Type = "private"
  }
}

VPC模块输出

output "private_subnet" {
  value = aws_subnet.private
}

EFS模块挂载目标代码

resource "aws_efs_mount_target" "efs-mt" {
  count = length(var.private_subnet)
  file_system_id  = aws_efs_file_system.efs.id
  subnet_id = var.private_subnet[count.index].id
  security_groups = var.security_groups
}

main.tf调用代码

module "efs" {
  source              = "./modules/efs"
  env                 = var.env
  vpc_id           = module.vpc.vpc_id
  security_groups = [module.security.efs_sg_ids]
  private_subnet = module.vpc.private_subnet
}

错误信息

│ Error: Invalid index
│ 
│   on modules/efs/main.tf line 14, in resource "aws_efs_mount_target" "efs-mt":
│   14:   subnet_id = var.private_subnet[count.index].id
│     ├────────────────
│     │ count.index is a number, known only after apply
│     │ var.private_subnet is a string, known only after apply
│ 
│ This value does not have any indices.

问题原因与解决方法

原因

VPC模块中用for_each创建的aws_subnet.private是**映射(map)**类型的资源集合,直接传递给EFS模块时,若未正确定义变量类型,Terraform会将其解析为字符串;同时count适合处理列表,与映射类型不匹配,导致索引错误。

解决方案

方案1:改用for_each遍历映射(推荐)

  1. 在EFS模块的variables.tf中定义正确的变量类型:
variable "private_subnet" {
  type = map(object({
    id = string
  }))
  description = "私有子网的映射集合"
}
  1. 修改EFS挂载目标的创建代码,用for_each替代count:
resource "aws_efs_mount_target" "efs-mt" {
  for_each = var.private_subnet
  file_system_id  = aws_efs_file_system.efs.id
  subnet_id = each.value.id
  security_groups = var.security_groups
}

方案2:将映射转为列表传递

  1. 修改VPC模块的输出,把映射转为列表:
output "private_subnet_list" {
  value = values(aws_subnet.private)
}
  1. 在main.tf中传递列表类型的子网:
module "efs" {
  source              = "./modules/efs"
  env                 = var.env
  vpc_id           = module.vpc.vpc_id
  security_groups = [module.security.efs_sg_ids]
  private_subnet = module.vpc.private_subnet_list
}
  1. 在EFS模块的variables.tf中定义变量类型为列表:
variable "private_subnet" {
  type = list(object({
    id = string
  }))
  description = "私有子网的列表集合"
}

此时原有的count代码即可正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 05:54:09