将 templatefile() 的输出作为要插值的输入

问题描述 投票:0回答:1

我有一个问题,是否可以使用 templatefile() 函数的渲染输出来构建 terraform 数据类型(特别是“对象集”)......然后使用此输出作为输入值传递到模块中? ..我似乎无法让它工作

所以解释一下,我有一个

pipelines.tmpl
文件,看起来像这样

pipelines_rendered = [
%{~ for p in pipelines  ~}
  {
    name                  = "${p.name}"
    project               = "blah"
    version               = "${p.ver}"
    branch                =  "something"
    description           =  "blah"
    ...
    ...
  },
%{~ endfor ~}
]

这是由看起来像这样的

local
提供的

locals {
  pipelines = [
    { name = "foo", ver = "1" },
    { name = "bar", ver = "1" },
    ...
  ]
}

此 templatefile() 形式的最终渲染输出,看起来与我需要的“对象集”结构完全相同。我现在想将模板创建的结果“对象集”作为输入(要进行插值)提供给模块。具体来说,作为名为“pipelines_in”的变量的值(该变量被声明为类型“set”)目标模块中的对象的数量)

正如您在下面看到的,在调用模块时,我调用 templatefile() 函数来返回渲染的输出(对象集)..以形成“pipelines_in”变量的值

module "build_pipelines" {
  source        = "somewhere:/mymodule"
  pipelines_in     = templatefile("${path.module}/pipelines.tmpl", { pipelines = local.pipelines })
}

但是无论我在这里尝试什么,在运行计划时我似乎都会遇到同样的错误

│ Error: Invalid value for input variable
│ 
│ The given value is not suitable for module.mymodule.var.pipelines
│ declared at
│ .terraform/modules/mymodule/terraform/variables.tf:35,1-21: set of
│ object required.

将 templatefile() 的输出作为要插值的输入时是否存在问题?

我应该这样做吗(我的简介是消除开发人员必须构建完整的“对象集”的需要,而只需添加一些变量并让模板构建完整的对象集

terraform
1个回答
0
投票

Terraform 的

templatefile
函数用于基于模板构建 strings,而不是构建任意数据结构。

但是,如果您愿意使用像 JSON 这样的中间序列化格式,那么您可以有效地欺骗它生成可以转换为非字符串类型的内容。

例如,在您的模板中您可以这样写:

${jsonencode([
  for p in pipelines : {
    name        = p.name
    project     = "blah"
    version     = p.ver
    branch      = "something"
    description = "blah"
  }  
])}

这是一个有点奇怪的模板,其整个内容是对

jsonencode
调用的单个插值。因此,该模板的结果是一个包含表示对象数组的 JSON 语法的字符串。

在你的主配置中,你可以使用相反的函数

jsondecode
将该字符串解析回相应的Terraform语言类型(一个对象元组,只要所有元素都可以自动转换为对象列表)具有相同的对象类型):

module "build_pipelines" {
  source = "somewhere:/mymodule"

  pipelines_in = jsondecode(templatefile(
    "${path.module}/pipelines.tmpl",
    { pipelines = local.pipelines },
  ))
}

templatefile
函数而言,它只是返回一个普通的旧字符串。但是
jsondecode
然后将其解释为 JSON 语法以生成更复杂的数据结构,然后您可以将其传递给模块。

要完成此操作,您需要将模块内的

pipelines_in
输入变量声明为具有对象列表类型,以确保模板生成适当形状的数据结构:

variable "pipelines_in" {
  type = list(object({
    name        = string
    project     = string
    version     = string
    branch      = string
    description = string
  }))
}

...这样,如果您在模板中犯了错误,它将在

pipelines_in
块中的
module
参数中被捕获为无效类型,而不是在您的内部可能更令人困惑的东西模块。

© www.soinside.com 2019 - 2024. All rights reserved.