0

我正在尝试在 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.

有谁知道如何使这项工作?

4

1 回答 1

3

使用表达式生成映射的正确语法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
  }
}

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

于 2020-11-13T02:12:14.777 回答