我正在尝试使用以下资源创建Azure应用程序网关: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/application_gateway
当地人是从单个地图构建的,因为我使用
url_maps
来创建其他作品,例如侦听器(每个侦听器是为每个具有唯一前端端口的服务创建的)。然而 services
用于创建其他相关的后端配置和路径规则。
因此,下面的每个 url 映射都代表具有多个后端池、设置和路径的服务。
locals {
url_maps = [
{
"name" = "service1"
"frontend_port" = 10000
"protocol" = "https"
},
{
"name" = "service2"
"frontend_port" = 20000
"protocol" = "https"
}
]
services = [
{
"frontend_port" = 10000
"name" = "one-service1"
"paths" = "/service1/one/*"
},
{
"frontend_port" = 10000
"name" = "two-service1"
"paths" = "/service1/two/*"
},
{
"frontend_port" = 20000
"name" = "one-service2"
"paths" = "/service2/one/*"
},
{
"frontend_port" = 20000
"name" = "two-service2"
"paths" = "/service2/two/*"
},
]
}
所以从地形的角度来看,这应该如下所示,但是我在
path_rule
的第二个动态块上遇到了问题。由于需要 path_rule
,因此出现错误:
At least 1 "path_rule" blocks are required.
dynamic "url_path_map" {
for_each = var.url_maps
content {
default_redirect_configuration_name = "default"
name = "${url_path_map.value.frontend_port}-${url_path_map.value.protocol}-url-path-map"
dynamic "path_rule" {
for_each = [
for s in var.services : s
### After comparing as below the error is thrown...
### "At least 1 "path_rule" blocks are required."
# if s.frontend_port == url_path_map.value.frontend_port
### After specifying correct port number, the if statement is working
### However then the same paths associated with this port are added to the url map
if s.frontend_port == 20000
]
content {
name = path_rule.value.name
backend_address_pool_name = path_rule.value.name
backend_http_settings_name = path_rule.value.name
paths = [path_rule.value.paths]
}
}
}
}
如上面代码注释中所述,如果我直接与端口号进行比较,则代码正在运行,因此不确定我在这里缺少什么,因为
url_path_map.value.frontend_port
值正在返回正确的端口号。
基于@lxop 的想法,使用本地中介......
这些循环的样子如下
combined = [
for map in local.url_maps : {
"name" : map.name,
"port" : map.frontend_port,
"services" : [
for service in local.services : {
"name" : service.name,
"paths" : service.paths
} if map.frontend_port == service.frontend_port
]
}
]
我稍微清理了循环,使端口仅位于输出对象上,并保持相同的列表结构而不是映射
完整代码如下
locals {
url_maps = [
{
"name" = "service1"
"frontend_port" = 10000
"protocol" = "https"
},
{
"name" = "service2"
"frontend_port" = 20000
"protocol" = "https"
}
]
services = [
{
"frontend_port" = 10000
"name" = "one-service1"
"paths" = "/service1/one/*"
},
{
"frontend_port" = 10000
"name" = "two-service1"
"paths" = "/service1/two/*"
},
{
"frontend_port" = 20000
"name" = "one-service2"
"paths" = "/service2/one/*"
},
{
"frontend_port" = 20000
"name" = "two-service2"
"paths" = "/service2/two/*"
}
]
combined = [
for map in local.url_maps : {
"name" : map.name,
"port" : map.frontend_port,
"services" : [
for service in local.services : {
"name" : service.name,
"paths" : service.paths
} if map.frontend_port == service.frontend_port
]
}
]
}
output "new_data" {
value = local.combined
}
TF 计划如下:
Changes to Outputs:
+ new_data = [
+ {
+ name = "service1"
+ port = 10000
+ services = [
+ {
+ name = "one-service1"
+ paths = "/service1/one/*"
},
+ {
+ name = "two-service1"
+ paths = "/service1/two/*"
},
]
},
+ {
+ name = "service2"
+ port = 20000
+ services = [
+ {
+ name = "one-service2"
+ paths = "/service2/one/*"
},
+ {
+ name = "two-service2"
+ paths = "/service2/two/*"
},
]
},
]