【问题标题】:Failing to associate load balancer with target group无法将负载均衡器与目标组关联
【发布时间】:2021-05-08 12:40:18
【问题描述】:

我正在使用 Terraform 部署我的基础架构,但一直遇到以下错误:

Error: InvalidParameterException: The target group with targetGroupArn [snip] does
not have an associated load balancer.

another question here on SO where the poster is running into a similar problem。答案之一引用了 AWS 文档:

Amazon ECS 服务需要显式依赖 Application Load Balancer 侦听器规则和 Application Load 平衡器监听器。这可以防止服务在 监听器已准备就绪。

这基本上是说我应该在我的服务之前创建我的监听器和监听器规则。但是,在我的侦听器中,我将服务的目标组指定为默认操作:

resource "aws_alb_listener" "app_http" {
  load_balancer_arn = module.alb_app.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    target_group_arn = module.app_service.lb_target_group.id
    type             = "forward"
  }
}

所以,如果应该在我的服务和目标组之前创建侦听器,我对如何在侦听器上设置 target_group_arn 感到困惑。

这就是我创建服务及其相应目标组的方式:

resource "aws_ecs_service" "service" {
  ...

  load_balancer {
    target_group_arn = aws_alb_target_group.service.arn
  }
}

resource "aws_alb_target_group" "service" {
  ...

  port        = 8080
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "ip"
}

【问题讨论】:

  • 为什么要在模块外创建目标组?您是否尝试在模块中移动它?另外,检查 module.app_service.lb_target_group.id 是否真的给了你 arn 而不是别的东西

标签: amazon-web-services terraform amazon-ecs terraform-provider-aws aws-load-balancer


【解决方案1】:

您的aws_alb_target_group 应该依赖于您的负载均衡器,因为两者之间没有直接引用:

resource "aws_alb_target_group" "service" {
  ...

  port        = 8080
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "ip"

  depends_on = [aws_alb.ecs-load-balancer]

}

aws_alb.ecs-load-balancer 应替换为您的负载平衡器资源。

【讨论】:

  • 嗯。好的。所以我尝试了,但不幸的是,我似乎仍然遇到同样的错误......在 Terraform 输出中,我可以看到它正在尝试创建 ECS 服务,但 2 分钟后它会出现此错误超时。当我检查 AWS 控制台时,我可以看到负载均衡器已创建。看ECS,我的应用服务还没有创建... :(
  • @Luke 该问题存在 github 问题。你能试试那里提出的解决方案之一吗,比如this one
【解决方案2】:

正如linked answer 建议的那样,您需要设置对负载均衡器侦听器的依赖。

使用您当前的代码,Terraform 将看到一个如下所示的依赖链(在 sn-p 上运行以查看依赖图):

mermaid.initialize({startOnLoad:true});
<script src="https://unpkg.com/mermaid@8.0.0/dist/mermaid.min.js"></script>

<div class="mermaid">
graph TD
    A[aws_alb_listener.app_http] --> B[module.alb_app.arn]
    A[aws_alb_listener.app_http] --> C[module.app_service.lb_target_group.id]
    D[aws_ecs_service.service] --> C*[aws_alb_target_group.service.arn]

</div>

您的错误是抱怨当它尝试创建/更新服务以使用目标组时,目标组尚未附加到负载均衡器,因为目标组尚未附加到侦听器规则或侦听器规则尚未附加到负载均衡器(这很可能是因为 ALB 创建比目标组创建慢得多,并且侦听器需要等待 ALB 和目标组创建后才能创建)。

通常,您可以通过告诉aws_ecs_service 资源它还必须依赖于侦听器或侦听器规则创建才能完成使用depends_on meta argument 来解决此问题,如下所示:

resource "aws_ecs_service" "service" {
  ...

  load_balancer {
    target_group_arn = aws_alb_target_group.service.arn
  }

  # We need to wait until the target group is attached to the listener
  # and also the load balancer so we wait until the listener creation
  # is complete first
  depends_on = [aws_alb_listener.app_http]
}

使用更简单的非模块布局,看起来像这样:

mermaid.initialize({startOnLoad:true});
<script src="https://unpkg.com/mermaid@8.0.0/dist/mermaid.min.js"></script>

<div class="mermaid">
graph TD
    A[aws_alb_listener.app_http] --> B[aws_alb.app.arn]
    A[aws_alb_listener.app_http] --> C[aws_alb_target_group.service.arn]
    D[aws_ecs_service.service] --> C[aws_alb_target_group.service.arn]
    D[aws_ecs_service.service] -->|depends_on| A[aws_alb_listener.app_http]

</div>

看起来你有一个过于复杂的模块布局,我可能会建议你反对,而且很难准确地告诉你提供的不完整代码的地址是什么,但如果监听器在一个模块中调用app_lb_listener,那么你会想要依赖module.app_lb_listener.aws_alb_listener.app_http

【讨论】:

  • 复杂的模块布局是因为我的登台和生产环境都有不同的监听器。看来我必须恢复到 Terraform count(条件资源策略)才能完成这项工作......
  • 它仍然可以使用您的模块布局(我认为,如果没有包括您的所有代码作为minimal reproducible example 的问题,很难判断),如上一段中提到的,但在我看来它确实是过于复杂,你可以通过扁平化你的模块来简化很多,除非有充分的理由让模块嵌套如此复杂。
猜你喜欢
  • 2019-05-27
  • 2021-09-08
  • 2020-07-24
  • 1970-01-01
  • 2021-05-19
  • 2017-11-07
  • 1970-01-01
  • 2013-08-26
  • 2021-12-07
相关资源
最近更新 更多