Intentamos aplicar un nombre dinámico a una regla de firewall para abrir 8089 y 8843 en GCP mediante terraform según la lista de direcciones URL de grupos de instancias. En lugar de tomar ese resultado y darnos el último elemento de la URL, nos da https:
t.f.:
#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" } }Resultado:
Error: "name" ("https:") doesn't match regexp "^(?:[az](?:[-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))¿Cuál es la solución aquí? ¿Por qué no da el último elemento de la matriz? ¿Hay una mejor manera?
Al igual que con muchos idiomas, Terraform/HCL utiliza una indexación basada en cero, por lo que si desea el último elemento en una matriz, debe restar uno de la longitud de esta manera:
locals { list = ["foo", "bar", "baz"] } output "last_element" { value = element(local.list, length(local.list) - 1) } La función del element está causando esta confusión porque en lugar de obtener un error fuera de los límites/rango cuando intenta acceder más allá de la longitud de la lista, se envuelve y obtiene el primer elemento:
El índice está basado en cero. Esta función produce un error si se usa con una lista vacía. El índice debe ser un número entero no negativo.
Utilice la lista de sintaxis de índice incorporada [índice] en la mayoría de los casos. Utilice esta función solo para el comportamiento adicional especial de "envolvimiento" que se describe a continuación.
Para obtener el último elemento de la lista, use la longitud para encontrar el tamaño de la lista (menos 1 ya que la lista está basada en cero) y luego elija el último elemento:
> element(["a", "b", "c"], length(["a", "b", "c"])-1) c
Desafortunadamente, en el momento de escribir este artículo, Terraform actualmente no admite índices negativos en la sintaxis de índice integrada:
locals { list = ["foo", "bar", "baz"] } output "last_element" { value = local.list[-1] }arroja el siguiente error:
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.