AWS EventBridge推送MR镜像时未向Uffizzi发送image_push事件
ECR对接Uffizzi预览环境MR流水线事件不触发问题处理
前置配置现状
已按照Uffizzi官方集成文档完成全链路基础配置:
- 完成对接所需IAM用户、权限配置
- 完成AWS EventBridge事件规则配置
- 完成自有ECR镜像仓库与Uffizzi平台的绑定
当前GitLab CI中MR场景的镜像推送阶段配置如下:
push_preview_container: <<: *on_project_runner <<: *with_docker_service <<: *with_docker_compose variables: GIT_STRATEGY: none APP_IMAGE: $PROJECT_ECR_URL VERSION: $CI_COMMIT_SHA MR_IID: $CI_MERGE_REQUEST_IID stage: push_preview_container image: $TOOLBOX_IMAGE only: - merge_requests script: - ecs_helper ecr_login - docker pull "${APP_IMAGE}:${VERSION}" - docker tag "${APP_IMAGE}:${VERSION}" "${APP_IMAGE}:uffizzi_request_${MR_IID}" - docker push "${APP_IMAGE}:uffizzi_request_${MR_IID}"
故障表现
普通分支触发CI/CD流水线时,镜像推送完成后EventBridge可正常向Uffizzi投递image_pushed事件,流程无异常;但MR触发流水线时出现异常:
push_preview_container阶段执行成功,无报错- ECR仓库内可正常看到带
:uffizzi_request_${MR_IID}标签的对应镜像,标签名符合预期 - 该次操作未触发EventBridge配置的
image_pushed规则,Uffizzi侧未收到任何对应事件,预览环境无法自动创建
根因定位
这个是ECR事件机制和docker push逻辑叠出来的典型坑,实际对接中高频出现:
- 普通分支流水线推的是刚构建完的新镜像,digest从来没在ECR里存在过,docker push会完整走镜像层、manifest上传流程,ECR收到PutImage请求后就会正常发
image_pushed事件,所以基础链路是通的 - MR流水线的逻辑是拉取ECR里已经存在的、对应COMMIT SHA版本的镜像,打Uffizzi要求的预览标签再推回同个仓库。这时候所有镜像层甚至manifest本身都已经在ECR里存着了,部分docker版本检测到目标标签对应的digest和远端完全一致时,会直接返回
Everything up-to-date,根本不会发PutImage请求到ECR;就算实际发起了PutImage请求,如果只是给已有镜像加新标签、digest没有任何变化,部分区域的ECR会默认过滤这类事件,不会投递到EventBridge - 还有个高频配置错误:如果EventBridge规则里加了
image-digest变更、或者推送发起者身份的过滤条件,也会把这种仅新增标签的推送场景拦下来,根本触发不了规则
修复方案
方案1:调整CI推送逻辑(推荐,兼容性最好)
修改MR阶段的docker推送逻辑,避免docker跳过PutImage调用,强制ECR识别到推送动作:
将原脚本中的pull、tag、push部分替换为以下内容:
ecs_helper ecr_login docker pull "${APP_IMAGE}:${VERSION}" # 先清理本地可能存在的同名标签缓存,避免docker判定为本地已存在直接跳过推送 docker rmi -f "${APP_IMAGE}:uffizzi_request_${MR_IID}" || true docker tag "${APP_IMAGE}:${VERSION}" "${APP_IMAGE}:uffizzi_request_${MR_IID}" # 关闭内容信任校验,强制发起PutImage请求 docker push --disable-content-trust "${APP_IMAGE}:uffizzi_request_${MR_IID}"
如果调整后还是不触发,可以给镜像加一个仅用于触发事件的自定义label,强制生成新的manifest(不会额外增加镜像体积):
docker tag "${APP_IMAGE}:${VERSION}" "${APP_IMAGE}:uffizzi_request_${MR_IID}" docker label --set "uffizzi.preview.mr=${MR_IID}" "${APP_IMAGE}:uffizzi_request_${MR_IID}" docker push "${APP_IMAGE}:uffizzi_request_${MR_IID}"
方案2:修正EventBridge规则配置
检查EventBridge规则的事件模式,移除不必要的过滤条件,保证能匹配到标签前缀为uffizzi_request_的所有推送事件,最小可用的事件模式配置参考:
{ "source": ["aws.ecr"], "detail-type": ["ECR Image Action"], "detail": { "action-type": ["PUSH"], "result": ["SUCCESS"], "repository-name": ["替换为你的ECR仓库名"], "image-tags": [{"prefix": "uffizzi_request_"}] } }
注意:不要添加initiator、image-digest相关的过滤条件,避免同digest新增标签的场景被规则过滤。
方案3:兜底触发(可选)
如果以上方案都不生效,可以在push命令执行完成后直接调用Uffizzi的开放API手动触发预览环境部署,直接绕开EventBridge事件链路。
验证步骤
- 修改配置后重新提交MR触发流水线
- 推送完成后在EventBridge控制台查看规则的监控指标,确认对应时间点有成功调用记录
- 检查Uffizzi侧是否收到事件、正常创建预览环境
内容的提问来源于stack exchange,提问作者Nikolay Ryabov
相关产品推荐
相关产品推荐

