Search code examples
terraformyamlhclterraform-template-file

Why does my terraform template for loop only add last element of map?


I have a map in terraform that I'm trying to use:

myfile.hcl

accounts = {
  x = [
    locals.account_ids.a,
    locals.account_ids.b,
    locals.account_ids.c
  ],
  y = [
    locals.account_ids.a
  ],
  z = [
    locals.account_ids.b
  ]
}

And in my templated file

myfile.yml

  #%{~ for name, ids in accounts }
  - group_name: "${name}"
    #%{~ for id in ids }
    iam_role_arns:
      - "arn:aws:iam::${id}:role/allow-${name}-access"
    #%{ endfor ~}
  #%{ endfor ~}

The issue is that for accounts.x it's only adding the last value. For accounts.y and accounts.z which both have 1 id, it works fine. But if I add more than one value, it only adds the last value.


Solution

  • Are you checking the resulting output YAML file, or just the result of applying that YAML file in some way? Because it looks like you are duplicating the iam_role_arns key inside your YAML file with each ID, which is going to result in an invalid YAML file, and probably cause some of the values in the file to be ignored.

    Given your template, your resulting file is going to look like this:

      - group_name: "x"
        iam_role_arns:
          - "locals.account_ids.a"
        iam_role_arns:
          - "locals.account_ids.b"
        iam_role_arns:
          - "locals.account_ids.c"
    

    If you change your template like so:

      #%{~ for name, ids in accounts }
      - group_name: "${name}"
        iam_role_arns:
        #%{~ for id in ids }
          - "arn:aws:iam::${id}:role/allow-${name}-access"
        #%{ endfor ~}
      #%{ endfor ~}
    

    Then the result would look like this, which has to be what you are actually trying to achieve:

      - group_name: "x"
        iam_role_arns:
          - "locals.account_ids.a"
          - "locals.account_ids.b"
          - "locals.account_ids.c"