As you know, Terraform's configuration language is the HashiCorp configuration language. While there are a lot of questionable things about HCL, it's Terraform's use of it that gets more in the way of users and their goals.
Terraform expects you to hard-code a number of values such as module URLs or state backend settings that remove all ability to reuse that code across projects. Jinja can work around that since it doesn't care what the underlying template represents.
Terraform also lacks conditional logic to include/exclude resources other than janky count
attributes with ternary operators that pollute your resource state addresses.
Jinja if blocks work better for that.
And finally, it was only until recently that Terraform enabled custom provider functions. We've had custom filters in Jinja for a decade.
Here's where you can use Jinja in Terraform code:
|-- environments/
`-- stacks/
`-- vpc/
|-- base/
| |-- main.tf # you get Jinja support here (any *.tf files)
| |-- module
| | `-- main.tf # and here (if you add the module to var.stacks_jinja_enabled_modules)
| `-- script.py # but not here (since it's not Terraform code)
`-- layers/
For using variables where you typically couldn't:
module "vpc" {
source = "{{ var.module_vpc_source }}"
name = "main"
cidr = "10.0.0.0/16"
}
For including code conditionally:
{% if var.enable_cloudtrail %}
resource "aws_cloudtrail" "main" {
name = "main"
}
{% endif %}