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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:27:22