【问题标题】:How to keep the last X ECS task definitions active?如何保持最后 X 个 ECS 任务定义处于活动状态?
【发布时间】:2018-08-30 19:51:08
【问题描述】:

我有以下 Terraform 代码来更新具有新任务定义的服务:

resource "aws_ecs_task_definition" "app_definition" {
  family = "my-family"

  container_definitions = "${data.template_file.task_definition.rendered}"
  network_mode          = "bridge"
}

resource "aws_ecs_service" "app_service" {
  name            = "my-service"
  cluster         = "my-cluster"
  task_definition = "${aws_ecs_task_definition.app_definition.arn}"
  desired_count   = "1"
  iam_role        = "my-iam-role"
}

更新我的服务时,我的任务定义的最新版本变为非活动状态。结果,在ECS控制台中尝试手动回滚到以前的版本时,我无法选择它:

Error: No active task definition found

理想情况下,我希望保持最后 X 个修订版本处于活动状态,以便在出现问题时始终通过控制台手动回滚。

我怎样才能做到这一点?

【问题讨论】:

    标签: amazon-web-services terraform amazon-ecs


    【解决方案1】:

    Terraform 目前不允许这样做,它的资源生命周期模型意味着当您替换某些东西(任务定义是不可变的)时,Terraform 必须创建一个新的并销毁旧的。

    使用 ECS 任务定义也不能真正被销毁,而是被标记为非活动状态,因为当前部署的任务可能正在使用它,直到它们被服务更新为新的任务定义。

    有 2 种常用方法来处理此问题,并且需要能够回滚到任务定义的先前版本。

    首先,在初始创建之外不使用 Terraform 来管理任务定义,而是使用 AWS ECS CLI 工具之类的工具来执行此操作。

    另一个选项,也是我使用的选项,是让我的 CI(在我们的例子中是 Gitlab CI)生成一个 Docker 映像,标记有要部署的应用程序的提交 SHA,然后 Terraform 将任务定义更新为apply 上的新提交 SHA 标记图像以及使用新任务定义 ARN 更新 ECS 服务。

    当我们想要回滚时,我们使用 CI 的能力回滚到不同的提交,仅使用旧提交 SHA 启动部署作业,然后部署旧映像。

    这使 Terraform 对正在部署的内容完全不可知,并使 CI 系统负责部署所需的版本,该版本通常是最新的,但如果我们手动单击部署,则有时是特定的提交,当然回滚时目标是以前的版本.

    这确实意味着您无法通过 AWS 控制台启动回滚,但我实际上很喜欢这样,因为我希望 CI 系统成为随时部署内容的真实来源。

    【讨论】:

      【解决方案2】:

      一个非常简单的方法是挂钩到 Terraform 的生命周期:

      resource "aws_ecs_task_definition" "app_definition" {
        family = "my-family"
      
        container_definitions = "${data.template_file.task_definition.rendered}"
        network_mode          = "bridge"
      
        # make sure Terraform does not unregister the task definition
        lifecycle {
          prevent_destroy = true
        }
      }
      

      As discussed in this Pull Request 它可以防止旧任务定义的破坏,从而保持所有任务定义处于活动状态。

      【讨论】:

      • 你自己试过了吗?它不起作用:* aws_ecs_task_definition.mydef: aws_ecs_task_definition.mydef: the plan would destroy this resource, but it currently has lifecycle.prevent_destroy set to true. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or adjust the scope of the plan using the -target flag.
      • @red888 我发现这个解决方案有效,但并非总是如此 - 一开始我运行时没有任何问题。在某些时候,我遇到了同样的错误。我很好奇是什么原因造成的!
      猜你喜欢
      • 1970-01-01
      • 2022-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      相关资源
      最近更新 更多