如何在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
相关产品推荐
相关产品推荐

