自作言語をAWS LambdaのCustom Runtimeで動かしてみました。
今回は自作言語のLANDをLambdaで動かしてみました。
LANDはシングルバイナリで動き、以下のインターフェースで処理を実行します。
$ land run -f ファイル名 -a "クラス名#メソッド名"
概要
- bootstrapと自作言語の環境(バイナリや設定ファイル)を作成
- 実行環境のzipファイルからLayerを作成
- Layerを使うLambda Functionを作成
bootstrapと自作言語の環境を作成
まずはbootstrapを作成します。名前の通りここがLambdaランタイムの起点となるようです。#!/bin/sh
set -euo pipefail
# Initialization - load function handler
CLASS=$(echo $_HANDLER | cut -d. -f1)
ACTION=$(echo $_HANDLER | cut -d. -f2)
CLASS_FILE_NAME="${LAMBDA_TASK_ROOT}/${CLASS}.cls"
LAND_BIN="$(cd $(dirname $0); pwd)/land"
# 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=$($LAND_BIN run -f ${CLASS_FILE_NAME} -a "${CLASS}#${ACTION}" "$EVENT_DATA")
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
チュートリアルのbootstrapのほぼ丸パクリですが、21行目の $LAND_BIN run …
のところが、自作言語を実行している部分になります。引数は$LAMBDA_TASK_ROOT
や$_HANDLER
から生成しています。$_HANDLER
は作成した関数のhandlerが入ります。
今回はbootstrapをbashで書いてますが、ランタイム内で使える別の言語(自作言語とか)で書いてもOKです。
続いて、自作言語のビルドをしていきます。
Dockerを使ってamazonlinuxのコンテナ内で自作言語をビルドしてローカルにビルドしたバイナリを置きます。Dockerfileの場合はFROMのイメージをこんな感じで書けばOK
FROM amazonlinux:2017.03.1.20170812
# ビルド処理...
ただ、Lambdaの実行環境で動けば良いので、必ずしもDockerfileでビルドする必要はないです。 実行環境はこちらに書いてあります↓
Lambda 実行環境と利用できるライブラリ - AWS Lambda
golangでビルドする場合はLinux + amd64でビルドしたものがそのまま動きました。
実行環境のzipファイルからLayerを作成
bootstrapと自作言語のバイナリなどをzip化してLayerを作成します$ zip runtime.zip bootstrap land
Layerはaws-cliだとこんな感じで作れます。レスポンスが返ってくるのでLayerArnをメモります。
$ aws lambda publish-layer-version \
--layer-name land-runtime \
--zip-file fileb://runtime.zip
Layerを使うLambda Functionを作成
あとはLayerを使ってLambda Functionを作るだけ。$ aws lambda create-function \
--function-name {関数名} \
--zip-file fileb://{ソースファイルのzip} \
--handler land-sample \
--runtime provided \
--role {Lambdaの実行ロール} \
--layers {作ったLayerのArn}