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

如何在Terraform中引用for_each创建的AWS安全组?

Terraform将for_each生成的ECS安全组批量加入RDS安全组入站规则的解决方法

问题本质

通过for_each创建的aws_security_group.sg_ecs_app_service是一个资源集合(map/set类型),而非单个资源对象,直接引用aws_security_group.sg_ecs_app_service.id会报错,因为集合本身没有id属性,需要遍历提取每个安全组的ID。

解决方法1:使用dynamic块生成独立入站规则

适合需要为每个ECS安全组单独创建入站规则的场景,灵活性更高:

resource "aws_security_group" "rds_sg" {
  name        = "rds-sg"
  description = "Allow traffic from ECS app services"
  vpc_id      = var.vpc_id

  # 动态遍历所有ECS应用安全组,生成对应入站规则
  dynamic "ingress" {
    for_each = aws_security_group.sg_ecs_app_service
    content {
      from_port       = 5432 # 替换为你的数据库端口(如3306对应MySQL)
      to_port         = 5432
      protocol        = "tcp"
      security_groups = [ingress.value.id]
    }
  }

  # 可选:添加管理员IP访问规则
  ingress {
    from_port   = 5432
    to_port     = 5432
    protocol    = "tcp"
    cidr_blocks = [var.admin_cidr]
  }

  # 默认全量出站规则(按需调整)
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

解决方法2:将所有ECS安全组合并到单条入站规则

适合ECS安全组数量较少(AWS单条规则支持最多60个安全组)的场景:

resource "aws_security_group" "rds_sg" {
  name        = "rds-sg"
  description = "Allow traffic from ECS app services"
  vpc_id      = var.vpc_id

  ingress {
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    # 遍历集合提取所有安全组ID
    security_groups = [for sg in aws_security_group.sg_ecs_app_service : sg.id]
  }

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

注意事项

  • 确保ECS安全组与RDS安全组处于同一个VPC,否则无法跨VPC引用安全组作为入站来源
  • 若for_each使用的是set类型而非map,上述两种写法完全兼容,无需修改

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:22:10