在 AWS 安全组中创建多个规则

Create multiple rules in AWS security Group

我尝试创建一个具有多个入站规则的 AWS 安全组,通常我们需要在 sg 中为多个入站规则设置多个入口。我没有单独创建多个入口规则,而是尝试创建一个入口列表,这样我就可以轻松地为不同的应用程序重用该模块。

PFB,

module/sg/sg.tf >>

resource "aws_security_group" "ec2_security_groups" {
  name   = var.name_security_groups
  vpc_id = var.vpc_id
}

module/sg/rules.tf >>

resource "aws_security_group_rule" "ingress_rules" {
  count             = lenght(var.ingress_rules)
  type              = "ingress"
  from_port         = var.ingress_rules[count.index][0]
  to_port           = var.ingress_rules[count.index][1]
  protocol          = var.ingress_rules[count.index][2]
  cidr_blocks       = var.ingress_rules[count.index][3]
  description       = var.ingress_rules[count.index][4]
  security_group_id = aws_security_group.ec2_security_groups.id
}

module/sg/variable.tf >>

variable "vpc_id" {
}
variable "name_security_groups" {
}
variable "ingress_rules" {
    type = list(string)
}

在应用程序文件夹中,

application/dev/sg.tf >>

module "sg_test" {
  source = "../modules/sg"

  vpc_id                   = "vpc-xxxxxxxxx"
  name_security_groups = "sg_test"
  ingress_rules                     = var.sg_ingress_rules 
}

application/dev/variable.tf >>

variable "sg_ingress_rules" {
    type        = list(string)
    default     = {
        [22, 22, "tcp", "1.2.3.4/32", "test"]
        [23, 23, "tcp", "1.2.3.4/32", "test"]
    }
}

错误:

Error: Missing attribute value

  on test-sgs.tf line 21, in variable "sg_ingress_rules":
  20: 
  21: 
  22: 

Expected an attribute value, introduced by an equals sign ("=").

请大家帮忙改正,如果有其他方法请提出。

此致,

如果您希望它按字面意义与索引字段一起使用,请将其设为 list(list(string)) 并将默认的牡蛎语法从大括号(用于地图)更改为方括号(用于列表):

variable "sg_ingress_rules" {
    type        = list(list(string))
    default     = [
        [22, 22, "tcp", "1.2.3.4/32", "test"]
        [23, 23, "tcp", "1.2.3.4/32", "test"]
    ]
}

这是一个令人困惑的数据结构,很难使用,所以我推荐这个:

variable "sg_ingress_rules" {
    type        = map(map(any))
    default     = {
        thing1 = {from=22, to=22, proto="tcp", cidr="1.2.3.4/32", desc=test"]
        thing2 = {from=23, to=23, proto="tcp", cidr="1.2.3.4/32", desc="test"}
    }
}

你可以使用比我选择的糟糕名称更好的名称,然后在你的资源中引用它们:

resource "aws_security_group_rule" "ingress_rules" {
  for_each          = var.ingress_rules
  type              = "ingress"
  from_port         = each.value.from
  to_port           = each.value.to
  protocol          = each.value.proto
  cidr_blocks       = each.value.cidr
  description       = each.value.desc
  security_group_id = aws_security_group.ec2_security_groups.id
}

您将获得 aws_security_group_rule 的多个命名副本,这些副本可以更好地从 ingress_rules 变量中插入和删除,并且可以让您省去麻烦。否则,您将获得多余的破坏和创建规则,有时还会由于计数创建的索引资源而发生冲突。

如果您希望对设置 ingress_rules 值的人设置更好的防护栏,您可以使用对象来要求和限制具有特定类型的一组特定字段,如下所示:

variable "sg_ingress_rules" {
    type        = map(object(
      {
        from = number
        to = number
        proto = string
        cidr = string
        desc = string
      }
    ))
    default     = {
        thing1 = {from=22, to=22, proto="tcp", cidr="1.2.3.4/32", desc=test"]
        thing2 = {from=23, to=23, proto="tcp", cidr="1.2.3.4/32", desc="test"}
    }
}

感谢@apparentlymart,他在 Terraform 讨论中帮助解决了这个问题

安全规则:-

resource "aws_security_group_rule" "ingress_rules" {
  count = length(var.ingress_rules)

  type              = "ingress"
  from_port         = var.ingress_rules[count.index].from_port
  to_port           = var.ingress_rules[count.index].to_port
  protocol          = var.ingress_rules[count.index].protocol
  cidr_blocks       = [var.ingress_rules[count.index].cidr_block]
  description       = var.ingress_rules[count.index].description
  security_group_id = aws_security_group.ec2_security_groups.id
}

和变量:

variable "sg_ingress_rules" {
    type = list(object({
      from_port   = number
      to_port     = number
      protocol    = string
      cidr_block  = string
      description = string
    }))
    default     = [
        {
          from_port   = 22
          to_port     = 22
          protocol    = "tcp"
          cidr_block  = "1.2.3.4/32"
          description = "test"
        },
        {
          from_port   = 23
          to_port     = 23
          protocol    = "tcp"
          cidr_block  = "1.2.3.4/32"
          description = "test"
        },
    ]
}

我们可以用一种简单的方式做到这一点:-

locals {
  ports_in = [
    443,
    80
  ]
  ports_out = [
    0
  ]
}

resource "aws_security_group" "internet_facing_alb" {
  name        = "internetfacing-loadbalancer-sg"
  description = "Security group attached to internet facing loadbalancer"
  vpc_id      = var.vpc_id

  dynamic "ingress" {
    for_each = toset(local.ports_in)
    content {
      description = "Web Traffic from internet"
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  dynamic "egress" {
    for_each = toset(local.ports_out)
    content {
      description = "Web Traffic to internet"
      from_port   = egress.value
      to_port     = egress.value
      protocol    = "-1"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  tags = {
    Name = "internetfacing-loadbalancer-sg"
  }
}

有一种管理多个入口规则的新方法,使用新的 terraform 资源,名为 aws_security_group_rule

它比其他方法更好,使用 Attributes as Blocks

参考样本

resource "aws_security_group_rule" "example" {
  type              = "ingress"
  from_port         = 0
  to_port           = 65535
  protocol          = "tcp"
  cidr_blocks       = [aws_vpc.example.cidr_block]
  ipv6_cidr_blocks  = [aws_vpc.example.ipv6_cidr_block]
  security_group_id = "sg-123456"
}

参考:aws_security_group_rule