Terraform templatefile() function renders a file as a template with variables per the Terraform docs. Use for nginx.conf, cloud-init scripts, Kubernetes manifests - any file with templated values. The team that uses templatefile() has DRY, configurable config files generated by Terraform.
Table of contents
- The templatefile function
- The template file
- Template syntax
- Loops in templates
- Conditionals
- Use cases
- Alternative: the deprecated template_file data source
- FAQ
The templatefile function
resource "local_file" "nginx_config" {
content = templatefile("${path.module}/nginx.conf.tpl", {
port = 80
upstream = "myapp:8080"
ssl_cert = "/etc/ssl/cert.pem"
})
filename = "/etc/nginx/nginx.conf"
}
The team that uses templatefile() has config files generated from Terraform variables.
The template file
nginx.conf.tpl:
server {
listen ${port};
location / {
proxy_pass http://${upstream};
}
ssl_certificate ${ssl_cert};
}
The ${var} syntax is Terraform template syntax. The team that writes templates has DRY config.
Template syntax
Terraform template syntax (not Jinja2):
${var}- variable substitution.$${literal}- escape dollar sign (literal${).%{ for x in list }...%{ endfor }- loops.%{ if cond }...%{ endif }- conditionals.
The team that uses these has full template power.
Loops in templates
content = templatefile("${path.module}/config.tpl", {
upstreams = ["app1:8080", "app2:8080", "app3:8080"]
})
config.tpl:
%{ for upstream in upstreams ~}
upstream ${upstream} { server ${upstream}; }
%{ endfor ~}
The team that uses loops has dynamic config generation.
Conditionals
%{ if ssl_enabled ~}
listen 443 ssl;
%{ else ~}
listen 80;
%{ endif ~}
The team that uses conditionals has environment-specific config in one template.
Use cases
- nginx/Apache configs: virtual hosts, upstreams.
- cloud-init scripts: bootstrap scripts with EC2 metadata.
- systemd units: service files with paths and env vars.
- K8s manifests: deployment YAML with image tags.
- Bash scripts: post-install with paths.
The team that uses templates has config as code, fully managed.
Alternative: the deprecated template_file data source
Older Terraform used data "template_file". This is deprecated - use templatefile() function. The team that has old code has migration work.
FAQ
What’s the difference between templatefile() and the template_file data source?
templatefile() is the modern function (inlined). template_file data source is deprecated. The team that uses templatefile() has the current syntax.
Can I use Jinja2 syntax?
No - Terraform has its own template syntax (similar but not Jinja2). The team that uses Terraform template syntax has portable Terraform code.
How do I include a file in a template?
Use fileexists() or file() function. The team that uses file() inlines the content; templatefile() renders a template.
Can templates reference other templates?
Yes - templatefile() can be nested. The team that uses composition has modular templates.
What about YAML output?
Templates can produce any text format - YAML, JSON, INI, etc. The team that uses templates for K8s manifests has full control.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: