How to have AWS Lambda update to latest container automatically
AWS Lambda does not have the option to run on the “latest” container image, so how does Narratrail do it?
When you set up AWS Lambda container runtime with the container image tagged “latest” you might think that if you upload a new image that Lambda would automatically choose it next time it starts. Unfortunately it does not.
But fear not, you can easily make your lambda update itself. This is what I do with Narratrail, on start-up it compares the currently configured image digest to the currently image tagged “latest” in the repository.
def update_lambda():
lambda_client = boto3.client("lambda")
res = lambda_client.get_function(FunctionName="my-function")
current_image = res["Code"]["ResolvedImageUri"].split("@")[1]
logging.debug("current image: %s", current_image)
ecr_client = boto3.client('ecr')
images = ecr_client.describe_images(registryId="123456789123", repositoryName="my-repo-name")
for i in images["imageDetails"]:
if "latest" in i.get("imageTags", []):
latest = i
break
if current_image == latest["imageDigest"]:
logging.debug("running latest image")
return
lambda_client.update_function_code(
FunctionName='my-function',
ImageUri="123456789123.dkr.ecr.{}.amazonaws.com/narratrail-test@{}".format(os.getenv("AWS_REGION"), latest["imageDigest"]),
)
logging.info("updated lambda")
Required IAM actions
The lambda execution role needs access to a few APIs for this to work.
- PolicyName: lambda-self-update
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- lambda:GetFunction
- lambda:UpdateFunctionCode
Resource: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:my-function'
- Effect: Allow
Action:
- ecr:DescribeImages
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
Resource: arn:aws:ecr:*:123456789123:repository/my-repo-name
Multiple Regions
Currently, at least https://github.com/aws/containers-roadmap/issues/1281, the ECR must be in the same region as the lambda. Because Narratrail might be deployed to any region, a registry in each region is needed. ECR has a feature to replicate images from one region to another but currently at least I handle this by explicitly pushing to each registry.