You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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 }}

关键说明

  1. 整合循环逻辑:将版本递减、任务定义检查、镜像检查全部放到单个Shell脚本步骤中,通过while循环实现迭代查找
  2. 防无限循环:设置MIN_REVISION环境变量,限制最低检查版本,避免脚本无限循环
  3. 提前终止循环:一旦找到同时满足「任务定义存在」和「镜像存在」的版本,立即设置环境变量并退出循环,进入回滚步骤
  4. 错误处理:如果遍历到最低版本仍未找到有效版本,脚本返回非零值,终止工作流(可根据需求添加告警逻辑)

内容的提问来源于stack exchange,提问作者rmznbyk 1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:10:26