我正在尝试使用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需要坚持下去。
答案 0 :(得分:2)
您可以为此使用Terraform 0.12中的动态块功能。
resource "aws_lb" "this" {
name = "eks-${var.cluster_name}"
load_balancer_type = "network"
dynamic "subnet_mapping" {
for_each = [ for i in range(length(aws_subnet.public)): {
subnet_id = aws_subnet.public[i].id
allocation_id = aws_eip.lb[i].id
} ]
content {
subnet_id = subnet_mapping.value.subnet_id
allocation_id = subnet_mapping.value.allocation_id
}
}
}
答案 1 :(得分:1)
Terraform目前不允许您在资源节/子资源上使用count
元参数。
有一个issue tracking this on Github,但目前还没有对它进行任何工作AFAIK。
Hashicorp员工在该线程中回复(apparentlymart)目前正在开发一个新版本的HCL,可能在将来支持这样的事情。
答案 2 :(得分:0)
一个非常丑陋的解决方案可能是为每个可能的AZ数量创建一个资源。 ex(代码未经测试):
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 ...
}
我还没有测试过前面的代码,但这里有一些我知道有用的代码。我有一个领事模块,如果它没有被用于保险库,就会创建一个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资源。