Reputation: 183
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
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