Dockerized Lambda deployments with CloudFormation
When you deploy a Lambda using a tagged docker image, updating the tagged image and redeploying the Lambda (using CloudFormation) doesn’t actually update the code running in the Lambda. This happens because neither CloudFormation nor Lambda know that the tag now points somewhere else.
The solution is actually pretty simple: instead of referring to the docker image by its tag, refer to it by its digest instead.
Old way, using a tag:
# Part of a CloudFormation template in yaml format:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
PackageType: Image
Timeout: 120
MemorySize: 512
Code:
ImageUri: !Sub ${DockerRegistry}/image-name@latest
New way, using a digest:
# Part of a CloudFormation template in yaml format:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
PackageType: Image
Timeout: 120
MemorySize: 512
Code:
# Reference the digest (sha hash) instead of tag here, since Lambda won't pick up the new image if we just re-tag it.
# Doing it this way ensure lambda pulls the new image.
ImageUri: !Sub ${DockerRegistry}/image-name@${LambdaDockerDigest}
The digest comes into the template as a parameter (LambdaDockerDigest), which ultimately comes from my build step and looks something like sha256:94a00394bc5a8ef503fb59db0a7d0ae9e1110866e8aee8ba40cd864cea69ea1a.
In hindsight, using the sha is probably better anyway: it’s the most unambiguous and immutable way of referring to a given image version.