我具有以下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版本有效,以便在出现问题时始终可以通过控制台手动回滚。
我该如何实现?
答案 0 :(得分:4)
Terraform当前不允许这样做,它的资源生命周期模型意味着当您替换某些东西(任务定义是不可变的)时,Terraform必须创建一个新的并且销毁旧的。
使用ECS任务定义也不能真正销毁,而是只是标记为未激活,因为当前可能部署了正在使用它的任务,直到服务将其更新为新的任务定义为止。
有两种常见的处理方式,并且需要能够回滚到任务定义的先前版本。
首先是根本不使用Terraform来管理任务定义,而不仅仅是使用初始创建,而是使用AWS ECS CLI工具之类的工具来代替。
另一个选择,也是我使用的一个选择,是让我的CI(在我们的例子中为Gitlab CI)生成一个带有要部署的应用程序的提交SHA标签的Docker映像,然后Terraform将任务定义更新为apply
上的新提交SHA标记图像,以及使用新任务定义ARN更新ECS服务。
当我们想回滚时,我们使用CI的能力回滚到另一个提交,仅使用旧的提交SHA启动部署作业,然后部署旧的映像。
这使Terraform完全不了解正在部署的内容,并且使CI系统负责部署所需的版本,该版本通常是最新版本,但如果我们手动单击以进行部署,并且回滚时当然是目标先前版本,则有时是特定提交
这确实意味着您无法通过AWS控制台启动回滚,但是我实际上很喜欢这样做,因为我希望CI系统成为随时部署的事实的真相。
答案 1 :(得分:-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可以防止破坏旧的任务定义,从而使所有任务定义保持活动状态。