AWS.Lambda.Runtime
A dependency-free AWS Lambda custom runtime for Elixir.
AWS.Lambda.Runtime implements the Lambda Runtime API
directly on top of :inets/:httpc and the OTP-bundled JSON module — no
HTTP client, no JSON library, and no other dependency beyond what ships with
Erlang/OTP itself. It also wires up the mix release steps needed to package
a function for the provided.al2023 runtime.
Installation
Add aws_lambda_runtime to your list of dependencies in mix.exs:
def deps do
[
{:aws_lambda_runtime, "~> 0.1.0"}
]
end
Usage
The steps below take you from a blank mix new project to a function ready
to be packaged for Lambda.
1. Create the function app
mix new hello_function
cd hello_function
2. Add the dependency and wire up releases
Add aws_lambda_runtime to deps/0 in mix.exs:
defp deps do
[
{:aws_lambda_runtime, "~> 0.1.0"}
]
end
Fetch it:
mix deps.get
Then, at the very top of mix.exs — above defmodule HelloFunction.MixProject do,
as the first line of the file — require the release helper shipped in
priv/mix/release.exs:
Code.require_file("deps/aws_lambda_runtime/priv/mix/release.exs", __DIR__)
This has to happen outside of any module body, and before Mix has compiled
any dependency — AWS.Lambda.Runtime.MixRelease is a plain script rather
than part of the compiled :aws_lambda_runtime application, specifically so
it is available this early.
Then, inside project/0, declare the release:
def project do
[
app: :hello_function,
version: "0.1.0",
elixir: "~> 1.18",
start_permanent: Mix.env() == :prod,
deps: deps(),
releases: AWS.Lambda.Runtime.MixRelease.releases()
]
end
AWS.Lambda.Runtime.MixRelease.releases/1 returns a release configured with
include_erts: false (ERTS comes from the Lambda layer, see below) and the
steps that copy the bootstrap entrypoint and the vm.args/env.sh files
Lambda's provided.al2023 runtime expects.
3. Write a handler
A handler is any module that implements the AWS.Lambda.Runtime.Handler
behaviour — a handle_event/2-shaped function receiving the decoded event
and an AWS.Lambda.Runtime.Context struct:
defmodule HelloFunction do
alias AWS.Lambda.Runtime.Context
alias AWS.Lambda.Runtime.Handler
@behaviour Handler
@impl Handler
def handler(event, context) do
{:ok,
%{
message: "hello from Elixir on #{:erlang.system_info(:otp_release)}",
received: event,
request_id: context.request_id,
remaining_ms: Context.remaining_time_ms(context)
}}
end
end
Point the function's Handler setting at it, e.g. HelloFunction or
HelloFunction.handler — see the AWS.Lambda.Runtime.Handler moduledoc for
every accepted format.
4. Build and deploy
mix release
produces a release under _build/prod/rel/lambda that can be zipped and
uploaded as a Lambda function package (or built inside a Docker image
targeting linux/arm64/linux/x86_64, matching the layer below).
The AWS Layer for OTP
Because releases are built with include_erts: false, the function package
only ships Elixir and your own code — the Erlang/OTP runtime itself must come
from a Lambda layer mounted at /opt/otp, matching the OTP version the
release was built against. More detailed instructions on building and
publishing this layer will be provided separately.
Trademarks
"AWS", "Amazon Web Services", and "AWS Lambda" are trademarks of Amazon.com, Inc. or its affiliates. This project is an independent, community-maintained library and is not affiliated with, endorsed by, or sponsored by Amazon.com, Inc. or its affiliates.