Hello all,
Is there a way to generate some Terraform JSON (version 0.12 btw), using a template file?
Here is what the template file look like:
{
"environment": ${TO_BE_REPLACED}
}
Here is my map:
variable "endpoints" {
type = list
default = [
{ POF = "pif" },
{ PAF = "pouf" }
]
}
And here is what I’d like to obtain:
{
"environment": [
{
"name": "POF",
"value": "pif"
},
{
"name": "PAF",
"value": "pouf"
}
]
}
So far, I “manually” got something that looked like I wanted:
data "template_file" "task_template" {
template = file("${path.module}/data/${var.service_name}.json")
vars = {
TO_BE_REPLACED = jsonencode(list({"name" = "POF", "value" = "pif"}))
}
}
But, I’m struggling getting my array around this…
Any ideas? Thank you!
Thanks to the help by my colleague Sergey, I got around this; the only missing part was the for loop, and using a map rather than a list
variable "endpoints_map" {
type = map(string)
default = {
"POF"="pif",
"PAF"="pouf"
}
}
locals {
remap_entries = [
for k, v in var.endpoints_map : {
name = k
value = v
}
]
}
data "template_file" "task_template" {
template = file("${path.module}/data/${var.service_name}.json")
vars = {
TO_BE_REPLACED = jsonencode(local.remap_entries)
}
}
1 Like
Hi @anthonydahanne!
The template_file
data source is primarily there for Terraform 0.11 users. For Terraform 0.12 you can use the templatefile
function instead, which is built in to Terraform and integrates better with the rest of the language.
With that said, for generating JSON we should always use jsonencode
rather than templates, because then Terraform can ensure that the result has valid JSON syntax. It’s a very common problem to try to generate by concatenating strings together and find that the result isn’t valid due to incorrect escaping, missing colons, etc.
For a simple example, you can just include the jsonencode
call directly in the configuration:
# In your main configuration
locals {
task_template = jsonencode({
"environment": jsonencode([{"name" = "POF", "value" = "pif"}])
})
}
If the JSON value you want to generate is too large to include directly in the Terraform configuration, or as in your case the specific file to choose depends on a variable, you can use jsonencode
from your external template:
# In your main configuration
locals {
task_template = templatefile("${path.module}/data/${var.service_name}.json.tmpl", {
environment = [{"name" = "POF", "value" = "pif"}]
})
}
…and then, in the .json.tmpl
file:
${jsonencode({
"environment": environment
})}
Because the entire template is a single interpolation sequence, the result will just be the result of that jsonencode
call and nothing else.
2 Likes