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

为所有EC2实例主网卡分配安全组失败问题排查

问题:Terraform中安全组附加到EC2实例网卡时索引不匹配报错

需求:查找所有VPC并在每个VPC中创建安全组,找出所有运行及停止状态的EC2实例,将新安全组附加到每个实例的主网卡(排除Auto Scaling组中的实例)。

执行terraform plan时出现以下错误:

│ Error: Invalid index
│ 
│   on main.tf line 70, in resource "aws_network_interface_sg_attachment" "attach_sg":
│   70:   security_group_id    = aws_security_group.vpc_sg[data.aws_instance.instance[each.key].network_interface_id]
│     ├────────────────
│     │ aws_security_group.vpc_sg is object with 3 attributes
│     │ data.aws_instance.instance is object with 33 attributes
│     │ each.key is "i-xxxxxxxxxxxxxxxxx"
│ 
│ The given key does not identify an element in this collection value.

错误原因

  1. 索引不匹配:aws_security_group.vpc_sg的for_each基于VPC ID列表创建,集合的键是VPC ID,但代码中用网卡ID去索引该集合,自然找不到对应元素。
  2. each.key为实例ID的原因:aws_network_interface_sg_attachment的for_each定义为{ for id in data.aws_instances.all.ids : id => (data.aws_instance.instance[id].network_interface_id) },这里明确用实例ID作为map的键、网卡ID作为值,因此each.key必然是实例ID。

修正方案

通过实例所属的VPC ID索引对应安全组(每个实例属于一个VPC,安全组按VPC创建,二者可匹配)。

修正后的完整代码

provider "aws" {
  region = "us-east-1"
}

# 获取所有VPC
data "aws_vpcs" "all" {}

# 在每个VPC中创建安全组
resource "aws_security_group" "vpc_sg" {
  for_each = toset(data.aws_vpcs.all.ids)

  name        = "Example"
  description = "Allows SSH access"
  vpc_id      = each.value

  ingress {
    from_port   = 0
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["1.1.1.0/27"] # 根据环境更新
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# 获取所有运行/停止状态的EC2实例
data "aws_instances" "all" {
  filter {
    name   = "instance-state-name"
    values = ["running", "stopped"]
  }
}

# 获取每个实例的详细信息
data "aws_instance" "instance" {
  for_each = toset(data.aws_instances.all.ids)
  instance_id = each.key
}

# 将安全组附加到非ASG实例的主网卡
resource "aws_network_interface_sg_attachment" "attach_sg" {
  for_each = {
    for id in data.aws_instances.all.ids : id => data.aws_instance.instance[id].network_interface_id
    if lookup(data.aws_instance.instance[id].tags, "aws:autoscaling:groupName", null) == null
  }

  # 通过实例的VPC ID索引对应的安全组
  security_group_id    = aws_security_group.vpc_sg[data.aws_instance.instance[each.key].vpc_id]
  network_interface_id = each.value
}

说明

  • 修正核心:将security_group_id的索引从网卡ID改为实例所属的VPC ID,匹配对应VPC下创建的安全组。
  • each.value直接对应网卡ID,简化了network_interface_id的引用逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:03:17