具有条件的 Terraform 嵌套动态块

问题描述 投票:0回答:1

我正在尝试使用以下资源创建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
值正在返回正确的端口号。

conditional-statements terraform nested block
1个回答
0
投票

基于@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/*"
                },
            ]
        },
    ]
© www.soinside.com 2019 - 2024. All rights reserved.