String interpolation works well for short Terraform values, such as an instance name built from a prefix and an index. For larger strings, keeping fixed text and variable content together becomes cumbersome. A template provides a pattern that can generate the string from developer input; the pattern can be kept in a file. section 4.4 section 4.11
Do not use a text template when Terraform can handle the target format directly. Build JSON or YAML data as a Terraform value, then use `jsonencode` or `yamlencode`. For IAM policies, a dedicated data source can also provide structural validation and clearer errors. section 4.4.5
Listing 4.23 JSON and YAML encoding with strings and functions
locals {
json_string = <<EOT
"{ #1
\"name\": \"${var.name}\"
}"
EOT
config_object = { #2
name = var.name
}
yaml_config = yamlencode(local.config_object) #3
json_config = jsonencode(local.config_object) #3
}
Compare the hand-built JSON string with the Terraform object passed to `jsonencode` and `yamlencode`. section 4.4.5
A project template solves a different problem: repeated setup. A shared repository can supply boilerplate code and quality-control configuration for each new project. When projects need choices or generated strings rather than simple copying and manual edits, a tool such as Cookiecutter can fill those parts in. section 7.2.1
Listing 7.1 Cookiecutter template example
plugin "terraform" { #1
enabled = true
preset = "all"
}
{% if cookiecutter.__short_primary_provider == "aws" %} #2
plugin "aws" {
enabled = true
version = "0.29.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
{% endif %}
{% if cookiecutter.__short_primary_provider == "gcp" %} #3
plugin "google" {
enabled = true
version = "0.27.0"
source = "github.com/terraform-linters/tflint-ruleset-google"
}
{% endif %}
{% if cookiecutter.__short_primary_provider == "azurerm" %} #4
plugin "azurerm" {
enabled = true
version = "0.25.1"
source = "github.com/terraform-linters/tflint-ruleset-azurerm"
}
{% endif %}
Cookiecutter conditions select the AWS, Google, or Azure TFLint plugin configuration from the chosen primary provider. section 7.2.1
Listing 7.2 Calling Cookiecutter with terraform-module-cookiecutter
$ cookiecutter gh:TerraformInDepth/terraform-module-cookiecutter #1
[1/6] name (): terraform-aws-test-module #2
[2/6] Select license
1 - All Rights Reserved
2 - MIT license
3 - BSD license
4 - Apache Software License 2.0
5 - GNU General Public License v3
Choose from [1/2/3/4/5] (1):
[3/6] author (): Robert Hafner
[4/6] primary_provider (hashicorp/aws):
[5/6] provider_min_version (5.0):
[6/6] private_registry_url (): #3
$ ls -1a terraform-aws-test-module #4
.
..
.checkov.yml
.github
.gitignore
.opentofu-version
.pre-commit-config.yml
.terraform-docs.yml
.terraform-version
.tflint.hcl
LICENSE
README.md
main.tf
makefile
outputs.tf
providers.tf
variables.tf
The prompted invocation creates a Terraform module directory with configuration files and quality-control tooling already present. section 7.2.1




















