【问题标题】:Create dynamic rules from list in terraform从 terraform 中的列表创建动态规则
【发布时间】:2021-06-24 13:36:03
【问题描述】:

我在 tf 中有一个 ips 列表

ips = ["1.2.3.1/32", "1.2.3.2/32", "1.2.3.3/32", "1.2.3.4/32", "1.2.3.5/32", "1.2.3.6/32" ]

规则:

resource "aws_alb_listener_rule" "test" {
  listener_arn = aws_alb_listener.https.arn
  priority     = 4

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.test.arn
  }

  condition {
    host_header {
      values = ["test"]
    }
  }

  condition {
    path_pattern {
      values = [
      "/somepath"]
    }
  }

  condition {
    source_ip {
      values = var.ips
    }
  }
}

现在我必须为此 ALB 创建一个侦听器规则。我遇到了一些问题,您最多只能为侦听器规则设置 5 个条件。

我可以通过将列表拆分为 2 并创建 2 个规则来使其工作,一个指向 ips_1,第二个规则使用 ips_2

ips_1 = ["1.2.3.1/32", "1.2.3.2/32", "1.2.3.3/32"]
ips_2 = ["1.2.3.4/32", "1.2.3.5/32", "1.2.3.6/32"]

现在的问题是我必须在添加新 IP 时创建一个新变量 (ips_3),因为现在每个规则最多有 5 个条件。

所以我想保留一份清单:

ips = ["1.2.3.1/32", "1.2.3.2/32", "1.2.3.3/32", "1.2.3.4/32", "1.2.3.5/32", "1.2.3.6/32"]

我怎样才能使它更具动态性:

  • 为变量的每 3 个项目 (ips) 创建一个规则,这样我现在将得到 2 个规则,如果我添加一个变量,我将得到第 3 个规则。

【问题讨论】:

    标签: amazon-web-services terraform


    【解决方案1】:

    您可以使用chunklist 将列表分块为大小为n 的列表列表。

    例如,以下 Terraform:

    variable "ips" {
      default = ["1.2.3.1/32", "1.2.3.2/32", "1.2.3.3/32", "1.2.3.4/32", "1.2.3.5/32", "1.2.3.6/32"]
    }
    
    output "ips_chunked" {
      value = chunklist(var.ips, 3)
    }
    

    会输出这个:

    ips_chunked = tolist([
      tolist([
        "1.2.3.1/32",
        "1.2.3.2/32",
        "1.2.3.3/32",
      ]),
      tolist([
        "1.2.3.4/32",
        "1.2.3.5/32",
        "1.2.3.6/32",
      ]),
    ])
    

    因此,在您的用例中,您可以遍历 chuked 列表,将子列表传递给每个规则:

    variable "ips" {
      default = ["1.2.3.1/32", "1.2.3.2/32", "1.2.3.3/32", "1.2.3.4/32", "1.2.3.5/32", "1.2.3.6/32"]
    }
    
    resource "aws_alb_listener_rule" "test" {
      for_each = toset(chunklist(var.ips))
    
      listener_arn = aws_alb_listener.https.arn
    
      action {
        type             = "forward"
        target_group_arn = aws_alb_target_group.test.arn
      }
    
      condition {
        host_header {
          values = ["test"]
        }
      }
    
      condition {
        path_pattern {
          values = [
            "/somepath"
          ]
        }
      }
    
      condition {
        source_ip {
          values = each.value
        }
      }
    }
    

    上面的 Terraform 会将var.ips 列表拆分为 3 个块,为每个 3 个块创建一个负载均衡器侦听器规则,然后每个规则将包含 3 个 IP 地址。

    请注意,我还删除了规则中的硬编码 priority argument,以允许 Terraform 自动增加每个负载均衡器侦听器规则的规则优先级,而不必在迭代它们时计算它们应该是什么:

    priority - (可选)150000 之间规则的优先级。不设置它会在当前存在的最高规则之后自动设置具有下一个可用优先级的规则。一个侦听器不能有多个具有相同优先级的规则。

    【讨论】:

    • 谢谢,我只是尝试了一下chuncklist。我没有使用 for_each atm,因为我必须定义计数来定义优先级。知道在使用计数时应该如何定义我的值 = xxx 吗?计数 = 长度(块列表(var.ips,3))
    • 需要优先级吗?如果您不指定它,那么它将默认使用下一个可用的优先级编号。除非您正在做特别复杂的事情,在大多数情况下 应该 就足够了。我们有负载均衡器侦听器规则,其中包含数百个动态创建的规则,并且从未遇到过仅使用下一个规则的问题。如果您有可能重叠的条件并希望在这些条件之间设置优先级,这只会是一个问题,但我会尝试通过使规则排他性来避免这种可能性。
    • 我在考虑类似 values = [chunklist(var.ips,3)[count.index]]
    • 如果您有一个可以扩展的额外限制条件,这可能接近于新问题领域。
    • 让它与计数一起使用。当然,您的解决方案更好(因此被接受为正确答案),但我必须遵守一些限制。
    猜你喜欢
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多