Terraform 动态生成属性(不是块)

Terraform dynamically generate attributes (not blocks)

我正在尝试在 terraform 13 中动态生成属性。我已经通读了文档,但我似乎无法让它工作:

给定以下地形:

#main.tf

locals {
  secrets = {
    secret1 = [
      {
        name  = "user",
        value = "secret"
      },
      {
        name  = "password",
        value = "password123"
      }
    ],
    secret2 = [
      {
        name  = "token",
        value = "secret"
      }
    ]
  }
}

resource "kubernetes_secret" "secrets" {
  for_each = local.secret

  metadata {
    name = each.key
  }

  data = {
    [for name, value in each.value : name = value]
  }
}

我希望呈现以下资源:

resource "kubernetes_secret" "secrets[secret1]" {
  metadata {
    name = "secret1"
  }

  data = {
    user     = "secret"
    password = "password123"
  }
}

resource "kubernetes_secret" "secrets[secret2]" {
  metadata {
    name = "secret2"
  }

  data = {
    token = "secret"
  }
}

但是我得到以下错误:

Error: Invalid 'for' expression

  on ../../main.tf line 96, in resource "kubernetes_secret" "secrets":
  96:     [for name, value in each.value : name = value]

Extra characters after the end of the 'for' expression.

有人知道怎么做吗?

使用 for 表达式生成映射的正确语法如下:

  data = {
    for name, value in each.value : name => value
  }

上面的内容实际上是完全多余的,因为它会产生与 each.value 相同的值。但是,因为您的本地值有一个具有 namevalue 属性的对象列表,而不是从名称到值的映射,所以为了获得有效的结果,我们要么需要将输入更改为已经是一张地图,像这样:

locals {
  secrets = {
    secret1 = {
      user     = "secret"
      password = "password123"
    }
    secret2 = {
      token    = "secret"
    }
  }
}

resource "kubernetes_secret" "secrets" {
  for_each = local.secrets

  metadata {
    name = each.key
  }

  # each.value is already a map of a suitable shape
  data = each.value
}

或者,如果出于某种原因输入对象列表很重要,您可以像这样从对象列表投影到映射:

locals {
  secrets = {
    secret1 = [
      {
        name  = "user",
        value = "secret"
      },
      {
        name  = "password",
        value = "password123"
      }
    ],
    secret2 = [
      {
        name  = "token",
        value = "secret"
      }
    ]
  }
}

resource "kubernetes_secret" "secrets" {
  for_each = local.secrets

  metadata {
    name = each.key
  }

  data = {
    for obj in each.value : obj.name => obj.value
  }
}

这两个应该产生相同的结果,所以选择哪个将取决于您认为哪种形状的局部值数据结构最易读或最方便。