Rust で書いたコードを AWS Lambda で動かす

Mac でクロスコンパイルしたバイナリを Lambda で動かすという記事はあったのですが、Linux でビルドして Lambda で動かすという記事が見当たらなかったのと、それなりに躓いたのでメモを残しておきます。

Rust 自体はインストールできてるとして、大まかな手順としては、

  1. rustup で target x86_64-linux-unknown-musl を追加する
  2. musl-gcc をインストールする
  3. cargo でビルド
  4. Lambda にデプロイ

ではそれぞれ詳細な手順をば。

1. rustup で target x86_64-linux-unknown-musl を追加する

これは以下のコマンドを実行するだけですね。

rustup target add x86_64-linux-unknown-musl

2. musl-gcc をインストールする

Mac だと brew で、Ubuntu だと apt で入れられるっぽいのですが、私の使っている Amazon Linux だと yum で入れる方法がわからなかったのでソースからビルドしました。

GitHub - richfelker/musl-cross-make: Simple makefile-based build for musl cross compiler

こちらのリポジトリをクローンしてきて、

TARGET=x86_64-linux-musl make

これにはしばらく時間がかかります。

ビルドが完了したら

make install

これで output ディレクトリ以下に成果物ができます。

成果物を適当なディレクトリにコピーします。

sudo cp -f output/* /usr

cargo でビルド

AWS Lambda で動く Rust のコードは AWS のオフィシャルなブログでサンプルコードが公開 されています。

まずはこちらのコマンドを実行して雛形を作っていきます。

cargo new my_lambda_function --bin

記事に書かれているように Cargo.toml[dependencies] セクションの内容を追加していきます。

[package] セクションに autobins = false を追加するのを忘れずに。

[[bin]] セクションも追加します。

.cargo ディレクトリを作成し、その下に config というファイルを作って以下のような内容を書きます

[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"

そしてこれをビルドします。

CC_x86_64_unknown_linux_musl="x86_64-linux-musl-gcc" cargo build --release --target x86_64-unknown-linux-musl

ビルドが成功すると、以下の場所にファイルができています。

$ file target/x86_64-unknown-linux-musl/release/bootstrap
target/x86_64-unknown-linux-musl/release/bootstrap: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

static link されていますね。

これを zip します。

zip -j rust.zip ./target/x86_64-unknown-linux-musl/release/bootstrap

4. Lambda にデプロイ

AWS の管理コンソールにログインして Lambda の関数を新しく作ります。

Auth from scratch を選択して Runtime は Provide your own bootstrap を選択します。

Function code で Upload a .zip file を選択して先程作成した rust.zip をアップロードします。

Save を押します。

以下のようなテストデータを作成してテストを実行してみましょう。

{
  "firstName": "Takashi"
}

実行が成功して以下のようなレスポンスが得られたら成功です!

{
  "message": "Hello, Takashi!"
}