Merging maps within a list

I have the following output example:

  + test = [
      + {
          + hostname1 = "ocid...asdf"
          + hostname2 = "ocid...fdsa"
      + {
          + hostname3 = "ocid...qwer"
          + hostname4 = "ocid...rewq"
      + {
          + hostname5 = "ocid...zxcv"
          + hostname6 = "ocid...vcxz"

I would like my output to look like this:

  + test = [
      + hostname1 = "ocid...asdf"
      + hostname2 = "ocid...fdsa"
      + hostname3 = "ocid...qwer"
      + hostname4 = "ocid...rewq"
      + hostname5 = "ocid...zxcv"
      + hostname6 = "ocid...vcxz"

I’ve tried using the merge function, but that doesn’t seem to work. Here’s the terraform code the produces the first output:

locals {
   backends = 
[
   {
      hostname1 = {
         id = "ocid...asdf"
         ip = "someIPAddress"
      }
      hostname2 = {
         id = "ocid...fdsa"
         ip = "someIPAddress"
      }
   }
   {
      hostname3 = {
         id = "ocid...qwer"
         ip = "someIPAddress"
      }
      hostname4 = {
         id = "ocid...rewq"
         ip = "someIPAddress"
      }
   }
   {
      hostname5 = {
         id = "ocid...zxcv"
         ip = "someIPAddress"
      }
      hostname6 = {
         id = "ocid...vcxz"
         ip = "someIPAddress"
      }
   }
]

output "test" {
  value = flatten([ for key, value in local.backends : merge({ for k, v in value : k => v.id }) ])
}

Not sure what I’m doing wrong, I feel like I’m close but I just don’t know what I need to do next.

Hi @brett.tafel,

The data you’re showing isn’t complete enough to tell exactly what it is, but I’m guessing it’s a list of simple maps?

If that’s the case, you can just use merge on its own to merge all the maps:

merge(local.test...)

Which outputs:

{
  "hostname1" = "ocid...asdf"
  "hostname2" = "ocid...fdsa"
  "hostname3" = "ocid...qwer"
  "hostname4" = "ocid...rewq"
  "hostname5" = "ocid...zxcv"
  "hostname6" = "ocid...vcxz"
}

@jbardin thanks for your reply.

It’s actually coming out to be a list of maps with children maps in which I’m trying to get the children maps to be the new parent map if that makes sense. I got it figured out by doing the following and adding additional local variables:

outputs = merge(data.terraform_remote_state.mgt_backends, data.terraform_remote_state.prd_backends)

backends_from_state = flatten(tolist([ for k, v in local.outputs: { for key, value in v.outputs : key => value }]))
  
  backends_flatten = flatten([
    for value in local.backends_from_state : [
      for k, v in value : {
        name = k
        id = v.id
        ip = v.ip
      }
    ]
  ])

  backends = { for key, value in local.backends_flatten : value.name => value }

Which gave me a much more desired output of

hostname1 = {
   id = blah
   ip = blahblah
}
hostname2 = {
   id = blah2
   ip = blahblah2
}
etc...

This way I can reference ids by using the key of the hostname, whereas before they were being grouped by the parent numbered key for the for_each of the remote_state data sources.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.