如何通过GitHub Action实现ECS任务的自动回滚策略?
GitHub Action实现ECS任务回滚的循环查找策略
需求背景
- 回滚ECS任务时,若上一个任务定义对应的镜像在ECR中不存在,自动递减版本号,继续检查更早的任务定义镜像,直到找到有效镜像
- 若上一个任务定义版本本身不存在,同样递减版本号查找,直到找到有效的任务定义版本
当前问题
现有GitHub Action工作流中,id:tag-checker步骤检测到镜像不存在时,无法重复执行从id:previous-revision-image-tag开始的后续步骤,需要实现循环查找逻辑。
解决方案
GitHub Action没有原生的步骤循环功能,我们可以将整个查找逻辑整合到一个Shell脚本中,通过脚本内部的循环来实现版本递减检查,替代原来分散的多个步骤。以下是修改后的完整工作流:
name: "AWS Rollback" on: workflow_dispatch: env: AWS_REGION: "region" ECR_REPOSITORY: "nodejs-1" ECS_SERVICE: "nodejs-service" ECS_CLUSTER: "test-1" ECS_TASK_DEFINITION: ".aws/staging.paris.json" CONTAINER_NAME: "nodejs-test" MIN_REVISION: 1 # 设置最低检查版本,防止无限循环 jobs: Rollback: name: "Rollback" runs-on: ubuntu-latest environment: production steps: - name: 配置AWS凭证 uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - name: 登录Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: 获取当前任务版本信息 id: current-revision run: | # 获取当前运行的任务定义完整ARN,拆分出版本名和版本号 TASK_DEF_ARN=$(aws ecs describe-services --cluster ${{ env.ECS_CLUSTER }} --query "services[].taskDefinition" --services ${{ env.ECS_SERVICE }} --output text) echo "REVISION_NAME=$(echo $TASK_DEF_ARN | cut -d: -f1-6)" >> $GITHUB_ENV echo "REVISION_NUMBER=$(echo $TASK_DEF_ARN | cut -d: -f7)" >> $GITHUB_ENV - name: 循环查找有效回滚版本 id: find-valid-revision run: | CURRENT_REV=${{ env.REVISION_NUMBER }} MIN_REV=${{ env.MIN_REVISION }} while [ $CURRENT_REV -ge $MIN_REV ]; do # 递减版本号 TARGET_REV=$((CURRENT_REV - 1)) # 检查任务定义是否存在 if aws ecs describe-task-definition --task-definition "${{ env.ECR_REPOSITORY }}:$TARGET_REV" &> /dev/null; then echo "找到任务定义版本: $TARGET_REV" # 获取该任务定义对应的镜像标签 IMAGE_TAG=$(aws ecs describe-task-definition --task-definition "${{ env.ECR_REPOSITORY }}:$TARGET_REV" --query "taskDefinition.containerDefinitions[0].image" --output text | cut -d: -f2) # 检查镜像是否存在于ECR if aws ecr describe-images --repository-name=${{ env.ECR_REPOSITORY }} --image-ids=imageTag=$IMAGE_TAG &> /dev/null; then echo "找到有效镜像,回滚版本确定为: $TARGET_REV" echo "VALID_REVISION=$TARGET_REV" >> $GITHUB_ENV exit 0 else echo "版本 $TARGET_REV 的镜像不存在,继续查找更早版本..." fi else echo "任务定义版本 $TARGET_REV 不存在,继续查找更早版本..." fi CURRENT_REV=$TARGET_REV done echo "已检查到最低版本 $MIN_REV,未找到有效回滚版本" exit 1 - name: 执行回滚操作 id: rollback run: | aws ecs update-service \ --cluster ${{ env.ECS_CLUSTER }} \ --service ${{ env.ECS_SERVICE }} \ --task-definition ${{ env.REVISION_NAME }}:${{ env.VALID_REVISION }}
关键说明
- 整合循环逻辑:将版本递减、任务定义检查、镜像检查全部放到单个Shell脚本步骤中,通过
while循环实现迭代查找 - 防无限循环:设置
MIN_REVISION环境变量,限制最低检查版本,避免脚本无限循环 - 提前终止循环:一旦找到同时满足「任务定义存在」和「镜像存在」的版本,立即设置环境变量并退出循环,进入回滚步骤
- 错误处理:如果遍历到最低版本仍未找到有效版本,脚本返回非零值,终止工作流(可根据需求添加告警逻辑)
内容的提问来源于stack exchange,提问作者rmznbyk 1
相关产品推荐
相关产品推荐

