| --- |
| page_title: templatefile - Functions - Configuration Language |
| 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#string-templates) |
| in the main Terraform 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 a map. 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 Terraform language, except that |
| recursive calls to `templatefile` are not permitted. Variable names must |
| each start with a letter, followed by zero or more letters, digits, or |
| underscores. |
| |
| Strings in the Terraform 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 a Terraform run. Functions do not participate in the dependency |
| graph, so this function cannot be used with files that are generated |
| dynamically during a Terraform operation. |
| |
| `*.tftpl` is the recommended naming pattern to use for your template files. |
| Terraform 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. |
| |
| ## Examples |
| |
| ### Lists |
| |
| Given a template file `backends.tftpl` with the following content: |
| |
| ``` |
| %{ for addr, port 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) or |
| [`yamlencode`](/language/functions/yamlencode), specifying the value to encode using |
| [normal Terraform expression syntax](/language/expressions) |
| 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) |
| rather than by using |
| [template directives](/language/expressions/strings#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) and [`yamlencode`](/language/functions/yamlencode). |
| |
| ## Related Functions |
| |
| * [`file`](/language/functions/file) reads a file from disk and returns its literal contents |
| without any template interpretation. |