snippetMinor
How to "inject" AWS Lambda code into a CloudFormation?
Viewed 0 times
intocloudformationinjectawshowcodelambda
Problem
I'm exercising an idea of not using S3 bucket to refer to the code of a lambda function.
The usual example of a lambda CloudFormation code might look like:
But what I would like to do instead is:
It is possible to do similar using CLI (create a zip manually, refer to it). I understand that CloudFormation changes would be running on the AWS infrastructure and not locally or a build server, so I'm open to other non-CloudFormation options.
So my question is - what is the best way to deploy the AWS functions sticking to "infrastructure as code", preferably sticking with CloudFormation. Or is S3 + CloudFormation really the best option?
The usual example of a lambda CloudFormation code might look like:
MyLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: hello
Handler: index.handler
Runtime: nodejs8.10
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
But what I would like to do instead is:
- inject that code from the file system, after potentially running my (unit) tests against that code;
- maybe even just inject a compiled binary instead of actual code;
It is possible to do similar using CLI (create a zip manually, refer to it). I understand that CloudFormation changes would be running on the AWS infrastructure and not locally or a build server, so I'm open to other non-CloudFormation options.
So my question is - what is the best way to deploy the AWS functions sticking to "infrastructure as code", preferably sticking with CloudFormation. Or is S3 + CloudFormation really the best option?
Solution
You've got a couple of options:
I do just that in my ec2-start-stop demo. You'll see file
Then I've got the actual Python script referred in the
Note that you're limited to 4096 bytes including new lines for your lambda code.
If you've got a more complex Lambda that needs external libraries or doesn't fit in the 4kB limit you can use
In this case your Lambda resource in the template points to a local directory, e.g.
I've used both methods in CI/CD pipelines and both work well because the source files are kept in separate files until deployment.
Hope that helps :)
- Embed the source code to the CloudFormation template
I do just that in my ec2-start-stop demo. You'll see file
ec2-start-stop.template.yml with these lines:StartStopLambda:
Type: AWS::Lambda::Function
Properties:
[...]
Runtime: python3.6
Code:
ZipFile:
Fn::Join:
[...]
-
- "%%{ec2-start-stop.lambda.py}%%"Then I've got the actual Python script referred in the
%%{ec2-start-stop.lambda.py}%% and a simple import-files.py script that somewhat intelligently embeds the python file into the yaml file and creates a valid standalone CloudFormation template with the lambda code in it.Note that you're limited to 4096 bytes including new lines for your lambda code.
- Use
aws cloudformation package / deploy
If you've got a more complex Lambda that needs external libraries or doesn't fit in the 4kB limit you can use
aws cloudformation package and aws cloudformation deploy to facilitate the deployment to CI/CD.In this case your Lambda resource in the template points to a local directory, e.g.
lambda/. The package command then zips up the contents of the directory, uploads to the provided S3 Bucket with a unique name and generates an updated CFN template with the link to the uploaded file. The aws cloudformation deploy command then takes the template, creates a change set and applies the changes, thus updating the Lambda.I've used both methods in CI/CD pipelines and both work well because the source files are kept in separate files until deployment.
Hope that helps :)
Code Snippets
StartStopLambda:
Type: AWS::Lambda::Function
Properties:
[...]
Runtime: python3.6
Code:
ZipFile:
Fn::Join:
[...]
-
- "%%{ec2-start-stop.lambda.py}%%"Context
StackExchange DevOps Q#5089, answer score: 3
Revisions (0)
No revisions yet.