How to Test AWS Lambda locally

Local development for AWS Lambda is usually coupled with an all-in-one framework like Serverless. These all-in-one frameworks breech the orthogonality of software design by tightly coupling your local development to other areas like your infrastructure provisioning or your CICD scripts. To avoid tight coupling in our infrastructure at ClickFlow we are using LocalStack: a Docker container that mimic AWS functionality in our local development environment.

💻 A fully functional local AWS cloud stack. Develop and test your cloud & Serverless apps offline! (https://github.com/localstack/localstack)

Running LocalStack using Docker

Using the below Docker Compose file, run to start LocalStack.

# docker-compose.yml
version: '3.8'
services:
aws:
image: localstack/localstack:0.12.5
environment:
# Out put error messaging for local development
DEBUG: 1
# (optional) Docker network that lambdas are reachable by.
# This makes it easier for Lambads to be invoked by other
# external Docker containers.
LAMBDA_DOCKER_NETWORK: my-local-aws-network
# Use our local files via Docker volumes to define our Lambdas
LAMBDA_REMOTE_DOCKER: 0
# Spin up the Lambda module
SERVICES: lambda
ports:
- 4566:4566
volumes:
# Let LocalStack create new docker containers by giving
# LocalStack access to your computer's Docker daemon
- /var/run/docker.sock:/var/run/docker.sock
networks:
default:
name: my-local-aws-network
Image for post
Image for post

Create and Invoke Lambda locally

Borrowing from AWS’s own NodeJS example, lets create an file with the below code which will print data out to the console in LocalStack for use to see:

// index.js
const perform = async (event, context) => {
console.log("EVENT: \n" + JSON.stringify(event, null, 2))
return context.logStreamName
}
exports.handler = perform

Now that we have created our lambda and have LocalStack running we need to create our local Lambda. LocalStack is compatible with AWS CLI to create, invoke, and delete Lambdas. After installing and configuring AWS CLI on your computer

# ./nodejs-example.bash# Point aws-cli to LocalStack instead of AWS
ENDPOINT=http://localhost:4566/
# The name of our lambda in LocalStack
FUNCTION_NAME=nodejs-example
# What code do we want LocalStack to execute on. In this case the
# handler() function defined in index.js
HANDLER=index.handler
# We want to run our index.js file using the node v12 runtime
RUNTIME=nodejs12.x
# Our local working directory where index.js is located
S3_KEY=$(pwd)
# Delete Lambda (if it already exists) to start with clean slate
aws --endpoint-url ${ENDPOINT} lambda delete-function \
--function-name ${FUNCTION_NAME}
# Create Lambda
aws --endpoint-url ${ENDPOINT} lambda create-function \
--code S3Bucket="__local__",S3Key="${S3_KEY}" \
--function-name ${FUNCTION_NAME} \
--handler ${HANDLER} \
--role value-does-not-matter \
--runtime ${RUNTIME}

Now, with LocalStack running we can run to create local Lambda. Next, using AWS CLI we can also invoke our lambda like so:

# ./invoke.bashENDPOINT=http://localstack:4566
FUNCTION_NAME=nodejs-example
PAYLOAD='{ "myJsonData": "true" }'
aws lambda invoke \
--cli-binary-format raw-in-base64-out \
--function-name ${FUNCTION_NAME} \
--invocation-type RequestResponse \
--no-sign-request \
--payload ${PAYLOAD}\
--endpoint ${ENDPOINT} \
output.json

Software engineer with a background in human psychology and data analytics who affords both customer and engineer delight through Agile software architectures.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store