我遇到的问题与负载均衡器前端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
我认为您正在尝试做的事情很有意义,应该可以实现。注意事项:
for_each
块中,您可以使用each.value
访问该值(在这种情况下,这是公共ip对象)。有关详情,请参见for_each documentation。ip_address
是指实际的分配IP,而不是对象count
在for_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
}
韦斯利,非常感谢您的回复。它给了我确认我需要通读的确认,并且我实际上正朝着正确的方向前进。昨晚我才能够测试解决方案。经过了更多的研究才能最终使它工作。