创建两台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
相关产品推荐
相关产品推荐

