この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Swift on Lambda
本記事はAWS Lambda Custom Runtimes芸人 Advent Calendar 2018の10日目の記事です。
AWS LambdaがCustom Runtimesをサポートしたので、記念にSwiftでLambda Functionを書いてみました。
実行ファイルの作成
まず超簡単なSwiftファイルを用意します。名前は main.swift
にしました。
main.swift
print("Hello! Swift!")
ビルド環境の構築
SwiftはAppleから公式のDocker Imageが公開されているので、こちらを使います。
Dockerfile
FROM swift:4.2.1
RUN mkdir /lambda
WORKDIR /lambda
COPY main.swift .
COPY build.sh .
build.sh
はビルドコマンド実行用のシェルスクリプトです。-static-executable
オプションを付け、実行ファイル単体で動かせるようにします。
build.sh
#!/bin/sh
swiftc main.swift -static-executable
簡単に実行できるよう docker-compose.yml
を用意します。
docker-compose.yml
version: "3"
services:
swift:
build:
context: .
image: swift-on-lambda
command: build.sh
volumes:
- .:/lambda
docker-compose を実行すると main
ファイルが作成されます。
$ docker-compose up --build
Lambda Functionの作成
次にLambda Functionを作成します。Custom Runtimeに必要不可欠な bootstrap
ファイルはサンプルのまんまです。
bootstrap
#!/bin/sh
set -euo pipefail
EXEC="$LAMBDA_TASK_ROOT/$_HANDLER"
# 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 "$EVENT_DATA" | $EXEC)
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
これらをZipに固めます。
$ zip -r lambda.zip bootstrap main
Lambda Functionを作成します。 handler
は先ほど作成した main
を設定し、runtime
は provided
にします。
$ aws lambda create-function \
--function-name "swift-on-lambda" \
--zip-file "fileb://lambda.zip" \
--handler "main" \
--runtime provided \
--role arn:aws:iam::xxxxxxxxxxxx:role/lambda_basic_execution
完成です!
実行してみる
LambdaのManagement Consoleから試しに実行してみると、実行結果が出力されました!
まとめ
上記の手順で「Swift製のLambda Functionを実行する」ということはできているのですが、あくまでお試しです。
実際に使えるレベルにするにはSwift Package Managerでライブラリを入れつつビルドできるようにする必要が出てきます。また、例えばコンパイルせず .swift
のまま実行できたほうがデバッグしやすかったりします。
そのためにはSwiftの実行環境をCustom Runtime内で構築すべきですが、時間切れのためここまで。引き続き挑戦していきたいと思います。
なお、試した内容はGitHubに公開しました。興味があれば参考にしてみてください。