- OpenTofu 语言
- 函数
- templatefile
templatefile
函数
templatefile
读取给定路径下的文件,并使用提供的模板变量集将其内容作为模板呈现。
templatefile(path, vars)
模板语法与 主 OpenTofu 语言中的字符串模板 相同,包括用 ${
... }
分隔的插值序列。此函数只是允许将更长的模板序列分解为单独的文件以提高可读性。
“vars” 参数必须是一个对象。在模板文件中,映射中的每个键都可用作插值的变量。模板也可以使用 OpenTofu 语言中可用的任何其他函数。变量名必须以字母开头,后跟零个或多个字母、数字或下划线。
OpenTofu 语言中的字符串是 Unicode 字符序列,因此此函数将解释文件内容为 UTF-8 编码的文本,并返回生成的 Unicode 字符。如果文件包含无效的 UTF-8 序列,则此函数将产生错误。
此函数只能用于 OpenTofu 运行开始时磁盘上已存在的文件。函数不参与依赖项图,因此此函数不能用于在 OpenTofu 操作期间动态生成的。文件。
*.tftpl
是推荐用于模板文件的命名模式。OpenTofu 不会阻止您使用其他名称,但遵循此约定将有助于您的编辑器了解内容,并可能因此提供更好的编辑体验。
递归
如果将递归与 templatefile 一起使用,需要注意一些限制。
对 templatefile
的任何递归调用将具有有限的调用深度(默认情况下为 1024)。这是为了防止因意外的无限递归调用而导致的崩溃,并限制内存不足崩溃的可能性。
由于不支持尾递归,因此在调用栈可以展开之前,必须将调用栈中的所有文档加载到内存中。在大多数现代系统和配置上,这可能不会出现问题,但值得注意。
如果在执行过程中达到最大递归深度,将提供一个简洁的错误,该错误描述调用栈的前几步,以帮助您诊断问题。如果您需要完整的调用栈,请设置 TF_LOG=debug
将导致完整的 templatefile 调用栈打印到控制台。
如果您的配置需要更大的最大递归深度,您可以使用 TF_TEMPLATE_RECURSION_DEPTH
环境变量覆盖默认值。不推荐这样做,只作为紧急情况下的解决方法提供。此外,将其设置为低于 1024 的默认值可能会导致使用 templatefile 函数的模块出现问题。
示例
列表
给定一个模板文件 backends.tftpl
,其内容如下
%{ for addr in ip_addrs ~}
backend ${addr}:${port}
%{ endfor ~}
templatefile
函数呈现模板
> templatefile("${path.module}/backends.tftpl", { port = 8080, ip_addrs = ["10.0.0.1", "10.0.0.2"] })
backend 10.0.0.1:8080
backend 10.0.0.2:8080
映射
给定一个模板文件 config.tftpl
,其内容如下
%{ for config_key, config_value in config }
set ${config_key} = ${config_value}
%{ endfor ~}
templatefile
函数呈现模板
> templatefile(
"${path.module}/config.tftpl",
{
config = {
"x" = "y"
"foo" = "bar"
"key" = "value"
}
}
)
set foo = bar
set key = value
set x = y
从模板生成 JSON 或 YAML
如果您要生成的字符串将采用 JSON 或 YAML 语法,那么编写一个模板来生成有效的 JSON 或 YAML,以便在使用大量单独的插值序列和指令时被正确解释,通常会很麻烦和乏味。
相反,您可以编写一个模板,该模板仅包含对 jsonencode
或 yamlencode
的单个插值调用,使用 正常的 OpenTofu 表达式语法 指定要编码的值,如以下示例所示
${jsonencode({
"backends": [for addr in ip_addrs : "${addr}:${port}"],
})}
${yamlencode({
"backends": [for addr in ip_addrs : "${addr}:${port}"],
})}
给定与上一节中的 backends.tftpl
示例相同的输入,这将生成给定数据结构的有效 JSON 或 YAML 表示,而无需手动处理转义或分隔符。在上面的最新示例中,基于 ip_addrs
元素的重复是通过使用 for
表达式 而不是使用 模板指令 来实现的。
{"backends":["10.0.0.1:8080","10.0.0.2:8080"]}
如果生成的模板很小,您可以选择在主配置文件中内联编写 jsonencode
或 yamlencode
调用,并且根本不需要创建单独的模板文件。
locals {
backend_config_json = jsonencode({
"backends": [for addr in ip_addrs : "${addr}:${port}"],
})
}
有关更多信息,请参阅 jsonencode
和 yamlencode
的主要文档。
相关函数
file
从磁盘读取文件并返回其字面内容,没有任何模板解释。templatestring
使用提供的模板变量集,将字符串作为模板呈现。