How to Develop AWS Lambda Functions Locally
LocalStack is the best way to develop AWS Lambda functions.
Most lambda development frameworks, like the Serverless framework or AWS SAM, are all-in-one solutions which tightly couple how you develop and deploy your lambda functions.
All-in-one solutions do not integrate well with other, and arguably better, infrastructure as code tools like Terraform.
But regardless your intentions, LocalStack lets you decouple development from deployment so that you can use the right tool for the right job.
How to Setup LocalStack
LocalStack works by mimicking AWS within localhost managed and ran through Docker Compose.
💻 A fully functional local AWS cloud stack. Develop and test your cloud & Serverless apps offline! (https://github.com/localstack/localstack)
To get started, create a docker-compose.yml
file like the one below
version: '3.8'
services:
localstack:
image: localstack/localstack:2.0.1
environment:
LS_LOG: trace
ports:
- 4566:4566
volumes:
- /var/run/docker.sock:/var/run/docker.sock
and then run docker-compose up
.
Once LocalStack is Ready
you can use the AWS CLI to create and invoke your functions locally.
How to Create a Lambda in LocalStack
Just like how you can use AWS CLI to create AWS Lambda functions in production; you can use the same commands to create functions in LocalStack.
To demonstrate how, lets create a “Hello World” lambda.
First, lets create a ./src/hello-world-v0/index.js
file which will act as our handler function.
// ./src/hello-world-v0/index.js
exports.handler = async (event = {}, ctx = {}) => {
console.log({ event })
return { event }
}
Our “Hello World” lambda will return whatever event
we pass to our lambda later.
Now that we have our lambda handler setup, we need to create our function in LocalStack using the aws lambda create-function
command.
Creating and running a ./01_create_lambda.bash
script like
#!/usr/bin/env bash
# ./01_create_lambda.bash
set -e
function create_lambda() {
# ! Absolute path to code
local dir=$PWD/src/hello-world-v0/
# * LocalStack localhost endpoint
local endpoint=http://localhost:4566
# * Lambda configuration
local function_handler=index.handler
local function_name=hello-world-v0
local function_role=arn:aws:iam::000000000000:role/localstack-does-not-care
local function_runtime=nodejs18.x
aws --endpoint-url $endpoint lambda delete-function --function-name $function_name || true
# * Create lambda in LocalStack
aws --endpoint-url $endpoint lambda create-function \
--code S3Bucket="hot-reload",S3Key="$dir" \
--function-name $function_name \
--handler $function_handler \
--role $function_role \
--runtime $function_runtime
}
create_lambda
we will create our “Hello World” function in LocalStack.
How to Invoke a Lambda in LocalStack
Just like creating a lambda function with the AWS CLI, you can also invoke a lambda using the AWS CLI.
Creating and running a ./02_invoke_lambda.bash
script to invoke our LocalStack lambda with a payload of { "hello": "world" }
like
#!/usr/bin/env bash
# ./02_invoke_lambda.bash
set -e
function invoke_lambda() {
# * LocalStack localhost endpoint
local endpoint=http://localhost:4566
# * Lambda configuration
local function_name=hello-world-v0
# * Invoke configuration
local invoke_payload='{ "hello": "world" }'
local invoke_to_file=response.json
local invoke_type=RequestResponse
# * Invoke lambda from LocalStack
aws --endpoint $endpoint lambda invoke \
--cli-binary-format raw-in-base64-out \
--function-name $function_name \
--invocation-type $invoke_type \
--payload "$invoke_payload" \
$invoke_to_file
}
invoke_lambda
we should get a response of {"event": { "hello": "world"} }
in our ./response.json
file.
Conclusion
LocalStack works by mimicking AWS on y our local computer.
This lets you create, invoke, and delete lambda functions as if they were in a production environment.
This also decouples your development process from your deployment process so that you can overall managed your lambda functions however you see fit.