【问题标题】:Create multiple rules in AWS security Group在 AWS 安全组中创建多个规则
【发布时间】:2020-10-15 22:08:02
【问题描述】:

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

PFB,

模块/sg/sg.tf >>

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

模块/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
}

模块/sg/variable.tf >>

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

在应用程序文件夹中,

应用程序/dev/sg.tf >>

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

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

应用程序/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 ("=").

请帮助纠正这个问题,或者如果有任何其他方法,请提出建议。

问候,

【问题讨论】:

  • 您的数据结构没有意义。如果您希望它是地图列表,您可以使用[{from_port: 22, to_port: 22, protocol: "tcp", cidr_range: "1.2.3.4/32", description: "test"}, {from_port: 23, to_port: 23, protocol: "tcp", cidr_range: "1.2.3.4/32", description: "test"}] 之类的内容。但是现在你有一张没有钥匙的破损地图。您还需要更改访问它的方式。或者,您可以有一个列表列表来保存您访问它的方式,但这对我来说描述性较差。
  • @ydaetskcoR 回复,我也尝试使用本地人:- locals { sg_ingress_rules = [ { from_port = 80, to_port = 80, protocol = tcp, cidr_blocks = "1.2.3.4/32",描述 = “测试”},{ from_port = 443,to_port = 443,协议 = tcp,cidr_blocks = “1.2.3.4/32”,描述 = “测试”},{ from_port = 22,to_port = 22,协议 = tcp, cidr_blocks = "1.2.3.4/32", description = "test" }, ] } 出现错误:- 未在根模块中声明托管资源“locals”“sg_egress_rules”。

标签: amazon-web-services terraform terraform-provider-aws


【解决方案1】:

感谢@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"
        },
    ]
}

【讨论】:

    【解决方案2】:

    如果您希望它与索引字段一起使用,请将其设为 list(list(string)) 并将默认的 oyter 语法从大括号(用于映射)更改为括号(用于列表):

    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 值的人设置一些更好的防护措施,您可以使用 object 来要求并限制特定类型的特定字段集,如下所示:

    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"}
        }
    }
    

    【讨论】:

    • 谢谢@Alain 我试过这个得到错误“错误:../modules/sgs/variable.tf 第 136 行的多行字符串无效,在变量“sg_ingress_rules”中:136:引用的字符串可能不会分割成多行。要生成多行字符串,请使用 \n 转义符来表示换行符或使用“heredoc”多行模板语法。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 2019-07-28
    • 2021-09-22
    • 2019-07-11
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    相关资源
    最近更新 更多