AWS LambdaのCustom Runtimesを利用してSwiftでLambda Functionを作ってみた! #reinvent

2018.12.10

この記事は公開されてから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 を設定し、runtimeprovided にします。

$ 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に公開しました。興味があれば参考にしてみてください。

参考