Looping Inside Templatefile for Valid JSON

Hiya

I have a template file consisting of lots of static JSON, with small bits that need to be filled by variables. There is a list in the file, which I would like to fill with a variable number of elements:

{
  ... lots of JSON ...

  "theList": [
    {
     ... lots more JSON

    "something": "variable"

     ... lots more JSON
    }
  ]

 ... lots of JSON
}

If the list consists of a single element, this will work:

{
  ... lots of JSON ...

  "theList": [
    %{ for this_function in function_names ~}
    {
     ... lots more JSON

    "something": ${this_function}

     ... lots more JSON
    }
    %{ endfor ~}
  ]

 ... lots of JSON
}

It does not work when there is more than a single element in the list however, since that would require a , after the first element. If I put a , in there at the end (just before the endfor, then it will not work at all, since it will always end the list with a ,, which is not valid JSON.

So I think I need a way to conditionally add a , to the JSON list, but only if it’s not the last element.

EDIT: Forgot to say that I am able to do this with the following code after the endfor:

${ this_function == element(function_names, length(function_names)-1) ? "" : "," }

but this seems kind of mental.

I think that kind of construction is what you’re stuck with, if you absolutely must assemble JSON data using text templating.

Generally, I’d try to avoid building JSON using text templating, and instead build an object structure as a Terraform expression, then serialize it to JSON using the jsonencode() function.

I recognize this may not be a simple transformation if you already have a large JSON document with only small amounts of customization.

Yup, it’s a Grafana dashboard, so getting all those fields in there is sub-optimal, to say the least :wink:

I just want to make sure there isn’t an easier way, and I’m not building hacky stuff for no reason.

If the thing you want to affect isn’t too deeply nested, it might be possible to read the JSON from a file, jsondecode() it, replace a certain part of it using an expression involving merge(), and re-jsonencode() it. This might be more palatable than templating.