我遇到的问题是关于负载均衡器前端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
答案 0 :(得分:0)
我觉得您正在尝试做的事情很有意义,应该可以实现。注意事项:
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
}
答案 1 :(得分:0)
卫斯理, 非常感谢您的回复。它给了我确认我需要通读的确认,并且我实际上正朝着正确的方向前进。昨晚我才能够测试解决方案。经过了更多的研究才能最终使它工作。
尝试使用each.value引用一直失败。它抛出了一个类似each.value的错误,需要与for_each一起使用...这让我感到沮丧,因为for_each仅比我尝试使用/引用它的地方高2行。此外,在错误中它创建了3条错误消息,因此它使用for_each进行了迭代。不管出于什么原因,它都无法使用each.value提取值。
最终在我的LB / Azure可用区中工作的代码如下(提示,必须使用iterator选项):
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" {
iterator = pub
for_each = azurerm_public_ip.pip
content {
name = "config_${pub.value.ip_address}"
public_ip_address_id = pub.value.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 = "config_${azurerm_public_ip.pip[count.index].ip_address}"
}
根据我对迭代器选项的了解,您不必使用它,而可以直接将动态块标签中的内容作为前缀引用,但这将是冗长且笨拙的。我上面发布的代码示例是功能代码:-)。当那件事发生时,我感到非常高兴。花了几天的时间来尝试解决所有问题。
至于您关于该版本不是11版本的最后声明,我不需要所有插值语法,我正在努力进行清理。这是我要完成的任务清单上的任务之一,因为我要完成一个功能齐全的VM模块的项目。如果terraform注册表在其计算模块中具有Azure区域,那将为我节省大量时间,但是在构建所有这些代码时,我必须比只调用注册表要好得多地学习语言。
就像我在上面说的那样,再次感谢您发布答案,它证实我正朝正确的道路前进。希望我一直都在帮助别人,如果他们遇到类似的问题。请注意,对于阅读此书的任何人,我都有一个azurerm_public_ip块,该块可创建VM和LB所需的任意数量的PIP。如果有人要我添加该代码,我可以。只是给我发消息或评论我的帖子。
干杯, -Sam Kachar