Search code examples
terraformterraform-provider-awsterraform0.12+

terraform merge list of objects with common value


I have the following list of objects:

variable "accounts" {
  default =[{
          hub      = "54326543266"
          ou_name  = "test1"
          spoke    = "76547654765"
          vpc_cidr = "10.13.0.0/16"
        },
      {
          hub      = "54326543266"
          ou_name  = "test1"
          spoke    = "563904425760"
          vpc_cidr = "10.14.0.0/16"
        },
      {
          hub      = "54387632457"
          ou_name  = "test2"
          spoke    = "934960631748"
          vpc_cidr = "10.13.0.0/16"
        },
      {
          hub      = "54387632457"
          ou_name  = "test2"
          spoke    = "43892321454"
          vpc_cidr = "10.14.0.0/16"
            }
]

I want to get a list of objects that merges the objects with the same hub and ou_name with the following format:

         [{
              hub      = "54326543266"
              ou_name  = "test1"
              spokes    = [ 
                 { spoke = "76547654765", vpc_cidr = "10.13.0.0/16" },
                 { spoke = "563904425760", vpc_cidr = "10.14.0.0/16" }
            },
           {
              hub      = "54387632457"
              ou_name  = "test2"
              spokes    = [ 
                 { spoke = "934960631748", vpc_cidr = "10.13.0.0/16" },
                 { spoke = "43892321454", vpc_cidr = "10.14.0.0/16" }
            }
         ]

Solution

  • It is not the easiest to accomplish this is Terraform, but this is what we could do:

    locals {
      account_groups = [
        for k, v in { for a in var.accounts : a.hub => a... } : #group by hub
        {
          "hub" : k,
          "ou_name" : v[0].ou_name,
          "spokes" : [for index, sp in v[*].spoke : { "spoke" : sp, "vpc_cidr" : v[index].vpc_cidr }] # loop again to build the spoke inner map
        }
      ]
    }
    

    At first we group by hub each item from accounts and then we loop through this map of groups and build a new list with the desired format. The output of the code above will look something like this:

    account_groups = [
      {
        "hub" = "54326543266"
        "ou_name" = "test1"
        "spokes" = [
          {
            "spoke" = "76547654765"
            "vpc_cidr" = "10.13.0.0/16"
          },
          {
            "spoke" = "563904425760"
            "vpc_cidr" = "10.14.0.0/16"
          },
        ]
      },
      {
        "hub" = "54387632457"
        "ou_name" = "test2"
        "spokes" = [
          {
            "spoke" = "934960631748"
            "vpc_cidr" = "10.13.0.0/16"
          },
          {
            "spoke" = "43892321454"
            "vpc_cidr" = "10.14.0.0/16"
          },
        ]
      },
    ]