# Python Lambda Packager

on
nov 16, 2018
in

When creating Lambda functions and deploy the functions using CloudFormation, the python code can be inline or packaged in a zip file. When no third party packages are required or tests are created, inline works fine. For very simple use cases this is ok. If you want to be able to test the python function locally, it should be a separate file (and not part of the CloudFormation template). There are many ways to package Lambda functions, and this is one of the easiest ways. It’s just a single command, and only requires Docker on your machine.

## CloudFormation

Consider the following CloudFormation template. You will find out the Version parameter is pretty important. If you update the code, but don’t change anything in the template, the function will not be replaced (the deployment even fails). In this example I just use an auto increment bash script to generate a new zip file and use this prefix when uploading. CloudFormation now thinks the function is new, will deploy the template and replace the function.

Parameters:
Version:
content: Lambdas are written in a version directory, which is auto incremented on upload
Type: String
Resources:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Handler: lambda_function.lambda_handler
Timeout: 30
Role: !GetAtt 'LambdaBasicExecutionRole.Arn'
Runtime: python3.6
Code:
S3Bucket: "mybucketname"
S3Key: !Sub "${Version}/<lambda_name>.zip" LambdaBasicExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole  This is the file structure you should consider using. The .gitignore is important to prevent saving the build artifacts ending up in your git repo (it’s a zip file and can grow quite big). You can also add custom dependencies in this folder. └── src └── <lambda_name> ├── lambda_function.py ├── readme.md └── requirements.txt └── ... └── build └── <lambda_name>.zip └── ... └── .gitignore └── version.txt └── template.yml  Now run the command to package all functions, including the version trick, and upload them to an S3 bucket. docker run -v$(pwd)/src:/src \
-v $(pwd)/build:/build \ binxio/python-lambda-packager version=cat version.txt version=$[$version+1] echo$version > version.txt

aws s3 cp --recursive \
./build s3://mybucketname/stack/${version}  Now you can deploy the CloudFormation stack using the uploaded Lambdas and example template, using the following command. version=cat version.txt aws cloudformation deploy \ --stack-name <stack name> \ --template-file template.yml \ --capabilities CAPABILITY_IAM \ --parameter-overrides version=${version}