Terraform - 迭代模板中的对象列表

Dan*_*rts 10 function terraform terraform0.12+

我在迭代函数解释的模板内的对象列表时遇到问题templatefile

我有以下变量:

variable "destinations" {
  description = "A list of EML Channel Destinations."

  type = list(object({
    id  = string
    url = string
  }))
}
Run Code Online (Sandbox Code Playgroud)

templatefile这将作为传递给函数destinations。相关模板的片段是这样的:

Destinations:
  %{ for dest in destinations ~}
  - Id: ${dest.id}
    Settings:
      URL: ${dest.url}
  %{ endfor }
Run Code Online (Sandbox Code Playgroud)

规划 Terraform 时会出现以下错误:

Error: "template_body" contains an invalid YAML: yaml: line 26: did not find expected key
Run Code Online (Sandbox Code Playgroud)

我尝试将模板代码切换为以下内容:

Destinations:
  %{ for id, url in destinations ~}
  - Id: ${id}
    Settings:
      URL: ${url}
  %{ endfor }
Run Code Online (Sandbox Code Playgroud)

这给出了不同的错误:

Call to function "templatefile" failed:
../../local-tfmodules/eml/templates/eml.yaml.tmpl:25,20-23: Invalid template
interpolation value; Cannot include the given value in a string template:
string required., and 2 other diagnostic(s).

[!] something went wrong when creating the environment TF plan
Run Code Online (Sandbox Code Playgroud)

我的印象是我对这里的数据类型的迭代在某种程度上是不正确的,但我无法理解如何做到这一点,而且我根本找不到任何关于此的文档。

这是我如何调用此模块的简化示例:

module "eml" {
  source = "../../local-tfmodules/eml"

  name = "my_eml"

  destinations = [
    {
      id  = "6"
      url = "https://example.com"
    },
    {
      id  = "7"
      url = "https://example.net"
    }
  ]
<cut>
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*rts 11

我刚刚发现(在制作一个小型 Terraform 模块仅测试templatefile输出之后)原始配置确实有效(至少在 TF 中v0.12.29)。

给出的错误有点红鲱鱼 - 问题与模板内的缩进有关,例如而不是:

Destinations:
  %{ for destination in destinations  ~}
  - Id: ${destination.id}
    Settings:
      URL: ${destination.url}
  %{ endfor ~}
Run Code Online (Sandbox Code Playgroud)

它应该是:

Destinations:
  %{~ for destination in destinations  ~}
  - Id: ${destination.id}
    Settings:
      URL: ${destination.url}
  %{~ endfor ~}
Run Code Online (Sandbox Code Playgroud)

~请注意Terraform 指令开头的额外波形符 ( )。这使得 Yaml 对齐工作正常(您会得到一些缩进不正确的行和一些空行)。之后,我的问题中的原始代码按照我的预期工作并生成有效的 yaml。


Mar*_*cin 6

您无法将var.destinations地图列表作为模板传递。它必须是字符串列表/集合。

但您可以执行以下操作:

templatefile("eml.yaml.tmpl", 
          { 
            ids =  [for v in var.destinations: v.id]
            urls =  [for v in var.destinations: v.url] 
          }
    )
Run Code Online (Sandbox Code Playgroud)

哪里 eml.yaml.tmpl

Destinations:
  %{ for id, url in zipmap(ids, urls)  ~}
  - Id: ${id}
    Settings:
      URL: ${url}
  %{ endfor ~}
Run Code Online (Sandbox Code Playgroud)