使用Terraform更新蓝绿部署ECS时,如何正确更新任务定义?
解决ECS服务结合CodeDeploy蓝绿部署时Terraform更新任务定义的报错问题
核心原因
当ECS服务配置了CODE_DEPLOY部署控制器时,AWS会限制直接通过ECS API更新服务的任务定义——这类服务的部署流程必须由CodeDeploy发起,而非Terraform直接调用ECS服务更新接口。
正确解决方案
1. 拆分任务定义与ECS服务的Terraform配置
- 单独维护任务定义资源,让Terraform仅负责生成新的任务定义版本,不直接将新版本ARN绑定到ECS服务的
task_definition参数:resource "aws_ecs_task_definition" "app" { family = "my-app" container_definitions = file("container-definitions.json") # 其余任务定义配置... } - ECS服务的
task_definition参数固定为初始ARN(或留空由CodeDeploy管理),避免Terraform自动触发服务更新。
2. 用Terraform触发CodeDeploy部署
通过aws_codedeploy_deployment资源,在任务定义更新时自动触发蓝绿部署:
resource "aws_codedeploy_deployment" "ecs_deployment" { depends_on = [aws_ecs_task_definition.app] application_name = aws_codedeploy_app.ecs_app.name deployment_group_name = aws_codedeploy_deployment_group.ecs_deployment_group.name deployment_config_name = "CodeDeployDefault.ECSBlueGreen" # 匹配蓝绿部署的配置 revision { revision_type = "ECS_TASK_DEFINITION" ecs_task_definition { task_definition_arn = aws_ecs_task_definition.app.arn platform_version = aws_ecs_task_definition.app.platform_version } } }
这样每次任务定义更新后,Terraform会自动调用CodeDeploy发起部署,完全符合AWS的规则。
3. 阻止Terraform自动更新ECS服务的任务定义
在ECS服务资源中添加生命周期规则,忽略task_definition的变更,避免Terraform尝试直接更新服务:
resource "aws_ecs_service" "app" { name = "my-app-service" cluster = aws_ecs_cluster.app.id deployment_controller { type = "CODE_DEPLOY" } # 其余服务配置... lifecycle { ignore_changes = [task_definition] } }
额外注意事项
- 确保CodeDeploy部署组已正确关联ECS服务、负载均衡器,且IAM角色具备ECS和CodeDeploy的完整操作权限。
- 若需更新ECS服务的其他配置(如自动扩缩容规则),可直接修改Terraform配置,部分配置变更需配合CodeDeploy部署生效。
内容的提问来源于stack exchange,提问作者Gergő Horváth
相关产品推荐
相关产品推荐

