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遍历映射(推荐)
- 在EFS模块的
variables.tf中定义正确的变量类型:
variable "private_subnet" { type = map(object({ id = string })) description = "私有子网的映射集合" }
- 修改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:将映射转为列表传递
- 修改VPC模块的输出,把映射转为列表:
output "private_subnet_list" { value = values(aws_subnet.private) }
- 在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 }
- 在EFS模块的
variables.tf中定义变量类型为列表:
variable "private_subnet" { type = list(object({ id = string })) description = "私有子网的列表集合" }
此时原有的count代码即可正常工作。
内容的提问来源于stack exchange,提问作者Ydrab
相关产品推荐
相关产品推荐

