AWS Lambda を Elixir で実行してみる

先日、AWS re:Invent 2018 で AWS Lambda にて Custom Runtime という機能が発表されました。興味があったので「New for AWS Lambda – Use Any Programming Language and Share Common Components | AWS News Blog」を読んでいると We are also working with our partners to provide more runtimes: Erlang (Alert Logic) Elixir (Alert Logic) という記述があり、Elixir好きとして試してみることにしました。

ビルド用コンテナイメージの作成

まずはじめに Elixir コードをコンパイルするための Docker コンテナイメージをビルドします。Elixir で書いたコードを AWS Lambda 上で実行するには、実行する同じ環境でコードをコンパイルする必要があるようです。以下のように GitHub から取得してビルドします。

$ git clone https://github.com/alertlogic/erllambda_docker.git
$ docker build -t erllambda:20.3-elixir erllambda_docker/elixir

プロジェクトの作成

コンテナを作成している間に Elixir プロジェクトを作成します。作成には、ローカル環境で Elixir が必要になります。

$ mix new hello_lambda
$ cd hello_lambda

lib/hello_lambda.ex を以下のように変更します。

defmodule HelloLambda do
  def handle(_event, _context) do
    {:ok, "Hello from Elixir"}
  end
end

ファンクション名はhandleとする必要があります。 mix.exsを編集してLambdaにアップロードするためのZIPファイルを作成するための依存性を追加します。

defp deps do
  [
    {:erllambda, "~> 2.0"},
    {:mix_erllambda, "~> 1.0"}
  ]
end

アップロードパッケージの作成

作成したコンテナを利用して以下のようにアップロードパッケージを作成します。

$ docker run -it --rm -v `pwd`:/buildroot -w /buildroot -e MIX_ENV=prod erllambda:20.3-elixir mix do deps.get, deps.compile, release.init, erllambda.release

本来なら release.init の後で rel/config.exs を確認すると良いのですが、今回は必要ないので一気にパッケージを作成します。 ビルドが成功すると _build/prod/rel/hello_lambda/releases/0.1.0/ 内に hello_lambda.zip が作成されているはずです。

Lambda 関数の作成

AWS コンソールにログインして Lambda 関数を作成します。ランタイムに「関数コードまたはレイヤーでカスタムランタイムを使用」を選択します。ロールは関数が実行できれば良いです。f:id:eitoball:20181219003705p:plain 関数が作成できたら作成したZIPファイルをアップロードします。アップロードする際は、ハンドラを「Elixir.HelloLambda」と指定して下さい。"HelloLambda"はプロジェクトでhandle関数があるモジュール名です。f:id:eitoball:20181219004141p:plain

関数の実行

テストイベントを作成して関数を実行します。テストイベントは「Hello World」というテンプレートを利用して下さい。実行が成功するとこのようにログに表示されます。 f:id:eitoball:20181219004440p:plain デフォルトの設定のメモリが128MBでタイムアウトが3秒する場合があるので、失敗する場合はログを見ながら適宜変更してみて下さい。

感想

AWS Lambda の関数をElixir などの色々な言語で書くことができるようになり選択が広がるのは良いことだと思いました。JavaScriptPython での場合と比べると起動が遅いような気がします。何か Elixir だと良い Lambda 関数とかがあるのだろうか…