概要
re:Invent2018に参加しています。
Keynote2日目でLambdaのCustom Runtimeが発表されました。
試してみたいと思います。
Custom Runtimeを触ってみる
ドキュメントやチュートリアルが公開されているので、それらを参考にBashのスクリプトを実行してみます。
ドキュメント
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
チュートリアル
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html
事前準備
2つの関数ファイルを用意します。
-
Runtime Bootstrap file
ファイル名をbootstrapとした実行可能なファイルです。Custom Runtimeの場合、Lambdaはデプロイメントパッケージ内の bootstrap という名前のファイルを実行します。そのため、エントリーポイントとして利用します。 -
Function file
bootstrapから呼び出す関数です。処理の中身はこちらに記載します。
Custom Runtimeでは、関数実行時に下記の環境変数が提供されます。
環境変数 | 概要 |
---|---|
LAMBDA_TASK_ROOT | ハンドラ関数の場所 |
LAMBDA_TASK_ROOT | 関数コードが格納されているディレクトリ |
AWS_LAMBDA_RUNTIME_API | ランタイムAPIのホストとポート |
またイベントで受け取ったjsonファイルを扱うため、作業用のディレクトリを用意し、jqをダウンロードします。
$ mkdir lambda-custom-tutorial
$ cd lambda-custom-tutorial
$ curl -o ./jq -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
Runtime Bootstrap fileの作成
エントリーポイントとなるBashスクリプトを作成します。
bootstrap
#!/bin/sh
# ハンドラ関数の読み込み
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
# 処理
while true
do
HEADERS="$(mktemp)"
# イベントの取得
EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# ハンドラ関数の実行
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
# 結果を返却
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
Bootstrap file内の処理では、専用のエンドポイントをポーリングしてイベントを取得するようです。またレスポンスもイベントごとに専用のエンドポイントが用意されるようで、そちらに返却をします。
ハンドラー関数の作成
続いてハンドラー関数を作成します。
ここではnameキーで指定された値を取得し、"Hello xxxxx !"とレスポンスするハンドラー関数を作成します。
handler.sh
function handler () {
EVENT_DATA=$1
echo "$EVENT_DATA" 1>&2;
NAME=$(echo $EVENT_DATA | $LAMBDA_TASK_ROOT/jq -r .name)
RESPONSE="Hello, $NAME !"
echo $RESPONSE
}
デプロイメントパッケージの作成
作成したファイルとjqに実行権限を付与し、Zipで固めてパッケージ化します。
$ ls
bootstrap handler.sh jq
$ chmod 755 handler.sh bootstrap jq
$ zip handler.zip handler.sh bootstrap jq
adding: bootstrap (deflated 30%)
adding: handler.sh (deflated 20%)
adding: jq (deflated 57%)
Lambda関数の作成
作成したデプロイメントパッケージを利用してLambda関数を作成します。
$ aws lambda create-function \
> --function-name bash-runtime --zip-file fileb://handler.zip \
> --handler handler.handler --runtime provided \
> --role arn:aws:iam::<account-id>:role/lambda_basic_execution
{
"FunctionName": "bash-runtime",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:<account-id>:function:bash-runtime",
"Runtime": "provided",
"Role": "arn:aws:iam::<account-id>:role/lambda_basic_execution",
"Handler": "handler.handler",
"CodeSize": 1710535,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2018-11-29T23:10:14.287+0000",
"CodeSha256": "KgI7A7F4V3DurbrDLzB+faSld9Hdp7uocsDHdnthn7I=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "9eafbc9f-9e3f-4a2b-9c37-07384671da97"
}
Custom RuntimeでLambda関数を作成するときは、--runtimeをprovidedにします。
これでLambda関数の作成は完了です。
Lambda関数をInvokeする
作成したLambda関数をInvokeして動作確認します。
$ aws lambda invoke --function-name bash-runtime --payload '{"name":"re:Invent2018"}' response.txt
$ cat response.txt
Hello, re:Invent2018 !
Custom RuntimeでLambda関数が実行され、レスポンスが返ってきているのが確認できました。
まとめ
Lambdaのアップデートとしては、いくつかの言語追加程度かなと期待していたら、Custom Runtimeが追加されたことで一気に多くの言語でLambda関数を動作させることができるようになりました。触ってみた所感としては、デプロイパッケージの作成など少し慣れないといけない部分もありそうですが、自由度が高いので、これからいろいろな活用ノウハウが共有されるようになるのではないかと期待が膨らみました。楽しみですね。