AWS LambdaのCustom Runtimeでmrubyを動かしてみた

re:Invent 2018で発表されたAWS Lambdaのカスタムランタイム機能、言語の縛りがなくなるということで、各地で盛り上がっています。アドベントカレンダーもできているほどです。

ぼくも試したくなったので、まだ触れたことのないmrubyを動かしてみることにしました。

レイヤと関数を作るだけで動きそう

手始めに、公式のチュートリアルAWSパートナーによるPHPのカスタムレイヤ、先達の記事(PerlNim)などを読みました。結果、下記の方針で進めればよさそうなことがわかりました。

  1. bootstrapスクリプトとmrubyを含むレイヤを作る
  2. 上記レイヤを指定した関数を作る

というわけで、下記の手順で進めてみました。

レイヤを作る

bootstrapスクリプト

まず、必須のbootstrapスクリプトを作ります。特に凝ったことはしないので、内容はチュートリアルとほぼ同じでよさそうです。

ただ、バイトコードに変換済みのファイルを mruby -b で動かすため、以下のようにします(12行目)。

Dockerfileでmrubyをビルド

また、mrubyのビルドも必要です。PHPのカスタムレイヤと同じく(参考)、lambci/lambda:build-nodejs8.10 をベースイメージとしたDockerコンテナ上で進めることにします。

Dockerfileは下記の内容にします。ruby-installを使って、Rubyとmrubyを順にビルドする寸法です。

zip_layer.shでアーカイブ

できた bootstrapmruby は、ZIPアーカイブにします。のちほどAWSにアップロードするためです。

ここでは、PHPカスタムレイヤの build.sh を参考に、アーカイブスクリプト zip_layer.sh を作ります。以下の内容です。

下記を実行すると、layer.zip が作成されます。

$ docker run --rm -v $(pwd):/opt/work \
aws-lambda-mruby-playground /opt/work/zip_layer.sh

aws lambda publish-layer-versionの実行

できた layer.zip を使って、AWS Lambda上にレイヤを作成します。

$ aws lambda publish-layer-version \
--layer-name mruby141 \
--zip-file fileb://layer.zip

関数を作る

function.rb

引数をそのまま出力するだけの function.rb を作ります。

zip_function.shでバイトコードに変換してアーカイブ

function.rb は、mrubyで動かすため mrbc function.rb でバイトコードに変換します。さらに、変換後の function.mrb を、レイヤと同じくZIPアーカイブにします。

というわけで、これらをまとめて処理する zip_function.sh を作ります。

下記のように実行すると、function.zip が作成されます。

$ docker run --rm -v $(pwd):/opt/work \
aws-lambda-mruby-playground /opt/work/zip_function.sh

aws lambda create-functionの実行

できた function.zip を使って、AWS Lambda上に関数を作ります。

$ aws lambda create-function \
--function-name mruby-test \
--zip-file fileb://function.zip \
--handler function \
--runtime provided \
--role {Lambda実行ロールのARN} \
--layers {レイヤのARN}

いざテスト!

テストイベントの設定

準備ができたので、AWSコンソール上でテストしてみます。とりあえず、簡単なJSONを渡すことにします。

実行結果

テストを実行すると、イベントデータがちゃんと出力されました!

まとめ

AWS Lambdaのカスタムランタイム機能を使って、mrubyの関数を動かしてみました。今回は端折ってしまいましたが、JSONライブラリをmrubyに組み込めば、上記のようなイベントデータのパースも可能のはずです。

今回使ったファイルは、以下のGitHubリポジトリにまとめています。よろしければご参照ください。