GitLab流水线中如何等待AWS ECS上的Knex.js迁移执行完成
解决GitLab流水线提前结束,等待AWS ECS迁移任务完成的方案
问题根源是aws ecs run-task属于异步调用,提交任务后会立即返回成功,不会等待任务实际执行完成,导致流水线直接推进到后续步骤。要让流水线等待迁移任务执行完毕,需要捕获任务状态并轮询直到任务结束,再根据执行结果决定是否继续。
具体实现步骤
1. 执行run-task并捕获任务ARN
修改原命令,通过--query提取任务ARN并保存到变量,后续用于查询状态:
TASK_ARN=$(aws ecs run-task --profile gitlab --cluster $SERVER_CLUSTER_ARN --task-definition $TASK_DEF_ARN --network-configuration '{"awsvpcConfiguration":{"subnets":["'$SUBNET_ID'"]}}' --launch-type FARGATE --overrides '{"containerOverrides":[{"environment":[{"name":"MONGO_DB","value":"'$MONGO_DB'"},{"name":"DB_USER","value":"'$DB_USER'"},{"name":"DB_PASS","value":"'$DB_PASS'"}],"name":"lh-server","command":["app/run-fargate-migrations.js"]}]}' --query 'tasks[0].taskArn' --output text)
2. 轮询任务状态直到结束
添加循环逻辑,定期调用describe-tasks查询任务状态,直到任务进入STOPPED状态:
# 轮询间隔(秒),可根据迁移任务耗时调整 POLL_INTERVAL=10 while true; do # 获取任务当前状态和容器退出码 TASK_STATUS=$(aws ecs describe-tasks --profile gitlab --cluster $SERVER_CLUSTER_ARN --tasks $TASK_ARN --query 'tasks[0].lastStatus' --output text) CONTAINER_EXIT_CODE=$(aws ecs describe-tasks --profile gitlab --cluster $SERVER_CLUSTER_ARN --tasks $TASK_ARN --query 'tasks[0].containers[0].exitCode' --output text) echo "当前迁移任务状态: $TASK_STATUS" if [ "$TASK_STATUS" = "STOPPED" ]; then break fi sleep $POLL_INTERVAL done
3. 根据任务结果控制流水线走向
任务停止后,检查容器退出码:退出码为0则迁移成功,继续后续步骤;非0则终止流水线并标记失败:
if [ "$CONTAINER_EXIT_CODE" -eq 0 ]; then echo "迁移任务执行成功" else echo "迁移任务执行失败,退出码: $CONTAINER_EXIT_CODE" exit 1 fi
完整GitLab流水线Job示例
将上述逻辑整合到GitLab CI配置中:
ecs-migrate: stage: migrate script: - | # 启动ECS迁移任务并获取任务ARN TASK_ARN=$(aws ecs run-task --profile gitlab --cluster $SERVER_CLUSTER_ARN --task-definition $TASK_DEF_ARN --network-configuration '{"awsvpcConfiguration":{"subnets":["'$SUBNET_ID'"]}}' --launch-type FARGATE --overrides '{"containerOverrides":[{"environment":[{"name":"MONGO_DB","value":"'$MONGO_DB'"},{"name":"DB_USER","value":"'$DB_USER'"},{"name":"DB_PASS","value":"'$DB_PASS'"}],"name":"lh-server","command":["app/run-fargate-migrations.js"]}]}' --query 'tasks[0].taskArn' --output text) # 轮询任务状态 POLL_INTERVAL=10 while true; do TASK_STATUS=$(aws ecs describe-tasks --profile gitlab --cluster $SERVER_CLUSTER_ARN --tasks $TASK_ARN --query 'tasks[0].lastStatus' --output text) CONTAINER_EXIT_CODE=$(aws ecs describe-tasks --profile gitlab --cluster $SERVER_CLUSTER_ARN --tasks $TASK_ARN --query 'tasks[0].containers[0].exitCode' --output text) echo "当前任务状态: $TASK_STATUS" if [ "$TASK_STATUS" = "STOPPED" ]; then break fi sleep $POLL_INTERVAL done # 根据结果判断是否继续流水线 if [ "$CONTAINER_EXIT_CODE" -eq 0 ]; then echo "迁移任务执行成功" else echo "迁移任务执行失败,退出码: $CONTAINER_EXIT_CODE" exit 1 fi only: - main
注意事项
- 确保GitLab Runner使用的AWS权限(或
gitlabprofile)拥有ecs:RunTask和ecs:DescribeTasks权限。 - 若迁移任务启动多个容器,需调整
--query中的容器索引(如containers[0])匹配执行迁移的容器。 - 可根据任务实际耗时调整
POLL_INTERVAL,避免不必要的频繁查询。
内容的提问来源于stack exchange,提问作者rpf
相关产品推荐
相关产品推荐

