【问题标题】:Redeploy Terraform aws_instance nodes consecutively, not in parallel连续重新部署 Terraform aws_instance 节点,而不是并行
【发布时间】:2019-10-10 18:21:59
【问题描述】:

我有几个 aws_instance 节点位于 Terraform 的负载均衡器目标组中。我做了一个更改,需要销毁每个实例并重新创建它。默认情况下,Terraform 将同时销毁和重新创建所有这些实例。一次销毁所有这些是不好的,因为负载均衡器中不会有任何节点。

有没有办法配置 Terraform,使其在销毁/创建其他实例之前等待一个实例完全销毁/重新创建?

【问题讨论】:

  • 您只有直接实例(使用aws_instance 资源)还是使用自动缩放组?即使您不需要能够实际自动缩放(将最小值和最大值设置为相同和/或没有自动缩放策略),使用 ASG 也更容易实现这一点。
  • 使用 aws_instance 资源的实例,尽管我可能会在下面遵循您的建议。

标签: amazon-ec2 terraform terraform-provider-aws


【解决方案1】:

您可以使用create_before_destroy lifecycle customisation 强制 Terraform 在替换操作期间销毁旧资源之前创建新资源。

不幸的是,如果您的实例需要一段时间才能启动所需的服务,那么您仍然会遇到问题,因为一旦 AWS API 返回实例正在运行,Terraform 就会认为它已完成并开始终止它要替换的旧实例。

您可以通过将实例放在自动缩放组中来解决此问题(即使您不需要它们自动缩放,因此具有相同的最小和最大大小或不将自动缩放策略附加到组)并设置 health_check_typeELB。这将确保实例在通过负载均衡器健康检查而不是默认的 EC2 健康检查(即如果它正在运行并且没有系统或实例状态检查失败)之前不会被认为是健康的。这样,Terraform 将等到新的 ASG 有最少数量的实例通过负载均衡器运行状况检查(并附加到相关的目标组或 ELB),然后才会认为它已完成,然后开始删除旧的 ASG。

【讨论】:

    【解决方案2】:

    depends_on 属性允许设置显式依赖项并按顺序创建事物。它对您的方案是有限的,因为它不会等待新实例“准备好”,而是刚刚创建。

    我在阅读您的场景时有一个想法,您可以使用 extermal 数据源。不肯定它是为这种事情设计的,但我认为它可以工作。本质上,您可以编写一个脚本,该脚本将使用 AWS CLI 以及查看实例是否已创建并准备就绪所需的任何其他内容。如果你使用 depends_on 或者将 external 数据源的输出链接到下一个实例(使用输出设置标签?),我认为它会达到你想要的效果。

    不过,这个设计对我来说有点味道。还有其他 AWS 服务和功能可以为您做这种事情,例如带有负载均衡器运行状况检查的 ECS 滚动部署。

    资源:

    https://www.terraform.io/docs/providers/external/data_source.html

    https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-create-loadbalancer-rolling.html

    编辑:

    如果您被 EC2 实例困扰,另一种解决此问题的原生 AWS 方法可能是使用生命周期挂钩。我已将 EC2 用户数据脚本与调用 Lambda 函数的生命周期挂钩结合使用,以进行自定义 Kafka 集群的滚动部署和配置(在 MSK 之前)。这要求我按顺序启动实例并为每个实例分配一个唯一的代理 ID。听起来与您的场景相似。

    资源: https://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html

    【讨论】:

    • 谢谢。滚动部署不是问题,我为此使用 CodeDeploy。问题是当我需要替换目标组中的实例而不是仅仅向它们部署新软件时。
    猜你喜欢
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2021-07-16
    • 2019-11-16
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    相关资源
    最近更新 更多