aws_lb 的动态子网映射
Dynamic subnet mappings for aws_lb
我正在尝试使用 Terraform 创建网络负载平衡器,重要的是它与受保护不被破坏的弹性 IP 相关联。
我有如下代码:
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))}"
}
我要做的是动态地制作 subnet_mapping
块,因为此代码位于模块中,我想根据传入的子网数量创建映射的数量。或者传入预定义的块。
有办法吗?对我来说重要的是相关的弹性 IP 需要保留。
如 this is now doable in Terraform 0.12 by using the dynamic
blocks特征中所述:
文档中显示了比上述链接答案更简单的示例:
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 当前不允许您在资源 stanzas/sub 资源上使用 count
元参数。
有一个 issue tracking this on Github 但据我所知目前没有任何工作在做。
在该主题 (apparentlymart) 中回复的 Hashicorp 员工目前正在开发新版本的 HCL,将来可能会支持类似的功能。
一个非常丑陋的解决方案可能是为每个可能的 AZ 数量创建一个资源。前(代码未经测试):
data "aws_availability_zones" "available" {}
resource "aws_lb" "lb_2_azs" {
count = "${length(data.aws_availability_zones.available.names) == 2 ? 1 : 0 }"
... all the rest of the stuff here ...
}
resource "aws_lb" "lb_3_azs" {
count = "${length(data.aws_availability_zones.available.names) == 3 ? 1 : 0 }"
... all the rest of the stuff here ...
}
然后在您的模块中输出类似这样的内容:
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 ...
}
我没有测试过以前的代码,但这里有一些我知道有效的代码。我有一个用于 consul 的模块,如果它没有被用于 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_group 和您需要的任何其他引用 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 创建网络负载平衡器,重要的是它与受保护不被破坏的弹性 IP 相关联。
我有如下代码:
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))}"
}
我要做的是动态地制作 subnet_mapping
块,因为此代码位于模块中,我想根据传入的子网数量创建映射的数量。或者传入预定义的块。
有办法吗?对我来说重要的是相关的弹性 IP 需要保留。
如dynamic
blocks特征中所述:
文档中显示了比上述链接答案更简单的示例:
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 当前不允许您在资源 stanzas/sub 资源上使用 count
元参数。
有一个 issue tracking this on Github 但据我所知目前没有任何工作在做。
在该主题 (apparentlymart) 中回复的 Hashicorp 员工目前正在开发新版本的 HCL,将来可能会支持类似的功能。
一个非常丑陋的解决方案可能是为每个可能的 AZ 数量创建一个资源。前(代码未经测试):
data "aws_availability_zones" "available" {}
resource "aws_lb" "lb_2_azs" {
count = "${length(data.aws_availability_zones.available.names) == 2 ? 1 : 0 }"
... all the rest of the stuff here ...
}
resource "aws_lb" "lb_3_azs" {
count = "${length(data.aws_availability_zones.available.names) == 3 ? 1 : 0 }"
... all the rest of the stuff here ...
}
然后在您的模块中输出类似这样的内容:
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 ...
}
我没有测试过以前的代码,但这里有一些我知道有效的代码。我有一个用于 consul 的模块,如果它没有被用于 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_group 和您需要的任何其他引用 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
}
}
}