我想要的
在地形中,我有一张地图service_map
:
variable "service_map" {
type = map
description = "Map of some services and their ports."
default = {
"dns" = "53"
"web" = "443"
"ssh" = "22"
"proxy" = ""
}
}
要在 AWS 上创建 LB 侦听器,我想调用资源aws_lb_listener
,遍历映射service_map
,跳过所有没有值的项目(在本例中,仅proxy
(:
resource "aws_lb_listener" "listeners" {
for_each = var.service_map
load_balancer_arn = aws_lb.all_lbs[each.key].arn
port = each.value
protocol = each.key != "dns" ? "TCP" : "TCP_UDP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.service_map-tg[each.key].arn
}
}
我尝试了什么
- 使用所有键=值对创建第二个本地映射,其中值不为空:
locals {
service_map_temp = [ for service, port in var.service_map : service, port if port != "" ]
}
哪个不起作用:Extra characters after the end of the 'for' expression.
.我想有比这种方法更聪明的解决方案。
- 想法:跳过空
each.value
s:
resource "aws_lb_listener" "listeners" {
for_each = var.service_map
load_balancer_arn = aws_lb.all_lbs[each.key].arn
port = each.value != "" # Skipping part
protocol = each.key != "dns" ? "TCP" : "TCP_UDP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.service_map-tg[each.key].arn
}
}
但我怀疑这是否有效,因为我仍在调用资源但端口为空,这将失败。由于我刚刚开始使用terraform,因此我确信有一个我还没有想到/读到的解决方案。
您的第一个解决方案失败,因为您使用了列表括号[ ... ]
但您打算生成地图。要从for
表达式生成地图,请使用地图括号{ ... }
:
locals {
service_map_temp = {
for service, port in var.service_map :
service => port if port != ""
}
}
主要区别在于,映射for
表达式在冒号后需要两个表达式(键和值(,而列表for
表达式只需要一个表达式。
如果您愿意,可以直接在for_each
参数中内联该表达式,将所有内容放在一个块中:
resource "aws_lb_listener" "listeners" {
for_each = {
for service, port in var.service_map :
service => port if port != ""
}
load_balancer_arn = aws_lb.all_lbs[each.key].arn
port = each.value
protocol = each.key != "dns" ? "TCP" : "TCP_UDP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.service_map-tg[each.key].arn
}
}
我意识到,如果您将参数设置为null
而不是空字符串""
,它将自动从映射中删除键,而无需创建 for 循环。
variable "service_map" {
type = map
description = "Map of some services and their ports."
default = {
"dns" = "53"
"web" = "443"
"ssh" = "22"
"proxy" = null
}
}
output "service_map" {
value = var.service_map
}
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
service_map = {
"dns" = "53"
"ssh" = "22"
"web" = "443"
}