我正在尝试设置Google Cloud Load Balancer,而第一步需要更新托管实例组上的命名端口,为此,我需要使用格式字符串来生成命令行调用。我觉得这应该是我可以使用terraform自动化的东西,但是我正在努力映射数据格式。
我有两组源数据。
从实例组资源中:
data "google_compute_instance_group" "all" {
count = "${length(var.backend)}"
self_link = "${element(var.backend, count.index)}"
}
我从data.google_compute_instance_group.all.*.named_port
获取现有的命名端口,格式为:
[
[
map[name:https port:30443],
map[name:http port:30080]
],
[
map[name:https port:30443],
map[port:30080 name:http]
]
]
我还想确保在自己的映射中定义了端口:
variable "node_ports" {
type = "map"
default = {
"https" = "30443"
"monitor" = "30012"
}
}
这些之间可能有重叠;我想选择在变量中定义的值。 (所有实例组的命名端口都相同。)
首先,我想将两个映射合并为一个映射,以确保每个名称都有一个端口。如何将地图列表的第一个列表转换为单个地图,以便获得此地图?
{
"http" = "30080"
"https" = "30443"
"monitor" = "30012"
}
第二,我想将所有这些转换为命令行所需的格式:
gcloud --project ${var.project} compute instance-groups set-named-ports ${basename(var.backend[count.index])} --named-ports=https:443,http:30080,monitor:30012
我认为我可以使用jsonencode
骇客来做到这一点,但我对更好的解决方案感兴趣:
"${replace(jsonencode(named_ports), "/[\\{\\}\"\\s]/", "")}"
答案 0 :(得分:1)
我能够使用for表达式使用terraform 0.12.x重新排列地图列表的列表。打破这句话
merge({ for l in local.lolom[0] : l.name => l.port }, { monitor = local.monitor })
for l in local.lolom[0]
表示的地图的第一个列表{ https = 30443, http = 30080 }
然后,merge()
将我们的地图与monitor
地图结合起来,以提供预期的结果
{
"http" = "30080"
"https" = "30443"
"monitor" = "30012"
}
在不使用jsonencode
的情况下,我找不到将以上内容转换为参数的方法,但是以下内容似乎可以提供预期的结果。
locals {
lolom = [
[
{ name : "https", port : 30443 },
{ name : "http", port : 30080 }
],
[
{ name : "https", port : 30443 },
{ port : 30080, name : "http" }
]
]
monitor = 30012
first = merge({ for l in local.lolom[0] : l.name => l.port }, { monitor = local.monitor })
second = merge({ for l in local.lolom[1] : l.name => l.port }, { monitor = local.monitor })
first_args = replace(jsonencode(local.first), "/[\\{\\}\"\\s]/", "")
second_args = replace(jsonencode(local.second), "/[\\{\\}\"\\s]/", "")
}
output "first_args" {
value = local.first_args
}
output "second_args" {
value = local.second_args
}
应用
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
first_args = http:30080,https:30443,monitor:30012
second_args = http:30080,https:30443,monitor:30012