How to build a map from a list of maps?

Hi,

I have a list of maps like this,

map_groups  = [
   {
       dev-api-eu = {
           envs  = [
               "dev-eu-1",
               "dev-eu-2",
            ]
           hosts = [
               "dev-api-eu.lm.eu",
               "dev-api-eu.lm1.co.eu",
            ]
        }
       dev-api-uk = {
           envs  = [
               "dev-uk-1",
               "dev-uk-2",
            ]
           hosts = [
               "dev-api-uk.lm.co.uk",
               "dev-api-uk.lm1.co.uk",
            ]
        }
    },
   {
       dev-api-us = {
           envs  = [
               "dev-us-1",
               "dev-us-2",
            ]
           hosts = [
               "dev-api-us.lm.com",
               "dev-api-us.lm1.com",
            ]
        }
    },
]

And I would like to change that into a map,

With the below code,

map_groups = {
    for record in local.list_envs:
      keys(record)[0] => values(record)[0]
  }

I am able to get my desired map, but it obviously omits the 2nd record in the first map,

map_groups  = {
   dev-api-eu = {
       envs  = [
           "dev-eu-1",
           "dev-eu-2",
        ]
       hosts = [
           "dev-api-eu.lm.eu",
           "dev-api-eu.lm1.co.eu",
        ]
    }
   dev-api-us = {
       envs  = [
           "dev-us-1",
           "dev-us-2",
        ]
       hosts = [
           "dev-api-us.lm.com",
           "dev-api-us.lm1.com",
        ]
    }
}

How do I change the below code to not hardcode the index (0) and convert all of them into a continuous map?

map_groups = {
    for record in local.list_envs:
      keys(record)[0] => values(record)[0]
  }

Hi @arun-a-nayagam,

Could you share an example of what you would like the result to look like, given the input you’ve shown here? I don’t currently understand what shape of data structure you are intending to produce.

Hi @apparentlymart ,

With this being the input,

list_groups = [
 {
     "dev-api-eu" = {
         envs  = [
             "dev-eu-1",
             "dev-eu-2",
          ]
         hosts = [
             "dev-api-eu.lm.eu",
             "dev-api-eu.lm1.co.eu",
          ]
      }
     "dev-api-uk" = {
         envs  = [
             "dev-uk-1",
             "dev-uk-2",
          ]
         hosts = [
             "dev-api-uk.lm.co.uk",
             "dev-api-uk.lm1.co.uk",
          ]
      }
  },
 {
     "dev-api-us" = {
         envs  = [
             "dev-us-1",
             "dev-us-2",
          ]
         hosts = [
             "dev-api-us.lm.com",
             "dev-api-us.lm1.com",
          ]
      }
  },
]

I would like the map to be,

map_groups            = {
   dev-api-eu = {
       envs  = [
           "dev-eu-1",
           "dev-eu-2",
        ]
       hosts = [
           "dev-api-eu.lm.eu",
           "dev-api-eu.lm1.co.eu",
        ]
    }
    dev-api-uk = {
         envs  = [
             "dev-uk-1",
             "dev-uk-2",
          ]
         hosts = [
             "dev-api-uk.lm.co.uk",
             "dev-api-uk.lm1.co.uk",
          ]
      }
   dev-api-us = {
       envs  = [
           "dev-us-1",
           "dev-us-2",
        ]
       hosts = [
           "dev-api-us.lm.com",
           "dev-api-us.lm1.com",
        ]
    }
}

Hi @arun-a-nayagam,

If you know that the keys will be unique across all of the maps in list_groups then you can use the merge function to produce a single map containing all of the elements from the maps in your list:

merge(local.list_groups...)

If you every have the same key (like dev-api-us) in more than one of the maps in the list then Terraform will keep the last value it saw for each key, taking the maps in the order given in the list.

1 Like