如何配置 AWS 网络负载均衡器以使用 Terraform 路由 HTTPS 流量?

Posted

技术标签:

【中文标题】如何配置 AWS 网络负载均衡器以使用 Terraform 路由 HTTPS 流量?【英文标题】:How do I configure AWS network load balancers to route HTTPS traffic with Terraform? 【发布时间】:2020-04-10 22:06:21 【问题描述】:

我正在尝试使用 API Gateway 的 VPC 链接将流量路由到 HTTPS 上的内部 API。 但是,VPC 链接迫使我将 API 的负载均衡器从“应用程序”更改为“网络”。

我了解网络负载平衡器位于第 4 层,因此不了解 HTTPS。

我习惯使用第 7 层应用负载均衡器。因此,我不确定应该如何在 terraform 中配置或确实使用网络负载均衡器。

以下是我在 Terraform 中配置网络负载均衡器的尝试。 健康检查失败,我不确定我做错了什么。

resource "aws_ecs_service" “app” 
  name = "$var.env-$var.subenv-$var.appname"
  cluster = "$aws_ecs_cluster.cluster.id"
  task_definition = "$aws_ecs_task_definition.app.arn"
  desired_count = "$var.desired_app_count"
  deployment_minimum_healthy_percent = 50
  deployment_maximum_percent = 200
  iam_role = "arn:aws:iam::$var.account:role/ecsServiceRole"

  load_balancer 
    target_group_arn = "$aws_lb_target_group.app-lb-tg.arn"
    container_name = "$var.env-$var.subenv-$var.appname"
    container_port = 9000
  
  depends_on = [
    "aws_lb.app-lb"
  ]


resource "aws_lb" “app-lb" 
  name               = "$var.env-$var.subenv-$var.appname"
  internal           = false
  load_balancer_type = "network"
  subnets = "$var.subnet_ids"
  idle_timeout = 600

  tags 
    Owner = ""
    Env = "$var.env"
  


resource "aws_lb_listener" “app-lb-listener" 
  load_balancer_arn = "$aws_lb.app-lb.arn"
  port = 443
  protocol = "TCP"

  default_action 
    type = "forward"
    target_group_arn = "$aws_lb_target_group.app-lb-tg.arn"
  


resource "aws_lb_target_group" “app-lb-tg" 
  name = "$var.env-$var.subenv-$var.appname"
  port = 443
  stickiness = []

  health_check 
    path = "/actuator/health"
  

  protocol = "TCP"
  vpc_id = "$var.vpc_id"

作为参考,这是我之前在尝试切换到网络负载平衡器之前配置应用程序负载平衡器的方式:

resource "aws_ecs_service" "app" 
  name = "$var.env-$var.subenv-$var.appname"
  cluster = "$aws_ecs_cluster.cluster.id"
  task_definition = "$aws_ecs_task_definition.app.arn"
  desired_count = "$var.desired_app_count"
  deployment_minimum_healthy_percent = 50
  deployment_maximum_percent = 200
  iam_role = "arn:aws:iam::$var.account:role/ecsServiceRole"

  load_balancer 
    target_group_arn = "$aws_lb_target_group.app-alb-tg.arn"
    container_name = "$var.env-$var.subenv-$var.appname"
    container_port = 9000
  
  depends_on = [
    "aws_alb.app-alb"]


resource "aws_alb" "app-alb" 
  name = "$var.env-$var.subenv-$var.appname"
  subnets = "$var.subnet_ids"
  security_groups = [
    "$var.vpc_default_sg",
    "$aws_security_group.app_internal.id"]
  internal = false
  idle_timeout = 600
  tags 
    Owner = ""
    Env = "$var.env"
  


resource "aws_lb_listener" "app-alb-listener" 
  load_balancer_arn = "$aws_alb.app-alb.arn"
  port = "443"
  protocol = "HTTPS"
  ssl_policy = "ELBSecurityPolicy-2015-05"
  certificate_arn = "$var.certificate_arn"

  default_action 
    type = "forward"
    target_group_arn = "$aws_lb_target_group.app-alb-tg.arn"
  


resource "aws_lb_target_group" "app-alb-tg" 
  name = "$var.env-$var.subenv-$var.appname"
  port = 80
  health_check 
    path = "/actuator/health"
  
  protocol = "HTTP"
  vpc_id = "$var.vpc_id"   

【问题讨论】:

这适用还是错误?如果它没有出错,仅仅是健康检查失败了吗?看起来 AWS 在您应用它时应该在验证时失败(Terraform 这样做会很棘手,因为它不正式支持交叉参数验证)但是您不应该在不设置健康检查协议的情况下指定健康检查路径到 HTTP/HTTPS。 查看此链接 aws.amazon.com/blogs/aws/… 如果我没记错的话,您需要将“协议”从 TCP 更改为 TLS 【参考方案1】:

一个流经它的网络负载平衡器automatically performs passive health checks on non UDP traffic,所以如果这足够了,那么您可以删除活动的运行状况检查配置。

如果您想启用主动健康检查,那么您可以使用 TCP 健康检查(默认),它只会检查端口是否打开,或者您可以指定 HTTP/HTTPS 协议并指定路径。理想情况下,当您尝试为健康检查指定路径但未将协议设置为 HTTP 或 HTTPS 时,AWS API 会出错,但现在显然不是这样。

使用 Terraform,这看起来像这样:

resource "aws_lb_target_group" "app-alb-tg" 
  name     = "$var.env-$var.subenv-$var.appname"
  port     = 443
  protocol = "TCP"
  vpc_id   = "$var.vpc_id"

  health_check 
    path     = "/actuator/health"
    protocol = "HTTPS"
  

请记住,主动运行状况检查将从网络负载平衡器的角度(不仅仅是源流量)检查目标上的端口是否打开。这意味着您的目标将需要允许来自您的 NLB 所在的子网以及您的源流量源自的安全组或 CIDR 范围等的流量。

【讨论】:

当我使用 TCP aws_lb_listener 尝试此操作时,我收到此错误:“侦听器和以下目标组的协议不兼容”。 抱歉,复制粘贴了错误的目标组定义。只是对目标组上的运行状况检查协议进行了更改,因此您仍应将 TCP 流量传递到目标,但使用 HTTP 或 HTTPS 协议进行运行状况检查。 Np,我不太确定的一件事是 ssl_policy 和 certificate_arn 应该去哪里。与之前的 ALB 一样,我在 aws_lb_listener 中进行了设置。但鉴于我现在使用的是 NLB,我是否可以假设不再需要它们? 如果您在 NLB 卸载 TLS 而不是执行直通 TCP,您只需要 ssl_policycertificate_arn,这就是您的问题。如果您对该配置有特定问题,但最好创建一个单独的问题。

以上是关于如何配置 AWS 网络负载均衡器以使用 Terraform 路由 HTTPS 流量?的主要内容,如果未能解决你的问题,请参考以下文章

如何将目标(不在 AWS 上)注册到网络负载均衡器?

网络负载均衡器目标组中的 AWS Auto Scaling 目标

在 aws 负载均衡器中 sshing 并将其配置为子域路由?

如何将 AWS 应用程序负载均衡器配置为超过 25 个 SSL 证书限制

将公共静态 ipv4 地址添加到 AWS 负载均衡器

在 AWS 中,如何将 Web 服务器安全组配置为仅接受来自 AWS 中的负载均衡器的流量?