'AWS Cloudformation | Configure Lambda to Use Latest Version of Code in S3 Bucket

Im using codepipeline, codebuild and cloudformation on AWS.

My flow is:

  1. Push a commit to github, this triggers the codepipeline
  2. Codebuild uploads (zipped) lambda functions to S3 bucket
  3. Cloudformation configure lambda functions

Cloudformation (simplified):

CreateDoctorLambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.6
      Handler: lambda_function.lambda_handler
      Role:
        Fn::GetAtt:
          - LambdaExecutionRole
          - Arn
      Code:
          S3Bucket: !Ref LambdaFunctionS3Bucket
          S3Key: CreateDoctor.zip
          S3ObjectVersion: Latest <-- This value is invalid

Problem: When I update the code for lambda functions (this new code is zipped and uploaded to the S3 bucket during codebuild), the change is not deployed to the existing lambda functions.

According to AWS documentation:

To update a Lambda function whose source code is in an Amazon S3 bucket, you must trigger an update by updating the S3Bucket, S3Key, or S3ObjectVersion property. Updating the source code alone doesn't update the function.

Question: Is there any way to tell Cloudformation to use the latest version of the code stored in S3? Using S3ObjectVersion: Latest will result in an error.



Solution 1:[1]

A quick hack that works well if you have a lot of lambdas in your CF stack so you want to manually select which lambdas to update from the source, and have lambda code that will work equally well under multiple runtimes. Just change the runtime version in your stack (say from "Runtime: nodejs8.10" to "Runtime: nodejs10.x". CodePipeline/CloudFormation will update just that function.

Solution 2:[2]

S3ObjectVersion could be extracted into Parameters section and the latest version could be passed to it dynamically.

Below is org-babel version but it can be converted into shell script instead.

#+name: latest-lambda-version
#+BEGIN_SRC sh :results output :var bucket=artifact-bucket-name
aws s3api list-object-versions --bucket $bucket --prefix lambda-function.zip --query 'Versions[?IsLatest].[VersionId]' --output text
#+END_SRC


#+BEGIN_SRC sh :results verbatim silent :var version=latest-lambda-version
aws cloudformation deploy --template-file stack.yml \
                          --stack-name FooStack \
                          --capabilities CAPABILITY_IAM \
                          --parameter-overrides LambdaVersion="${version}" \
                          --no-execute-changeset
#+END_SRC

Solution 3:[3]

My requirement was also similar but I didn't use aws-cloudformation. I have configured AWS pipeline to deploy my latest nodeJS code as zip file to S3. Instead of going to AWS Lambda and manually choosing the "upload from Amazon S3 location" option, I needed my lambda function to take the latest code once it is written to S3, so that it will automatically update its function code when you update the zip file in S3 through AWS pipeline.

Solution that worked for me is in this link:- https://stackoverflow.com/a/71079021/10049471

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Robin Melhuish
Solution 2 Nikita Fedyashev
Solution 3 Rahith RR