Building DevSecOps solutions using AWS, Terraform and Kubernetes

Deploy a Python Lambda

  • 13th August 2022

The Problem

If you're used to using Golang, then everything gets bundled up into a single binary and deployments are easy.

However, if you're using Python then a simple pip install isn't enough to make sure that your third party binary are installed correctly. You need to make sure you are specifying which platform, python version and binaries you want to include.

Let's create our lambda and look at creating a Makefile to handle building, deploying and running a lambda.

Deploy a Python Lambda

The Solution

1) Prerequisites
This article assumes you have these installed already:
  • Python 3.9
  • Pip3
  • AWS CLI
  • The jq package for parsing json
  • IAM permissions required to deploy the lambda
2) Create lambda in console

Create a lambda called BlogHelloWorldExample with the Python 3.9 runtime in the AWS console. This example uses the eu-west-1 region. You'll only do this once, and it will save you needing to create the IAM role yourself.

Image showing fields to complete to create a python lambda in the console
3) Create lambda_function.py file

Create a file called lambda_function.py in the project root directory on your local machine.

Here is a quick hello world script.

import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    # TODO implement
    logger.info('HelloWorld from Python Lambda!')
    return {
        'statusCode': 200,
        'body': json.dumps('HelloWorld from Python Lambda!')
    }
4) Create requirements.txt

Python convention is to list your requirements in a file called requirements.txt, so create that file and add our first dependency:

boto3

While boto3 is already included in the lambda by default, you will need it locally if you want to interact with any of the other AWS resources in your script.

5) Create Makefile

Create a file called Makefile in the root directory.

Please edit the parameters for LAMBDA_NAME and LAMBDA_REGION

The important part to note here is how we are building our dependencies, we are following this guide from AWS. This will let us create and zip up all of our binaries in a format that's compatible with the lambda.

export LAMBDA_NAME=BlogHelloWorldExample
export LAMBDA_REGION=eu-west-1

.DEFAULT_GOAL := all

build:
	pip3 install -r requirements.txt \
		--platform manylinux2014_x86_64 \
		--target=. \
		--implementation cp \
		--python 3.9 \
		--only-binary=:all: --upgrade

deploy:
	zip -r function.zip ./
	aws lambda update-function-code \
		--function-name "${LAMBDA_NAME}" \
		--zip-file fileb://function.zip \
		--region="${LAMBDA_REGION}" \
		| jq ".LastUpdateStatusReason" -r
	aws lambda wait function-updated \
		--function-name "${LAMBDA_NAME}" \
		--region="${LAMBDA_REGION}"
	@echo "The function has been deloyed."

run:
	aws lambda invoke \
		--function-name "${LAMBDA_NAME}" \
		--region="${LAMBDA_REGION}" out \
		--log-type Tail \
		| jq ".LogResult" -r | base64 -d

all:
	make build
	make deploy
	make run

Note: If you receive the error "Makefile:6: *** missing separator. Stop.", make sure to replace the spaces with tabs.

6) Install Python Dependencies

You only need to do this step each time your requirements.txt changes:

make build

This installs all of our dependencies and creates a zip file we can upload to our lambda.

7) Run Makefile

Run the following CLI command to build, zip and deploy our example Lambda

make deploy

You should now see output similar to:

...
The function is being created.
...
The function has been deloyed.
8) Invoke Lambda

Now to confirm it works, you can either run a test in the console or use our newly created Makefile from CLI:

make run

If it works you should see your logged statement in the response:

...
[INFO]  2022-08-13T12:21:15.565Z some-request-uuid HelloWorld from Python Lambda!
...

Summary

That's it! Your lambda should now be working. The build step within the Makefile will make sure that you are installing the correct version that will work in your lambda.

As a bonus tip, if you want to build, deploy and run in a single command just run this CLI shortcut:

make

Hopefully this also gives you a quick starting point for building your own deployment pipeline.

Rhuaridh

Please get in touch through my socials if you would like to ask any questions - I am always happy to speak tech!