Rust で AWS Lambda を実装する機会がありましたが、ちょっとクセがあったので、備忘録も兼ねて記事にしておきます。
デプロイも簡略化できるよう、 Serverless Framework を使ってデプロイできるようにします。
環境
$ rustc -V
rustc 1.45.0 (5c1f21c3b 2020-07-13)
$ cargo --version
cargo 1.45.0 (744bd1fbb 2020-06-15)
とりあえず動かすまで
通常通り、プロジェクト作成
cargo new sample_lambda_function
使用する crete 等を Cargo.toml に記述
Cargo.toml
[package]
name = “sample_lambda_function”
version = “0.1.0”
authors = [“example name <example@mail.com>”]
edition = “2018”
[dependencies]
lambda_runtime = “0.2.1”
serde = { version = “1.0.117”, features = [“derive”] }
package.json を作成して以下のように編集する
package.json
{
“scripts”: {
“build”: “docker run –rm -v $PWD:/code -v $HOME/.cargo/registry:/root/.cargo/registry -v $HOME/.cargo/git:/root/.cargo/git softprops/lambda-rust:latest”,
“deploy”: “sls deploy –stage dev –verbose”
},
“devDependencies”: {
“serverless”: “2.8.0”,
“serverless-rust”: “0.3.8”
}
}
上記を作成したら yarn install で Serverless Framework を手元のプロジェクトにインストールする
とりあえず動かすための Lambda 関数を作成する。 src/main.rs を以下のように実装する:
メイン関数は lambda の マクロを用いて、ハンドラ関数を呼び出す。
ハンドラ関数には、イベントとコンテキストを引数に指定する。
main.rs
use std::error::Error as StdError;
use lambda_runtime::{error::HandlerError, lambda, Context};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
#[serde(rename_all = “camelCase”)]
struct CustomEvent {
first_time: String,
}
#[derive(Serialize)]
#[serde(rename_all = “camelCase”)]
struct CustomOutput {
message: String,
}
fn main() -> Result<(), Box> {
lambda!(handler);
Ok(())
}
fn handler(
event: CustomEvent,
_context: Context,
) -> Result<CustomOutput, HandlerError> {
Ok(CustomOutput {
message: format!(“Hello, {}!”, event.first_time),
})
}
手元でビルドをしてみる。ビルドには softprops/lambda-rust の Docker イメージを利用する
https://hub.docker.com/r/softprops/lambda-rust/
yarn build
エラーなく無事にビルドできたら OK
serverless.yml を以下のように作成する
作成される関数名は [seivice で指定した名前]-[ステージ名]-[functions の下で指定した名前] となる。
serverless.yml
service: sample-lambda-function
provider:
name: aws
runtime: rust
memorySize: 128
region: us-east-2
package:
individually: true
plugins:
– serverless-rust
custom:
# this section customizes of the default
# serverless-rust plugin settings
rust:
dockerTag: ‘latest’
functions:
hello_world:
handler: sample_lambda_function
デプロイは以下のコマンドで可能。
yarn deploy
複数の Lambda 関数をデプロイする
-
- ライブラリ + 複数バイナリの構成にする方法を採用する
構成としてはこんな感じ
.
|– Cargo.toml
|– node_modules
|– package.json
|– serverless.yml
|– src
| `– bin
| |– function-a.rs
| `– function-b.rs
`– target
Cargo.toml に以下の記述を追加する
Cargo.toml
[[bin]]
name = “function-a”
path = “src/bin/function-a.rs”
[[bin]]
name = “function-b”
path = “src/bin/function-b.rs”
serverless.yml には以下のように書く
ハンドラの指定は、「【Cargo.toml の [package] の name】.【Cargo.toml の [[bin]] の name】」と記述する
serverless.yml
functions:
function-a:
handler: sample_lambda_function.function-a
function-b:
handler: sample_lambda_function.function-b
ビルドとデプロイのコマンドは先程と同じ。
複数の関数は関連した関数としてデプロイされる。
参考資料
Rustで始めるCustom Runtime Lambda入門
記事の内容全般について参考にしました。