Terraform创建aws_security_group时错误加载所有安全组出入站规则
问题原因
动态规则块的遍历范围写错了。
你在aws_security_group资源中用count循环创建安全组时,内部ingress和egress动态块的for_each参数直接遍历了全量安全组列表var.vpc_config.security_groups,导致每创建一个安全组实例,都会把列表中所有安全组的出入站规则全部加载一遍,最终每个安全组都带上了全部规则。
另外你的dev.tfvars配置还有一个隐藏错误:sg_2的出站规则协议填了"http",该字段只接受传输层协议值(比如tcp/udp/-1代表所有协议),443端口对应协议应为tcp,原配置会触发AWS接口报错。
修复方法
把动态块的遍历范围改成当前count索引对应的单个安全组的规则即可,修正后的./security.tf代码如下:
resource "aws_security_group" "sg" { count = length(var.vpc_config.security_groups) name = var.vpc_config.security_groups[count.index].name description = var.vpc_config.security_groups[count.index].description vpc_id = var.vpc_id dynamic "ingress" { # 仅取当前安全组对应的入站规则,转为单元素列表适配dynamic块语法 for_each = [var.vpc_config.security_groups[count.index].ingress] content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol cidr_blocks = ingress.value.cidr_block } } dynamic "egress" { # 仅取当前安全组对应的出站规则 for_each = [var.vpc_config.security_groups[count.index].egress] content { from_port = egress.value.from_port to_port = egress.value.to_port protocol = egress.value.protocol cidr_blocks = egress.value.cidr_block } } tags = { Name = var.vpc_config.security_groups[count.index].name Environment = var.vpc_config.environment } }
同时修改./dev.tfvars里sg_2的egress协议配置:
egress = { from_port = 443 to_port = 443 protocol = "tcp" # 原配置为"http"是错误值 cidr_block = ["0.0.0.0/0"] }
修改完成后重新执行terraform plan就能看到,每个安全组只会关联自己对应的1条入站、1条出站规则,符合预期。
内容的提问来源于stack exchange,提问作者Talha Sheikh
相关产品推荐
相关产品推荐

