如何使用Terraform动态块在Az负载均衡器中构建多个前端ip,该负载均衡器利用公共ip来获取Azure可用区

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

我遇到的问题与负载均衡器前端ip有关,因此它可以使用唯一的公用IP来访问位于不同可用区域中的另一台服务器。我在创建公共IP时使用了count,但在负载均衡器上却没有使用count,因为我不想为每个服务器都添加一个新的LB。如果我能以某种方式将公共IP保存到变量中,那么我可以在动态块内使用for_each引用它们,但我找不到解决方法。这是我到目前为止的代码,但是不能按原样工作。这个问题可能没有解决方案,这确实很令人讨厌。顺便说一句,我正在使用下面的split函数,因此它将返回属性所需的列表。有点破烂,但确实有效。

resource "azurerm_public_ip" "pip" {
  count               = "${var.nblinuxvms}"
  name                = "${var.proj_name}-lbpip${count.index}-${var.region}-${var.app_env}"
  location            =  var.region
  resource_group_name = "${azurerm_resource_group.rg.name}"
  allocation_method   = "Static"   #Public IP Standard SKUs require allocation_method to be set to Static
  sku                 = "Standard" #Standard SKU Required for Zones
  domain_name_label   = "${var.proj_name}${count.index}${split("", "${element(["1", "2", "3"], "${count.index}")}")}"
  zones = "${var.avzones}" ? split("", "${element(["1", "2", "3"], "${count.index}")}") : null
}
resource "azurerm_lb" "lb" {
  name                = "externallb"
  location            = "${azurerm_resource_group.rg.location}"
  resource_group_name = "${azurerm_resource_group.rg.name}"
  sku                 = "standard" #standard SKU needed to support zones
 dynamic "frontend_ip_configuration" {
   for_each             = "${azurerm_public_ip.test.*.ip_address}" #this is the problem line. I need a way to store all the IPs in a variable and then iterate through them for each new frontend ip configuration
   content{
     name  = "primary${count.index}" #This name is also important as this is how I'll connect the nat rule down below
     public_ip_address_id = "${azurerm_public_ip.pip.id}"
  }
resource "azurerm_lb_nat_rule" "lbnr" {
  count                          = "${var.nblinuxvms}"
  resource_group_name            = "${azurerm_resource_group.rg.name}"
  loadbalancer_id                = "${azurerm_lb.lb.id}"
  name                           = "SSHHost${count.index}"
  protocol                       = "Tcp"
  frontend_port                  = "${2200 + count.index}"
  backend_port                   = 22
  frontend_ip_configuration_name = "primary${count.index}" #This name needs to match the LB Front End IP Configuartion
}

frontend_ip_configuration_name需要与负载均衡器名称匹配。带有for_each的动态块似乎是针对特定问题的最佳解决方案,因为它不是一种资源...但是我没有看到一种将公共IP保存到我可以引用的任何变量的方法。如果没有解决方案,人们将如何解决?通过为每个Azure可用性区域创建一个单独的LB?由于它必须是一个标准,而不是看起来成本高昂的基本LB。希望我只是错过了一些东西。任何帮助将不胜感激。注意我只共享了我的terraform项目中的relevent代码。如果需要更多代码,请让我知道。(我的代表声望太低,因此我无法将动态块添加到问题标签中。)谢谢,-Sam Kachar

azure foreach load-balancing terraform azure-public-ip
2个回答
0
投票

我认为您正在尝试做的事情很有意义,应该可以实现。注意事项:

  • for_each块中,您可以使用each.value访问该值(在这种情况下,这是公共ip对象)。有关详情,请参见for_each documentation
  • [ip_address是指实际的分配IP,而不是对象
  • [countfor_each块中不可用,因此frontend_ip_configuration块的名称应直接从公共ip对象推导。
  • 鉴于以上所述,您可以尝试类似的方法(未经测试!):

resource "azurerm_lb_nat_rule" "lbnr" {
  count                          = "${var.nblinuxvms}"
  ...
  frontend_ip_configuration_name = "config_${azurerm_public_ip[count].name}"
}
dynamic "frontend_ip_configuration" {
   for_each = "${azurerm_public_ip.pip}"
   content{
     name                 = "config_${each.value.name}" 
     public_ip_address_id = "${each.value.id}"
  }

我假设您使用的是Terraform 0.12,因为for_each在0.11中不可用。您使用的详细插值语法已在最新版本中弃用,最好使用新的语法:

resource "azurerm_lb_nat_rule" "lbnr" {
  count                          = var.nblinuxvms
  ...
  frontend_ip_configuration_name = "config_${azurerm_public_ip[count].name}"
}
dynamic "frontend_ip_configuration" {
   for_each = azurerm_public_ip.pip
   content{
     name                 = "config_${each.value.name}" 
     public_ip_address_id = each.value.id
}

0
投票

韦斯利,非常感谢您的回复。它给了我确认我需要通读的确认,并且我实际上正朝着正确的方向前进。昨晚我才能够测试解决方案。经过了更多的研究才能最终使它工作。

© www.soinside.com 2019 - 2024. All rights reserved.