Amazon web services aws_lb的动态子网映射

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

我正在尝试用Terraform创建一个网络负载均衡器,重要的是它与弹性IP相关联,可以保护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))}"
}
我要做的是动态地生成
子网映射
块,因为此代码位于模块中,我想根据传入的子网数量创建映射的数量。要么这样,要么传入预定义的块

有办法做到这一点吗?对我来说,重要的是相关的弹性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将出错。是的,最近这已成为一个非问题,您将接受这一点,因为升级到新版本修复了该问题及其最干净的解决方案。正如前一个被接受的回答中所提到的,最近这已经成为一个不存在的问题,我们将接受这一点,因为升级到新的闪亮解决方案解决了这个问题,并且是最干净的解决方案。正如先前被接受的答案所暗示的那样