Current section
Files
Jump to
Current section
Files
lib/mix/tasks/aws/release.ex
defmodule Mix.Tasks.Aws.Release do
@moduledoc """
Create zip file for AWS Lamdba with custom runtime.
Run this task inside Docker image `amazonlinux:2.0.20200722.0`.
Docker image `erintheblack/elixir-lambda-builder:al2_1.10.4` is prepared to build.
## How to build
### zip file
```
$ mkdir -p _build
$ docker run -d -it --rm --name elx erintheblack/elixir-lambda-builder:al2_1.10.4
$ docker cp mix.exs elx:/tmp
$ docker cp lib elx:/tmp
$ docker exec elx /bin/bash -c "mix deps.get; MIX_ENV=prod mix aws.release"
$ docker cp elx:/tmp/_aws ./_build
$ docker stop elx
```
### Docker image
```
$ mkdir -p _build
$ docker run -d -it --rm --name elx erintheblack/elixir-lambda-builder:al2_1.10.4
$ docker cp mix.exs elx:/tmp
$ docker cp lib elx:/tmp
$ docker exec elx /bin/bash -c "mix deps.get; MIX_ENV=prod mix aws.release ${handle_module}"
$ docker cp elx:/tmp/_aws ./_build
$ docker stop elx
$ docker build -t ${image_name}:latest ./_build/_aws/
```
## Lambda setting
- Set `Module Name` to `handler`.
- Set Log level to `environment` -> `LOG_LEVEL`
"""
use Mix.Task
@build_dir "_aws"
@doc """
Create zip file for AWS Lamdba with custom runtime.
"""
@impl Mix.Task
def run([handler_module]), do: run_internal(true, handler_module)
def run(_args), do: run_internal(false, nil)
defp run_internal(docker?, handler_module) do
app_name = app_name()
version = version()
bootstrap = bootstrap(app_name)
env = Mix.env()
Mix.Shell.cmd("rm -f -R ./#{@build_dir}/*", &IO.puts/1)
Mix.Shell.cmd("mkdir -p ./#{@build_dir}", &IO.puts/1)
Mix.Shell.cmd("rm -f -R ./_build/#{env}/*", &IO.puts/1)
Mix.Shell.cmd("MIX_ENV=#{env} mix release --quiet", &IO.puts/1)
File.write("./_build/#{env}/rel/#{app_name}/bootstrap", bootstrap)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/bin/#{app_name}", &IO.puts/1)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/releases/*/elixir", &IO.puts/1)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/erts-*/bin/erl", &IO.puts/1)
Mix.Shell.cmd("chmod +x ./_build/#{env}/rel/#{app_name}/bootstrap", &IO.puts/1)
if docker? do
Mix.Shell.cmd("mkdir -p ./#{@build_dir}/docker", &IO.puts/1)
Mix.Shell.cmd(
"mv -f ./_build/#{env}/rel/#{app_name}/* ./#{@build_dir}/docker/",
&IO.puts/1
)
File.write("./#{@build_dir}/Dockerfile", dockerfile(handler_module))
else
Mix.Shell.cmd(
"cd ./_build/#{env}/rel/#{app_name}; zip #{app_name}-#{version}.zip -r -q *",
&IO.puts/1
)
Mix.Shell.cmd(
"mv -f ./_build/#{env}/rel/#{app_name}/#{app_name}-#{version}.zip ./#{@build_dir}/",
&IO.puts/1
)
end
end
defp app_name do
Mix.Project.config() |> Keyword.get(:app) |> to_string
end
defp version do
Mix.Project.config() |> Keyword.get(:version)
end
defp bootstrap(app_name) do
"""
#!/bin/sh
set -euo pipefail
export HOME=/
$(bin/#{app_name} start)
"""
end
defp dockerfile(handler_module) do
"""
FROM amazon/aws-lambda-provided:al2.2021.07.05.11
COPY docker/bootstrap /var/runtime/
COPY docker/ /var/task/
CMD [ "#{handler_module}" ]
"""
end
end