---
page_title: templatefile function reference
description: |-
  The `templatefile` function reads a file and renders its
  content as a template using a set of template variables. Learn how to use the `templatefile` function.
---

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]  
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

# `templatefile` Function

The `templatefile` function 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)
```

We recommend using the `.pkrtpl.hcl` file extension when using the `templatefile` function to create templates. Packer treats HCL templates as combination of file and template. As a result, HCL template files have slightly different set of features than the templates with a `.pkr.hcl` extension. Using the `.pkr.hcl` extension also enables syntax highlighters to properly understand your file.

The template syntax is the same as for string templates in the main HCL2
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 Packer, 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 HCL2 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 run.

## Examples

### Lists

Given a template file backends.tpl with the following content:

```hcl
%{ for addr in ip_addrs ~}
backend ${addr}:${port}
%{ endfor ~}
```

The templatefile function renders the template:

```shell-session
> templatefile("${path.root}/backends.tmpl", { 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.tmpl with the following content:

```hcl
%{ for config_key, config_value in config }
set ${config_key} = ${config_value}
%{ endfor ~}
```

The templatefile function renders the template:

```shell-session
> templatefile(
               "${path.root}/config.tmpl",
               {
                 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 or yamlencode, specifying the value to encode using
normal expression syntax as in the following examples:

```hcl
${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.tmpl` 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 rather than by using template directives.

```
{"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 and yamlencode.

## Related Functions

- [`file`](/packer/docs/templates/hcl_templates/functions/file/file) reads the contents
  of a file at a given path.
- [`fileexists`](/packer/docs/templates/hcl_templates/functions/file/fileexists)
  determines whether a file exists at a given path.
