使用元素和拆分获取 Terraform 中的第一个项目而不是最后一个项目

Nat*_*kle 2 split element nginx terraform

我们尝试将动态名称应用于防火墙规则,以便使用基于实例组 URL 列表的 terraform 在 GCP 中打开 8089 和 8843。它没有获取该结果并向我们提供 url 中的最后一项,而是为我们提供 https:

tf:

#This is to resolve an error when deploying to nginx
  resource "google_compute_firewall" "ingress" {
  for_each      = toset(google_container_cluster.standard-cluster.instance_group_urls)
  description   = "Allow traffic on ports 8843, 8089 for  nginx ingress"
  direction     = "INGRESS"
  name          = element(split("/", each.key), length(each.key))
  network       = "https://www.googleapis.com/compute/v1/projects/${local.ws_vars["project-id"]}/global/networks/${local.ws_vars["environment"]}"
  priority      = 1000
  source_ranges = google_container_cluster.standard-cluster.private_cluster_config.*.master_ipv4_cidr_block
  target_tags = [
    element(split("/", each.key), length(each.key))
  ]

  allow {
    ports = [
      "8089",
    ]
    protocol = "tcp"
  }
  allow {
    ports = [
      "8443",
    ]
    protocol = "tcp"
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

    Error: "name" ("https:") doesn't match regexp "^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$"

  on main.tf line 133, in resource "google_compute_firewall" "ingress":
 133:   name          = element(split("/", each.key), length(each.key))
Run Code Online (Sandbox Code Playgroud)

这里的解决方案是什么?为什么它不给出数组中的最后一项?有没有更好的办法?

yda*_*coR 7

与许多语言一样,Terraform/HCL 使用基于零的索引,因此如果您想要数组中的最后一个元素,则需要从长度中减一,如下所示:

locals {
  list = ["foo", "bar", "baz"]
}

output "last_element" {
  value = element(local.list, length(local.list) - 1)
}
Run Code Online (Sandbox Code Playgroud)

element函数导致了这种混乱,因为当您尝试访问超出它所环绕的列表的长度时,而不是出现越界/范围错误,因此您将获得第一个元素:

该索引是从零开始的。如果与空列表一起使用,此函数会产生错误。索引必须是非负整数。

大多数情况下使用内置索引语法 list[index]。仅将此函数用于下述特殊的附加“环绕”行为。

要从列表中获取最后一个元素,请使用 length 来查找列表的大小(负 1,因为列表是从零开始的),然后选择最后一个元素:

> element(["a", "b", "c"], length(["a", "b", "c"])-1)
c
Run Code Online (Sandbox Code Playgroud)

不幸的是,在撰写本文时,Terraform 目前不支持内置索引语法中的负索引:

locals {
  list = ["foo", "bar", "baz"]
}

output "last_element" {
  value = local.list[-1]
}
Run Code Online (Sandbox Code Playgroud)

抛出以下错误:

Error: Invalid index

  on main.tf line 6, in output "last_element":
   6:   value = local.list[-1]
    |----------------
    | local.list is tuple with 3 elements

The given key does not identify an element in this collection value.
Run Code Online (Sandbox Code Playgroud)

正如评论中所建议的,这里更好的方法是首先反转列表,然后使用以下reverse函数从反转列表中取出第一个元素:

output "last_element" {
  value = reverse(local.list)[0]
}
Run Code Online (Sandbox Code Playgroud)

  • 您还可以反转列表并获取第一个元素:`reverse(local.list)[0]`。 (5认同)