Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a new version of a Lambda function using CloudFormation?

I'm trying to create a new version of a Lambda function using CloudFormation.

I want to have multiple versions of the same Lambda function so that I can (a) point aliases at different versions - like DEV and PROD - and (b) be able to roll back to an earlier version

This is the definition of my Lambda version:

LambdaVersion:   Type: AWS::Lambda::Version   Properties:     FunctionName:       Ref: LambdaFunction 

A version gets created when running "aws cloudformation create-stack" but the subsequent "aws cloudformation update-stack" commands don't do anything. There are no new Lambda versions created.

I'm trying to get a new version of the Lambda function created after I upload new zip file to S3 and then run "update-stack". Can I do it with CloudFormation? Is AWS::Lambda::Version really broken (as mentioned here https://github.com/hashicorp/terraform/issues/6067#issuecomment-211708071) or am I just not getting something?

Update 1/11/17 Official reply from Amazon support: "...for any new version to be published you need to define an addition (sic) AWS::Lambda::Version resource..."

AWS CloudFormation/Lambda team, if you're reading this - this is unacceptable. Fix it.

like image 370
boris Avatar asked Jan 03 '17 21:01

boris


People also ask

How do I update Lambda using CloudFormation?

So, to update the Lambda function, all you need to do is update a stack parameter. But real deployments are much more complex and can have many Lambda functions that may need to be updated. For such cases, you would have to use some advance CloudFormation tricks to update the relevant strings in the template.


2 Answers

I have a similar use case (needing to use CloudFormation to manage a lambda function to be used @edge in CloudFront, for which a specific lambda function version is always required, not $LATEST) and my searches landed me at this question first, but after a bit more digging I was happy to find there is now native support for automatic lambda versioning with the new AutoPublishAlias feature of the AWS Serverless Application Model (basically an optional extra set of higher-level constructs for your CloudFormation templates).

Announced here: https://github.com/awslabs/serverless-application-model/issues/41#issuecomment-347723981

For details see:

  • https://github.com/awslabs/serverless-application-model/blob/master/docs/safe_lambda_deployments.rst#instant-traffic-shifting-using-lambda-aliases
  • https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#referencing-lambda-version--alias-resources

Essentially you include AutoPublishAlias in your AWS::Serverless::Function definition:

MyFunction:   Type: "AWS::Serverless::Function"   Properties:     # ...     AutoPublishAlias: MyAlias 

And then elsewhere in the CloudFormation template you can reference the latest published version as !Ref MyFunction.Version (yaml syntax).

like image 192
Rob Peters Avatar answered Oct 11 '22 23:10

Rob Peters


AWS::Lambda::Version is not useful. You have to add a new resource for every Lambda version. If you want to publish a new version for every Cloudformation update, you have to hack the system.

I solved this issue creating a Lambda backed custom resource which is triggered for every deployment. Inside this Lambda, I am creating a new version for the Lambda function given in parameter.

For the Lambda's source you can check http://serverless-arch-eu-west-1.s3.amazonaws.com/serverless.zip

Here is the example Cloudformation using this Deployment Lambda function (You might need some modification):

{   "AWSTemplateFormatVersion": "2010-09-09",   "Parameters": {     "DeploymentTime": {       "Type": "String",       "Description": "It is a timestamp value which shows the deployment time. Used to rotate sources."     }   },   "Resources": {     "LambdaFunctionToBeVersioned": {       "Type": "AWS::Lambda::Function",        ## HERE DEFINE YOUR LAMBDA AS USUAL ##     },     "DeploymentLambdaRole": {       "Type": "AWS::IAM::Role",       "Properties": {         "AssumeRolePolicyDocument": {           "Version": "2012-10-17",           "Statement": [             {               "Effect": "Allow",               "Principal": {                 "Service": [                   "lambda.amazonaws.com"                 ]               },               "Action": [                 "sts:AssumeRole"               ]             }           ]         },         "Path": "/",         "ManagedPolicyArns": [           "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"         ],         "Policies": [           {             "PolicyName": "LambdaExecutionPolicy",             "PolicyDocument": {               "Version": "2012-10-17",               "Statement": [                 {                   "Effect": "Allow",                   "Action": [                     "lambda:PublishVersion"                   ],                   "Resource": [                     "*"                   ]                 }               ]             }           }         ]       }     },     "DeploymentLambda": {       "Type": "AWS::Lambda::Function",       "Properties": {         "Role": {           "Fn::GetAtt": [             "DeploymentLambdaRole",             "Arn"           ]         },         "Handler": "serverless.handler",         "Runtime": "nodejs4.3",         "Code": {           "S3Bucket": {             "Fn::Sub": "serverless-arch-${AWS::Region}"           },           "S3Key": "serverless.zip"         }       }     },     "LambdaVersion": {       "Type": "Custom::LambdaVersion",       "Properties": {         "ServiceToken": {           "Fn::GetAtt": [             "DeploymentLambda",             "Arn"           ]         },         "FunctionName": {           "Ref": "LambdaFunctionToBeVersioned"         },         "DeploymentTime": {           "Ref": "DeploymentTime"         }       }     }   } } 

(Disclaimer: This code is a part of my book, for more information about Lambda & API Gateway you can check: https://www.amazon.com/Building-Serverless-Architectures-Cagatay-Gurturk/dp/1787129195)

like image 31
Çağatay Gürtürk Avatar answered Oct 12 '22 01:10

Çağatay Gürtürk