Terraform使用for_each创建EC2附加EBS卷出现资源引用报错问题
问题根因
报错1(instance_id类型不匹配)
你的EC2模块module.this是通过count参数声明创建的,返回的id属性是数字索引的列表类型,仅支持0/1/2这类数字下标取值。你当前使用each.value.ec2_key(字符串类型,比如server1)作为索引取值,无法匹配列表的数字索引规则,取值失败后返回的非字符串值不符合instance_id的参数要求。
报错2(EBS卷键不存在)
你给aws_ebs_volume.this配置的for_each生成的键是${disk.ec2_key}.${disk.disk_key}格式(比如server1.disk1),但你引用时仅传入each.value.disk_key(比如disk1)作为索引,键名不匹配因此无法找到对应的EBS资源。
修复方案
建议优先把EC2模块module.this也改为用for_each声明,和你的var.ec2_info键对应,保证索引规则统一,修正后的代码如下:
- 先调整EC2模块的调用规则,和ec2_info的键对齐:
module "this" { for_each = var.ec2_info # 其余模块参数按你的业务配置补全 instance_type = each.value.instance_type subnet_id = each.value.subnet_id key_pair = each.value.key_pair }
- 修正
aws_volume_attachment资源的引用逻辑:
resource "aws_volume_attachment" "this" { for_each = { for disk in local.info_disk_object : "${disk.ec2_key}.${disk.disk_key}" => disk } device_name = each.value.device_name # 索引和EBS资源的for_each键保持一致,补充ec2_key前缀 volume_id = aws_ebs_volume.this["${each.value.ec2_key}.${each.value.disk_key}"].id # 调整后module.this是for_each生成的map,支持用字符串类型的ec2_key索引 instance_id = module.this[each.value.ec2_key].id }
如果暂时不想修改EC2模块的count声明,可以额外新增字符串到数字下标的映射规则:
locals { ec2_key_to_index = {for idx, k in keys(var.ec2_info) : k => idx} }
之后把instance_id改为instance_id = module.this[local.ec2_key_to_index[each.value.ec2_key]].id即可,但更推荐统一用for_each的方案,后续增删EC2实例不会产生顺序偏移的副作用。
内容的提问来源于stack exchange,提问作者AJC
相关产品推荐
相关产品推荐

