7

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.

Vingtoft
  • 13,368
  • 23
  • 86
  • 135

4 Answers4

4

Its just an alternative workflow, but maybe it will solve your problem:

  1. Instead of saving the artifact with the same name, you must configure CodePipeline or CodeBuild to generate a different name for the artifact based, for example, in the deploy time;
  2. At your CloudFormation Action you pass the artifact name as a parameter for the template (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-parameter-override-functions.html) and it will redeploy the function based on new code.
Gustavo Tavares
  • 2,579
  • 15
  • 29
1

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
BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
0

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.

0

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

Rahith R R
  • 129
  • 2
  • 13