Closed9

Swift を AWS Lambda で使うために必要だったこと

yukiyuki

日本語情報でもいくつかブログ記事があり参考にできたが、情報が若干古いものもあったので、改めて Lambda で Hello, World するためになにをやったかをまとめ直してみる。

yukiyuki

まず 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"]),
    ]
)
yukiyuki

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月頃の投稿で同様の質問をしている人がいた。

https://forums.swift.org/t/how-to-use-withlocalserver-if-its-internal/37727

コメントにある通り、解決策は LOCAL_LAMBDA_SERVER_ENABLED という環境変数を true に設定して起動することだった。

ということで、withLocalServer のブロックを削除し、Xcode の設定を使って環境変数を下記のようにセットした。

yukiyuki

無事起動できたので、下記のように何かしらのデータを送る 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%
yukiyuki

builder 用の Dockerfile を用意する

FROM swiftlang/swift:nightly-master-amazonlinux2

RUN yum -y install zip
yukiyuki

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 *
yukiyuki

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 にアップロードするだけ。

yukiyuki

上げてみた。バイナリサイズは少々大きめみたいだ。Rustだと、同等のコードならこの1/3で済むと思う。

このスクラップは2021/09/05にクローズされました