如何用envsubst修改ECS任务定义镜像标签实现Fargate自动化部署
解决BitBucket Pipelines部署ECS Fargate时镜像标签固定为latest的问题
问题背景
通过BitBucket Pipelines部署ECS Fargate集群,Docker镜像存储在ECR中,每次部署用$BITBUCKET_BUILD_NUMBER打标签推送到ECR,但ECS任务定义JSON里的镜像标签固定为latest,导致Fargate无法拉取正确版本的镜像。
解决方案
方法一:使用envsubst替换标签(推荐,适合提前定义占位符)
修改原始任务定义的镜像字段
将任务定义里的镜像行改成带变量占位符的格式:"image": "$AWS_REGISTRY/$DOCKER_IMAGE:$BITBUCKET_BUILD_NUMBER",其中
$AWS_REGISTRY和$DOCKER_IMAGE是你流水线中已定义的环境变量,$BITBUCKET_BUILD_NUMBER是BitBucket内置的构建号变量。更新部署流水线配置
在部署阶段添加envsubst命令,生成替换变量后的临时任务定义文件,再用这个文件部署:name: Deploy to Fargate script: # 生成替换变量后的任务定义文件 - envsubst < $TASK_DEFINITION > updated-task-definition.json # 使用更新后的任务定义部署 - pipe: atlassian/aws-ecs-deploy:1.6.2 variables: CLUSTER_NAME: $CLUSTER_NAME SERVICE_NAME: $SERVICE_NAME TASK_DEFINITION: updated-task-definition.json FORCE_NEW_DEPLOYMENT: 'true' DEBUG: 'true'
方法二:使用jq直接修改JSON(适合不想改动原始任务定义的场景)
jq是专门处理JSON的工具,BitBucket Pipelines环境默认已安装,可以直接用它替换镜像标签:
更新部署流水线配置如下:
name: Deploy to Fargate script: # 下载当前任务定义到本地文件 - aws ecs describe-task-definition --task-definition $TASK_DEFINITION > task-def.json # 使用jq替换image字段中的latest为构建号 - jq --arg tag "$BITBUCKET_BUILD_NUMBER" ' .taskDefinition.containerDefinitions[0].image |= sub(":latest$"; ":" + $tag) ' task-def.json > updated-task-def.json # 注册修改后的任务定义,获取新的任务定义ARN - NEW_TASK_DEF=$(aws ecs register-task-definition --cli-input-json file://updated-task-def.json | jq -r '.taskDefinition.taskDefinitionArn') # 使用新的任务定义部署 - pipe: atlassian/aws-ecs-deploy:1.6.2 variables: CLUSTER_NAME: $CLUSTER_NAME SERVICE_NAME: $SERVICE_NAME TASK_DEFINITION: $NEW_TASK_DEF FORCE_NEW_DEPLOYMENT: 'true' DEBUG: 'true'
说明:
- 如果你的任务定义中有多个容器,需要调整
.containerDefinitions[0]的索引,或者用条件匹配容器名称(比如select(.name == "your-container-name"))。 sub(":latest$"; ":" + $tag)是正则替换,确保只替换末尾的latest标签。
内容的提问来源于stack exchange,提问作者Dave Michaels
相关产品推荐
相关产品推荐

