mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-21 10:47:34 -05:00
Signed-off-by: Janos <86970079+janosdebugs@users.noreply.github.com> Signed-off-by: Damian Stasik <920747+damianstasik@users.noreply.github.com> Signed-off-by: Roman Grinovski <roman.grinovski@gmail.com> Co-authored-by: Damian Stasik <920747+damianstasik@users.noreply.github.com> Co-authored-by: Roman Grinovski <roman.grinovski@gmail.com>
175 lines
5.9 KiB
Plaintext
175 lines
5.9 KiB
Plaintext
---
|
|
sidebar_label: templatefile
|
|
description: |-
|
|
The templatefile function reads the file at the given path and renders its
|
|
content as a template.
|
|
---
|
|
|
|
# `templatefile` Function
|
|
|
|
`templatefile` reads the file at the given path and renders its content
|
|
as a template using a supplied set of template variables.
|
|
|
|
```hcl
|
|
templatefile(path, vars)
|
|
```
|
|
|
|
The template syntax is the same as for
|
|
[string templates](../../language/expressions/strings.mdx#string-templates)
|
|
in the main OpenTofu language, including interpolation sequences delimited with
|
|
`${` ... `}`. This function just allows longer template sequences to be factored
|
|
out into a separate file for readability.
|
|
|
|
The "vars" argument must be an object. Within the template file, each of the
|
|
keys in the map is available as a variable for interpolation. The template may
|
|
also use any other function available in the OpenTofu language. Variable
|
|
names must each start with a letter, followed by zero or more
|
|
letters, digits, or underscores.
|
|
|
|
Strings in the OpenTofu language are sequences of Unicode characters, so
|
|
this function will interpret the file contents as UTF-8 encoded text and
|
|
return the resulting Unicode characters. If the file contains invalid UTF-8
|
|
sequences then this function will produce an error.
|
|
|
|
This function can be used only with files that already exist on disk at the
|
|
beginning of an OpenTofu run. Functions do not participate in the dependency
|
|
graph, so this function cannot be used with files that are generated
|
|
dynamically during an OpenTofu operation.
|
|
|
|
`*.tftpl` is the recommended naming pattern to use for your template files.
|
|
OpenTofu will not prevent you from using other names, but following this
|
|
convention will help your editor understand the content and likely provide
|
|
better editing experience as a result.
|
|
|
|
## Recursion
|
|
|
|
There are a few limitations to be aware of if recursion is used with templatefile.
|
|
|
|
Any recursive calls to `templatefile` will have a limited call depth (1024 by default).
|
|
This is to prevent crashes due to unintential infinite recursive calls and limit the chance
|
|
of Out Of Memory crashes.
|
|
|
|
As tail-recursion is not supported, all documents in a call stack must be loaded
|
|
into memory before the stack can unwind. On most modern systems and configurations
|
|
this will likely not be an issue, but it is worth being mindful of.
|
|
|
|
If the maximum recursion depth is hit during execution, a concise error will be provided
|
|
which describes the first few steps of the call stack to help you diagnose the issue.
|
|
If you need the full call stack, setting `TF_LOG=debug` will cause the full templatefile
|
|
callstack to be printed to the console.
|
|
|
|
If your configuration requires a larger maximum recursion depth, you can override the
|
|
default using the `TF_TEMPLATE_RECURSION_DEPTH` environment variable. This is not
|
|
recommended and is only provided as an escape hatch. Additionally, setting it lower
|
|
than the 1024 default has the potential to cause problems with modules that use
|
|
the templatefile function.
|
|
|
|
## Examples
|
|
|
|
### Lists
|
|
|
|
Given a template file `backends.tftpl` with the following content:
|
|
|
|
```
|
|
%{ for addr in ip_addrs ~}
|
|
backend ${addr}:${port}
|
|
%{ endfor ~}
|
|
```
|
|
|
|
The `templatefile` function renders the template:
|
|
|
|
```
|
|
> 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
|
|
|
|
```
|
|
|
|
### Maps
|
|
|
|
Given a template file `config.tftpl` with the following content:
|
|
|
|
```
|
|
%{ for config_key, config_value in config }
|
|
set ${config_key} = ${config_value}
|
|
%{ endfor ~}
|
|
```
|
|
|
|
The `templatefile` function renders the template:
|
|
|
|
```
|
|
> templatefile(
|
|
"${path.module}/config.tftpl",
|
|
{
|
|
config = {
|
|
"x" = "y"
|
|
"foo" = "bar"
|
|
"key" = "value"
|
|
}
|
|
}
|
|
)
|
|
set foo = bar
|
|
set key = value
|
|
set x = y
|
|
```
|
|
|
|
### Generating JSON or YAML from a template
|
|
|
|
If the string you want to generate will be in JSON or YAML syntax, it's
|
|
often tricky and tedious to write a template that will generate valid JSON or
|
|
YAML that will be interpreted correctly when using lots of individual
|
|
interpolation sequences and directives.
|
|
|
|
Instead, you can write a template that consists only of a single interpolated
|
|
call to either [`jsonencode`](../../language/functions/jsonencode.mdx) or
|
|
[`yamlencode`](../../language/functions/yamlencode.mdx), specifying the value to encode using
|
|
[normal OpenTofu expression syntax](../../language/expressions/index.mdx)
|
|
as in the following examples:
|
|
|
|
```
|
|
${jsonencode({
|
|
"backends": [for addr in ip_addrs : "${addr}:${port}"],
|
|
})}
|
|
```
|
|
|
|
```
|
|
${yamlencode({
|
|
"backends": [for addr in ip_addrs : "${addr}:${port}"],
|
|
})}
|
|
```
|
|
|
|
Given the same input as the `backends.tftpl` example in the previous section,
|
|
this will produce a valid JSON or YAML representation of the given data
|
|
structure, without the need to manually handle escaping or delimiters.
|
|
In the latest examples above, the repetition based on elements of `ip_addrs` is
|
|
achieved by using a
|
|
[`for` expression](../../language/expressions/for.mdx)
|
|
rather than by using
|
|
[template directives](../../language/expressions/strings.mdx#directives).
|
|
|
|
```json
|
|
{"backends":["10.0.0.1:8080","10.0.0.2:8080"]}
|
|
```
|
|
|
|
If the resulting template is small, you can choose instead to write
|
|
`jsonencode` or `yamlencode` calls inline in your main configuration files, and
|
|
avoid creating separate template files at all:
|
|
|
|
```hcl
|
|
locals {
|
|
backend_config_json = jsonencode({
|
|
"backends": [for addr in ip_addrs : "${addr}:${port}"],
|
|
})
|
|
}
|
|
```
|
|
|
|
For more information, see the main documentation for
|
|
[`jsonencode`](../../language/functions/jsonencode.mdx) and [`yamlencode`](../../language/functions/yamlencode.mdx).
|
|
|
|
## Related Functions
|
|
|
|
* [`file`](../../language/functions/file.mdx) reads a file from disk and returns its literal contents
|
|
without any template interpretation.
|
|
* [`templatestring`](../../language/functions/templatestring.mdx) takes a string and renders it as a
|
|
template using a supplied set of template variables.
|