The introduction of Custom Runtimes has opened up new possibilities when it comes to the spectrum of languages that can be used in Amazon Lambda. This short document will show how to run virtually any statically linked binary on it. The example will cover a stack built Haskell project.
-
Create an Amazon Linux instance compatible with Lambda, you can use AMI link provided on the page (this is the one current for the time when this document was written, but make sure you have a look at the page if something goes not the way you expected).
- In theory it should be also possible to install Amazon Linux locally
-
SSH to the instance as you would usually do
-
Upgrade pip and aws-cli on the instance
-
sudo pip install --upgrade pip
-
sudo /usr/local/bin/pip install --upgrade awscli
-
Create an IAM user for lambda operations with
AWSLambdaFullAccess
policy attached- Enable programmatic access and export appropriate env vars:
export AWS_ACCESS_KEY_ID=.. export AWS_SECRET_ACCESS_KEY=.. export AWS_DEFAULT_REGION=..
-
Create IAM role called
basic-execution-role
withAWSLambdaBasicExecutionRole
policy attached to it- note down role arn
- Save this file to file named
bootstrap
#!/bin/sh
set -euo pipefail
while true
do
HEADERS="$(mktemp)"
# Pass the event straight to binary
RESPONSE=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next" | ./${_HANDLER})
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
zip bootstrap.zip boostrap
aws lambda public-layer-version --layer-name binary-layer --zip-file fileb://bootstrap.zip
- note down the
LayerVersionArn
- Create Haskell binary to run on the instance
- Install stack
curl -sSL https://get.haskellstack.org/ | sh
- Install required software
sudo yum install perl make automake gcc gmp-devel libffi zlib xz tar git gnupg
- Create a simple project
stack new lambda
cd lambda
stack build
stack exec lambda-exe
(to make sure it build and works properly)
- Install stack
- Package the binary
cd .stack-work/install/x86_64-linux/lts-12.20/8.4.4/bin/ && zip ~/lambda.zip lambda-exe && cd -
(beware of lts directory which may vary)
cd ~ && aws lambda create-function --function-name my-lambda --layers <layer_version_arn_from_above> --handler lambda --runtime provided --role <execution_role_arn> --zip-file fileb://lambda.zip
aws lambda invoke --function-name my-lambda response.txt
- if everything goes well you should see success - make sure by looking into output file
response.txt