Swift を AWS Lambda で使うために必要だったこと
日本語情報でもいくつかブログ記事があり参考にできたが、情報が若干古いものもあったので、改めて Lambda で Hello, World するためになにをやったかをまとめ直してみる。
手順を参考にした記事
まず Swift パッケージ等を用いて上の記事のようにプロジェクトをセットアップする。
今回は、「AWSLambda
」という名前でディレクトリを作ったので、そのディレクトリを基準にセットアップした。
Package.swift は下記のようになった。
import PackageDescription
let package = Package(
name: "AWSLambda",
products: [
.executable(name: "AWSLambda", targets: ["AWSLambda"])
],
dependencies: [
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", from: "0.1.0"),
],
targets: [
.target(
name: "AWSLambda",
dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
]),
.testTarget(
name: "AWSLambdaTests",
dependencies: ["AWSLambda"]),
]
)
main.swift は下記のようになる。
import AWSLambdaRuntime
Lambda.run { (_, _, callback) in
callback(.success("Hello, Lambda. by Swift"))
}
紹介した記事では、try Lambda.withLocalServer {
というブロックで囲まれていたが、これを現在のバージョン 0.1.0
の Lambda Runtime で書くとエラーになる。withLocalServer
の可視性が調整されたようなエラーが出る。
実際にいろいろと変更状況と対応策を探ってみたところ、2020年の6月頃の投稿で同様の質問をしている人がいた。
コメントにある通り、解決策は LOCAL_LAMBDA_SERVER_ENABLED
という環境変数を true
に設定して起動することだった。
ということで、withLocalServer
のブロックを削除し、Xcode の設定を使って環境変数を下記のようにセットした。
無事起動できたので、下記のように何かしらのデータを送る curl を Lambda に送信する。localhost のポートは7000番で、/invoke
というエンドポイントを利用すると Lambda をローカルでモック起動できる。
❯ curl -X POST http://127.0.0.1:7000/invoke --data 'test' -i
HTTP/1.1 200 OK
content-length: 23
Hello, Lambda. by Swift%
builder 用の Dockerfile を用意する
FROM swiftlang/swift:nightly-master-amazonlinux2
RUN yum -y install zip
Lambda 用にパッケージングするシェルスクリプトを書く。
#!/bin/bash
set -eu
executable="AWSLambda"
target=.build/lambda/$executable
rm -rf "$target"
mkdir -p "$target"
cp ".build/release/$executable" "$target/"
cp -Pv /usr/lib/swift/linux/lib*so* "$target"
cd "$target"
ln -s "$executable" "bootstrap"
zip --symlinks lambda.zip *
docker build して、Swift コードのビルドをする下記を実行する。
docker run --rm -v "$(pwd)":/workspace -w /workspace builder bash -cl "swift build --product AWSLambda -c release -Xswiftc -g"
その後、zip ファイルを作る下記を実行する。
docker run --rm -v "$(pwd)":/workspace -w /workspace builder bash -cl "./package.sh"
あとは、できあがった zip を Lambda にアップロードするだけ。
上げてみた。バイナリサイズは少々大きめみたいだ。Rustだと、同等のコードならこの1/3で済むと思う。