---
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](/terraform/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 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 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`](/terraform/language/functions/jsonencode) or
[`yamlencode`](/terraform/language/functions/yamlencode), specifying the value to encode using
[normal Terraform expression syntax](/terraform/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](/terraform/language/expressions/for)
rather than by using
[template directives](/terraform/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`](/terraform/language/functions/jsonencode) and [`yamlencode`](/terraform/language/functions/yamlencode).

## Related Functions

* [`file`](/terraform/language/functions/file) reads a file from disk and returns its literal contents
  without any template interpretation.
