AWS Lambda(Image包类型)执行sam deploy后无法自动更新至latest镜像
解决AWS SAM部署Image类型Lambda不自动更新的问题
问题原因
CloudFormation(SAM基于CloudFormation)判断资源是否需要更新时,会严格对比模板中定义的属性值。你的Lambda使用latest标签作为镜像URI的一部分,尽管你推送了新镜像,但标签字符串本身没有变化,CloudFormation会认为ImageUri属性未修改,因此不会触发Lambda函数的更新。而手动调用aws lambda update-function-code或控制台操作时,是主动触发Lambda拉取对应标签的最新镜像,所以能生效。
解决方案
方案1:使用镜像SHA256摘要替代latest标签
每次推送新镜像后,镜像的SHA256摘要会唯一变化,CloudFormation能通过检测这个变化来触发Lambda更新。
- 修改SAM模板,将
ImageUri改为使用参数传入镜像摘要:
Parameters: LambdaImageDigest: Type: String Description: ECR镜像的SHA256摘要(格式如sha256:xxxxxxxx...) Resources: MyLambda: Type: AWS::Serverless::Function Properties: Role: foobar-lambda-role PackageType: Image ImageUri: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/foobar@${LambdaImageDigest}
- 在BitBucket CI流程中,推送镜像后获取摘要并传入
sam deploy:
# 推送镜像到ECR后,获取latest标签对应的镜像摘要 IMAGE_DIGEST=$(aws ecr describe-images --repository-name foobar --image-ids imageTag=latest --query 'imageDetails[0].imageDigest' --output text) # 执行SAM部署,传入镜像摘要参数 sam deploy --parameter-overrides LambdaImageDigest=$IMAGE_DIGEST
这个方案能确保部署的镜像版本完全匹配,避免标签被覆盖导致的版本混乱,是最可靠的方式。
方案2:添加动态属性触发资源更新
通过在Lambda属性中添加一个随每次部署变化的字段(如描述信息),强制CloudFormation更新Lambda资源,从而拉取最新的latest标签镜像。
- 修改SAM模板,增加
BuildTimestamp参数并用于Lambda的描述:
Parameters: BuildTimestamp: Type: String Default: '1970-01-01T00:00:00' Resources: MyLambda: Type: AWS::Serverless::Function Properties: Role: foobar-lambda-role PackageType: Image ImageUri: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/foobar:latest Description: !Sub "Lambda函数构建于 ${BuildTimestamp}"
- 在CI流程中部署时传入当前时间戳:
sam deploy --parameter-overrides BuildTimestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
每次部署时BuildTimestamp都会变化,CloudFormation会更新Lambda的描述属性,同时触发Lambda重新拉取latest标签的镜像。
内容的提问来源于stack exchange,提问作者Ian Liu Rodrigues
相关产品推荐
相关产品推荐

