Amazon web services aws_lb的动态子网映射
我正在尝试用Terraform创建一个网络负载均衡器,重要的是它与弹性IP相关联,可以保护IP免受破坏 我有如下代码:Amazon web services aws_lb的动态子网映射,amazon-web-services,terraform,terraform-provider-aws,Amazon Web Services,Terraform,Terraform Provider Aws,我正在尝试用Terraform创建一个网络负载均衡器,重要的是它与弹性IP相关联,可以保护IP免受破坏 我有如下代码: resource "aws_lb" "balancer" { name = "${var.name}-nlb" internal = "${var.internal}" load_balancer_type = "network" subnets = ["${data.aws_subnet_ids.selected.i
resource "aws_lb" "balancer" {
name = "${var.name}-nlb"
internal = "${var.internal}"
load_balancer_type = "network"
subnets = ["${data.aws_subnet_ids.selected.ids}"]
subnet_mapping {
subnet_id = "someid"
allocation_id = "someid"
}
subnet_mapping {
subnet_id = "someid"
allocation_id = "someid"
}
subnet_mapping {
subnet_id = "someid"
allocation_id = "someid"
}
tags = "${merge(var.tags,
map("Terraform", "true"),
map("Environment", var.environment))}"
}
我要做的是动态地生成子网映射
块,因为此代码位于模块中,我想根据传入的子网数量创建映射的数量。要么这样,要么传入预定义的块
有办法做到这一点吗?对我来说,重要的是相关的弹性IP需要保持不变。如本文所述,现在可以在Terraform 0.12中使用以下功能:
文档中显示了一个比上述链接答案更简单的示例:
resource "aws_security_group" "example" {
name = "example" # can use expressions here
dynamic "ingress" {
for_each = var.service_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
}
}
}
原件: Terraform目前不允许您在资源节/子资源上使用
count
元参数
有一个,但目前还没有任何工作正在进行中
在该线程()中响应的Hashicorp员工目前正在开发新版本的HCL,该版本将来可能支持类似的功能。如本文所述,现在可以在Terraform 0.12中使用以下功能:
文档中显示了一个比上述链接答案更简单的示例:
resource "aws_security_group" "example" {
name = "example" # can use expressions here
dynamic "ingress" {
for_each = var.service_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
}
}
}
原件: Terraform目前不允许您在资源节/子资源上使用
count
元参数
有一个,但目前还没有任何工作正在进行中
在该线程()中响应的Hashicorp员工目前正在开发一个新版本的HCL,该版本将来可能会支持类似的内容。一个非常丑陋的解决方案可能是为每个可能数量的AZ创建一个资源。ex(代码未测试): 然后在您的模块中,类似这样的输出可能会起作用:
output "lb_id" {
value = "${element(concat(aws_lb.lb_2_azs.*.id, aws_lb.lb_3_azs.*.id, list("")), 0)}"
}
如何处理侦听器和LB可能需要的其他资源:
resource "aws_lb_listener" "listener" {
count = "${length(concat(aws_lb.lb_2_azs.*.id, aws_lb.lb_3_azs.*.id))}"
load_balancer_arn = "${element(concat(aws_lb.lb_2_azs.*.id, aws_lb.lb_3_azs.*.id, list("")), 0)}"
... rest of the resource settings ...
}
我还没有测试前面的代码,但我知道有一些代码是有效的。我有一个Consor模块,用于在未用于vault的情况下创建NLB:
resource "aws_lb" "consul" {
name = "${var.lb_name}"
count = "${var.for_vault ? 0 : 1}"
internal = true
subnets = ["${var.subnet_ids}"]
load_balancer_type = "network"
idle_timeout = 60
}
resource "aws_lb_listener" "consul" {
count = "${var.for_vault ? 0 : 1}"
load_balancer_arn = "${aws_lb.consul.arn}"
port = 8500
protocol = "TCP"
default_action {
target_group_arn = "${aws_lb_target_group.consul.arn}"
type = "forward"
}
}
您可以对aws_lb_target_组和您需要的任何其他资源使用相同的计数技巧,这些资源引用了aws_lb资源中的任何一个。一个非常丑陋的解决方案可能是为每个可能数量的AZ创建一个资源。ex(代码未测试): 然后在您的模块中,类似这样的输出可能会起作用:
output "lb_id" {
value = "${element(concat(aws_lb.lb_2_azs.*.id, aws_lb.lb_3_azs.*.id, list("")), 0)}"
}
如何处理侦听器和LB可能需要的其他资源:
resource "aws_lb_listener" "listener" {
count = "${length(concat(aws_lb.lb_2_azs.*.id, aws_lb.lb_3_azs.*.id))}"
load_balancer_arn = "${element(concat(aws_lb.lb_2_azs.*.id, aws_lb.lb_3_azs.*.id, list("")), 0)}"
... rest of the resource settings ...
}
我还没有测试前面的代码,但我知道有一些代码是有效的。我有一个Consor模块,用于在未用于vault的情况下创建NLB:
resource "aws_lb" "consul" {
name = "${var.lb_name}"
count = "${var.for_vault ? 0 : 1}"
internal = true
subnets = ["${var.subnet_ids}"]
load_balancer_type = "network"
idle_timeout = 60
}
resource "aws_lb_listener" "consul" {
count = "${var.for_vault ? 0 : 1}"
load_balancer_arn = "${aws_lb.consul.arn}"
port = 8500
protocol = "TCP"
default_action {
target_group_arn = "${aws_lb_target_group.consul.arn}"
type = "forward"
}
}
您可以对aws_lb_target_组和您需要的任何其他资源使用相同的计数技巧,这些资源引用了aws_lb资源中的任何一个。您可以使用Terraform 0.12中的动态块功能
resource "aws_lb" "balancer" {
name = "${var.name}-nlb"
load_balancer_type = "network"
dynamic "subnet_mapping" {
for_each = aws_subnet.public.*.id
content {
subnet_id = subnet_mapping.value
allocation_id = aws_eip.lb[subnet_mapping.key].id
}
}
}
您可以使用Terraform 0.12中的动态块功能进行此操作
resource "aws_lb" "balancer" {
name = "${var.name}-nlb"
load_balancer_type = "network"
dynamic "subnet_mapping" {
for_each = aws_subnet.public.*.id
content {
subnet_id = subnet_mapping.value
allocation_id = aws_eip.lb[subnet_mapping.key].id
}
}
}
您真的有理由使用不同数量的子网吗?您是否使用不同数量的AZ在多个地区跑步?如果不是的话,你可以简化很多事情。视情况而定,这是我发布到内部存储库的一个模块。我不能假设其他人如何使用它。不,我不能假设,这不是我要问的。所以真正的问题是,我问的是可能的,因为如果不是(你不能使用count)那么你是对的,你可以简化它。那么答案是否定的。Terraform当前不允许你动态设置子资源计数。@krystanhonour我使用random_shuffle管理动态子网,我使用lifecyle忽略与子网相关的更改。同样,这是乏味的,因为您需要一次又一次地污染random_shuffle模块。这就是我管理分散在多个AZ中的基础设施的方式。您真的有理由使用不同数量的子网吗?您是否使用不同数量的AZ在多个地区跑步?如果不是的话,你可以简化很多事情。视情况而定,这是我发布到内部存储库的一个模块。我不能假设其他人如何使用它。不,我不能假设,这不是我要问的。所以真正的问题是,我问的是可能的,因为如果不是(你不能使用count)那么你是对的,你可以简化它。那么答案是否定的。Terraform当前不允许你动态设置子资源计数。@krystanhonour我使用random_shuffle管理动态子网,我使用lifecyle忽略与子网相关的更改。同样,这是乏味的,因为您需要一次又一次地污染random_shuffle模块。这就是我管理分散在多个AZ中的基础设施的方式。谢谢,很烦人,但看起来我不是唯一需要这个的人。谢谢,很烦人,但看起来我不是唯一需要这个的人。那么你如何处理侦听器规则和目标群?您需要参考aws_lb资源的Arn,如果它不存在,因为它不是由计数为0创建的,则Terraform将出错。然后如何处理侦听器规则和目标组?您需要参考aws_lb资源的Arn,如果它不存在,因为它不是由计数为0创建的,则Terraform将出错。是的,最近这已成为一个非问题,您将接受这一点,因为升级到新版本修复了该问题及其最干净的解决方案。正如前一个被接受的回答中所提到的,最近这已经成为一个不存在的问题,我们将接受这一点,因为升级到新的闪亮解决方案解决了这个问题,并且是最干净的解决方案。正如先前被接受的答案所暗示的那样