skip to Main Content

I have a task definition json file which is created via a templatefile.

Something like the below:

data "template_file" "task_definition" {
  templatefile = file("${path.module}/templates/task-definition.json")

  vars {
    environment = var.environment
  }

Within the json file (aka the task definition), I have some variables which could be a list. However the app expects them to be split. Something like the below:

      {
        "name": "MyEnvironmentVariable:0",
        "value": "123"
      },
      {
        "name": "MyEnvironmentVariable:1",
        "value": "456"
      },

In Production, there could be 10 of these (i.e. go all the way up to MyEnvironmentVariable:10), but in some testing environments it could be 2 or even 0.

How can I handle that use-case?

2

Answers


  1. Chosen as BEST ANSWER

    I ended up taking a slightly different approach which I think is more readable in the long-run, especially to people who may not have worked with Terraform before.

    I basically removed all the environment variables from the template (instead of a half/half situation I was getting into originally):

    "environment": ${task_def_environment_vars},
    

    I passed a local of all the environment variables I needed:

    task_def_environment_vars = jsonencode(local.task_def_environment_vars),
    

    And created that list by combining two lists:

    task_def_environment_vars = concat(local.common_task_def_environment_vars, var.specific_task_def_environment_vars)
    

    One list is common across all environments so no need for duplication. This can be predictable variables or hard-coded values that I want to be consistent across environments/workspaces.

    The other list is a specific set of variables depending on which environment/workspace. These are for variables which may exist for dev/qa builds but are not present in production and vice-versa. This list is stored in variables/ folder which contains different files for different environments/workspaces and is selected at runtime.


  2. There are some details missing from your question so I’m making some assumptions.

    First, it sounds like your "environment" input variable is a map of lists of strings:

    variable "environment" {
      type = map(list(string))
    }
    

    The JSON file you need to generate here needs to to flatten this into a single-level list while appending the indices to avoid conflicts between multiple values of the same name.

    The following expression should get the data structure you need:

    locals {
      environment_flat = tolist(flatten([
        for name, values in var.environment : [
          for i, value in values : {
            name  = length(values) > 1 ? "${name}:${i}" : name
            value = value
          }
        ]
      ]))
    }
    

    You can access this data structure elsewhere in you module using local.environment_flat.


    The template_file data source from the hashicorp/template provider has been obsolete since 2019 so you should not use it as part of any modern Terraform module.

    If you want to generate JSON then I would suggest using the jsonencode function.

    If your JSON data structure is complicated enough for it to be helpful to write the expression that generates it in a separate file then you can use the templatefile function as modern a replacement for the template_file data source. If you choose this option, please refer to Generating JSON or YAML from a Template to see how to write a jsonencode call inside your external template file, so that you can avoid generating JSON by string concatenation.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search