【问题标题】:Terraform dynamically generate attributes (not blocks)Terraform 动态生成属性(不是块)
【发布时间】:2021-02-24 23:50:26
【问题描述】:

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

有人知道怎么做吗?

【问题讨论】:

  • 你能发布完整的错误信息吗?哪个表达式无效?
  • 添加到问题

标签: terraform hcl


【解决方案1】:

使用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-12-25
  • 2019-04-01
  • 2022-07-07
  • 2014-10-18
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多