JonLinux
JonLinux

Reputation: 183

terraform build list of maps

I am trying to build list of maps for three logging services in order to pass to Kubernetes service creation resource. I have tried two possible ways to represent input variables , used locals to generate the requires list without success.

variable "elk_services1" = {
  default = [
    {
    name = "logs",
    ports = ["9200", "7000"],
    protocol = ["TCP"]
    namespace = "ns1"
    },
    {
    name = "elk",
    ports = ["9200", "7000", "5044", "8080"],
    protocol = ["TCP"]
    namespace = "ns2"
    },
    {
    name = "syslog"
    ports = ["514", "5200"]
    protocol = ["TCP", "UDP"]
    namespace = "ns3"
    },
 ]

variable elk_services2 = {
    default = {
    logs = {
      name = "logs",
      ports = ["9200", "7000"],
      protocol = ["TCP"]
      namespace = "ns1"
    } ,
    elk = {
      name = "elk",
      ports = ["9200", "7000", "5044", "8080"],
      protocol = ["TCP"]
      namespace = "ns2"
    },
    syslog = {
      name = "syslog"
      ports = ["514", "5200"]
      protocol = ["TCP", "UDP"]
      namespace = "ns3"
    }
  }
}

Tried this local without success.

locals {
  svc_mapping  = flatten([
     for svc in var.elk_services1 : [
       for port in svc.ports : [
         for protocol in svc.protocol : {
           svcname = svc.name
           svcport = port
           svcprotocol = try(length(protocol),0) > 0 ? protocol : "tcp"
           svcns       = svc.namespace
         }
       ]
     ]
     ])
}

The end goal is to create k8s services for each type of logs, each service with be for multiple ports/protocols.

The output I am looking for is to build list of port/protocol per service with "service name" being the key of the map .

syslog = [
    {
      ports = ["514"]
      protocol = ["TCP"]
      namespace = "ns3"
    },
    {
      ports = ["514"]
      protocol = ["UDP"]
      namespace = "ns3"
    },
    {
      ports = ["5200"]
      protocol = ["TCP"]
      namespace = "ns3"
    },
    {
      ports = ["5200"]
      protocol = ["UDP"]
      namespace = "ns3"
    },
]

logs = [
    {
      ports = ["9200"]
      protocol = ["TCP"]
      namespace = "ns1"
    },
    {
      ports = ["7000"]
      protocol = ["TCP"]
      namespace = "ns1"
    }
]

elk = [
    {
      ports = ["9200"]
      protocol = ["TCP"]
      namespace = "ns2"
    },
    {
      ports = ["7000"]
      protocol = ["TCP"]
      namespace = "ns2"
    },
    {
      ports = ["5044"]
      protocol = ["TCP"]
      namespace = "ns2"
    },
    {
      ports = ["8080"]
      protocol = ["TCP"]
      namespace = "ns2"
    }
]

Upvotes: 2

Views: 48

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17664

You got really close...

In your loop if you want the service name to be the key you need svc.name => flatten([ and then everything else is pretty much the same as you have it, just change the object to match the structure you wanted with the ports = ["9200"] not sure why you would want it like that when you know there is only one item, but I matched that.

variable "services" {
  default = {
    logs = {
      name      = "logs",
      ports     = ["9200", "7000"],
      protocol  = ["TCP"]
      namespace = "ns1"
    },
    elk = {
      name      = "elk",
      ports     = ["9200", "7000", "5044", "8080"],
      protocol  = ["TCP"]
      namespace = "ns2"
    },
    syslog = {
      name      = "syslog"
      ports     = ["514", "5200"]
      protocol  = ["TCP", "UDP"]
      namespace = "ns3"
    }
  }
}

locals {
  svc_mapping = {
    for svc in var.services : svc.name => flatten([
      for port in svc.ports : [
        for protocol in svc.protocol : {
          ports     = [port]
          protocol  = [try(length(protocol), 0) > 0 ? protocol : "tcp"]
          namespace = svc.namespace
        }
      ]
    ])
  }
}

output "test" {
  value = local.svc_mapping
}

and a TF plan on that will give us:

Changes to Outputs:
  + test = {
      + elk    = [
          + {
              + namespace = "ns2"
              + ports     = [
                  + "9200",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
          + {
              + namespace = "ns2"
              + ports     = [
                  + "7000",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
          + {
              + namespace = "ns2"
              + ports     = [
                  + "5044",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
          + {
              + namespace = "ns2"
              + ports     = [
                  + "8080",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
        ]
      + logs   = [
          + {
              + namespace = "ns1"
              + ports     = [
                  + "9200",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
          + {
              + namespace = "ns1"
              + ports     = [
                  + "7000",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
        ]
      + syslog = [
          + {
              + namespace = "ns3"
              + ports     = [
                  + "514",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
          + {
              + namespace = "ns3"
              + ports     = [
                  + "514",
                ]
              + protocol  = [
                  + "UDP",
                ]
            },
          + {
              + namespace = "ns3"
              + ports     = [
                  + "5200",
                ]
              + protocol  = [
                  + "TCP",
                ]
            },
          + {
              + namespace = "ns3"
              + ports     = [
                  + "5200",
                ]
              + protocol  = [
                  + "UDP",
                ]
            },
        ]
    }

Upvotes: 1

Related Questions