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

创建两台EC2实例时Terraform安全组语法错误求助

解决Terraform for_each创建多EC2实例后的安全组规则引用问题

当你对模块使用for_each后,module.ec2-module会变成一个映射对象(键为你指定的"1"、"2",值为对应模块实例的输出),不再是单个模块实例,所以直接访问module.ec2-module.security_groups会报错——这个映射对象本身没有security_groups属性,每个模块实例才有。

下面提供两种可行的解决方案:

方案一:为每个EC2实例创建独立的安全组规则

这种方式会为每台EC2生成一条独立的RDS访问规则,规则对应关系清晰:

### Allow traffic from each EC2 to RDS mysql instance
resource "aws_security_group_rule" "ec2_rds_webserver" {
  for_each                 = module.ec2-module
  type                     = "ingress"
  from_port                = var.webserver_rds["db_port"]
  to_port                  = var.webserver_rds["db_port"]
  protocol                 = "tcp"
  source_security_group_id = each.value.security_groups[0]
  security_group_id        = module.rds-webserver.sg_rds_servers
}
  • for_each = module.ec2-module:遍历所有EC2模块实例,每个实例生成一条规则
  • each.value:代表当前遍历到的单个EC2模块实例,直接引用其security_groups[0]即可获取对应实例的安全组ID

方案二:合并所有EC2安全组为一条规则

如果你希望用一条规则允许所有EC2实例访问RDS,可以用for表达式收集所有安全组ID,使用source_security_group_ids(复数形式)参数:

### Allow traffic from all EC2 instances to RDS mysql instance
resource "aws_security_group_rule" "ec2_rds_webserver" {
  type                      = "ingress"
  from_port                 = var.webserver_rds["db_port"]
  to_port                   = var.webserver_rds["db_port"]
  protocol                  = "tcp"
  source_security_group_ids = [for ec2 in module.ec2-module : ec2.security_groups[0]]
  security_group_id         = module.rds-webserver.sg_rds_servers
}
  • [for ec2 in module.ec2-module : ec2.security_groups[0]]:遍历所有EC2模块实例,提取每个实例的安全组ID,组成列表
  • source_security_group_ids:AWS安全组规则支持传入多个源安全组ID,用这个参数替代单个的source_security_group_id

选择建议

  • 若需要单独管理每台EC2的RDS访问权限,选方案一
  • 若所有EC2的RDS访问策略一致,选方案二更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:35:03