re:Invent 2018 新機能!LambdaのCustom Runtimesを試してみた
Hello, サービス開発チームの北野です。
re:Inventでラスベガスに来ています。とうとう最終日です。
今日はKeynoteでServerless関連が大きくアップデートしました。
LambdaのRubyサポート, Lambda Layers, API GatewayのWebSocket対応, ALB for Lambdaなどなど、
どれも使ってみるのが楽しみになるアップデートでした。
LambdaのCustom Runtimesの発表を見て、
「これはもしやハンズラボの謎技術ユニケージ on Lambdaができるのでは…?」
という悪魔のささやきが聞こえましたが、無視しました。
ちなみに私は業務でユニケージを触ったことはございません。
それはともかく、LambdaのCustom Runtimesが気になったので、公式チュートリアルに沿って試してみました。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtimes-walkthrough.html
Lambdaの作成
まずはLambdaをマネジメントコンソールから作成します。
ランタイムに「独自のランタイムを使用する」という選択肢が増えているので、これを選びます。
名前とロールは適当に設定して関数を作成します。
独自のランタイムを使用する場合、プログラムはマネジメントコンソールで編集できないようなので、プログラムはローカルマシンで作成します。
bootstrapの作成
独自のランタイムを使用する場合、bootstrapシェルスクリプトを起点にLambdaが動くようです。
サンプルスクリプトを見ると、LambdaのRuntimeAPIに対してGETでHTTPアクセスしてLambdaを起動したEventを取得して、
LambdaのRuntimeAPIに対してPOSTでHTTPアクセスしてResponseを返す仕組みになっています。
今回はサンプルスクリプトをちょっとだけ変更して使います。
bootstrap
#!/bin/sh
set -euo pipefail
# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
# Processing
while true
do
HEADERS="$(mktemp)"
# Get an event
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)
# Execute the handler function from the script
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
echo $RESPONSE | tr "@" "\n"
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
function.shの作成
bootstrapから呼び出して実行するシェルスクリプトfunction.shを作成します。
シェルスクリプトのfunctionには戻り値が無いので、標準出力を使って擬似的に戻り値があるような振る舞いをさせます。
シェルスクリプトに馴染みがないとよくわからないと思うので、bootstrapの振る舞いと合わせて後ほど解説します。
function.shもサンプルスクリプトを少し変更して使います。
function.sh
function handler () {
EVENT_DATA=$1
echo "$EVENT_DATA" 1>&2;
echo " ,.rニ二)_ @ ,' ___二) @! __ノ @| __,ノ @l、___,,..ノ HANDS LAB"
}
bootstrapとfunction.shの振る舞い
シェルスクリプトの動作について少しだけ解説します。
まず環境変数$_HANDLERには、Lambdaで設定しているハンドラが設定されます。
今回はfunction.handlerという値が設定される想定です。
そしてbootstrapの6行目
source $LAMBDA_TASK_ROOT/”$(echo $_HANDLER | cut -d. -f1).sh”
の
echo $_HANDLER | cut -d. -f1
で、function.handlerを”.”で文字列分割した1つ目を取得しています。
これを展開すると、
source $LAMBDA_TASK_ROOT/function.sh
ということになります。
17行目も似たような形で、
RESPONSE=$($(echo “$_HANDLER” | cut -d. -f2) “$EVENT_DATA”)
の
echo “$_HANDLER” | cut -d. -f2
で、function.handlerを”.”で文字列分割した2つ目を取得しています。
これを展開すると、
RESPONSE=$(handler “$EVENT_DATA”)
ということになります。
このhandlerはfunction.shで定義したfunctionで、handler実行時の標準出力がRESPONSE変数に格納されます。
$()
を使ってfunctionの標準出力を変数に格納することで、擬似的に戻り値があるような振る舞いをさせています。
Lambdaのコードアップロード
作成した二つのファイルはzip圧縮して一つのファイルにします。
- bootstrap
- function.sh
マネジメントコンソールを開いて、コードエントリタイプで「.zipファイルをアップロード」を選択します。
アップロードボタンを押して作成したzipファイルを選択し、ハンドラを修正して保存ボタンを押します。
これで動かす準備が出来ました。テスト実行してみましょう。
Lambdaのテスト実行
右上の方にあるテストボタンを押します。
テスト用のEventを作る必要があるので、名前だけつけて適当に作成します。
作成したEventが設定されていることを確認して、再度テストボタンを押します。
「実行結果:成功」でちゃんと動いています。やったね!
終わりに
LambdaのCustom Runtimesを動かすことができました。
便利だなと思う半面、せっかくのシンプルなLambdaにだいぶ管理しなければならないことが増えてしまう印象があり、Custom Runtimesの使用は慎重に検討したいところです。
選択肢が増えたことはとても良いことだと思うので、本当にCustom Runtimesを使う必要があるのか?他にもっと良い方法が無いか?と自問自答して、適切な技術選択をしていけたらと思います。