MacOS(Intel)でクロスコンパイル出来たら楽なんですが、一筋縄ではいかないのでDockerを使います。
Rustツールチェーンがプリインストールされたsoftprops/lambda-rustをビルドに使います。
ところが、Docker Hubで公開されているsoftprops/lambda-rust:latest
の
Rustのバージョンが古い(1.45)ので、lambda_runtime "0.3.0"
のビルドに失敗する。
ビルドエラーの詳細は↓こちらの折り畳みにまとめてあります。
ビルドエラー詳細
softprops/lambda-rust:latest
でビルドしたときのログ
docker run --rm -v ${PWD}:/code -v ${HOME}/.cargo/registry:/cargo/registry -v ${HOME}/.cargo/git:/cargo/git softprops/lambda-rust:latest
Updating crates.io index
Downloading crates ...
Downloaded num-integer v0.1.44
Downloaded pin-utils v0.1.0
Downloaded proc-macro-hack v0.5.19
(省略)
Compiling num_cpus v1.13.0
Compiling socket2 v0.4.0
Compiling time v0.1.44
error[E0658]: `match` is not allowed in a `const fn`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/socket2-0.4.0/src/lib.rs:156:9
|
156 | / match address {
157 | | SocketAddr::V4(_) => Domain::IPV4,
158 | | SocketAddr::V6(_) => Domain::IPV6,
159 | | }
| |_________^
|
= note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
error: could not compile `socket2`.
To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed
socket2はhyperが依存しているcrate
cargo tree -i socket2
socket2 v0.4.0
└── hyper v0.14.7
└── lambda_runtime v0.3.0
└── rust_lambda_sample v0.1.0
コンパイルエラーが発生する箇所はここ
impl Domain {
/// Domain for IPv4 communication, corresponding to `AF_INET`.
pub const IPV4: Domain = Domain(sys::AF_INET);
/// Domain for IPv6 communication, corresponding to `AF_INET6`.
pub const IPV6: Domain = Domain(sys::AF_INET6);
/// Returns the correct domain for `address`.
pub const fn for_address(address: SocketAddr) -> Domain {
match address {
SocketAddr::V4(_) => Domain::IPV4,
SocketAddr::V6(_) => Domain::IPV6,
}
}
}
Rust 1.46.0からconst fn
の中でmatch
が使えるようになった。
すなわち、Rust 1.46.0以上では上記のコードは合法である。
lambda-rustのGitHubのmasterブランチはRust 1.51に対応しています。
(commit sha: 0280da0821c4671af1554757bbc7adb59dbfa0d4
)
ということで、ローカルにクローンしてイメージをビルドします。
git clone https://github.com/softprops/lambda-rust.git
cd lambda-rust
docker build -t softprops/lambda-rust:1.51 .
ローカルのsoftprops/lambda-rust:1.51
イメージでコードをビルドします。
まずはこのリポジトリをクローンしてください。main.rs
はaws-lambda-rust-runtime/basic.rs at master · awslabs/aws-lambda-rust-runtimeをお借りしました。
git clone https://github.com/ryosukeeeee/rust_lambda_sample.git
cd rust_lambda_sample
プロジェクトルートで↓のコマンドを実行します。ビルドにはかなり時間がかかるので気長に待ちましょう。
docker run --rm \
-v ${PWD}:/code \
-v ${HOME}/.cargo/registry:/cargo/registry \
-v ${HOME}/.cargo/git:/cargo/git \
softprops/lambda-rust:1.51
ビルドが終わると、./target/lambda/release/
にzipファイルが作られています。
これをlambdaにデプロイします。
aws lambda create-function \
--function-name rustTest \
--zip-file fileb://./target/lambda/release/rust_lambda_sample.zip \
--role arn:aws:iam::0123456789012345:role/YourLambdaRole \
--runtime provided.al2 \
--handler doesnt.matter \
--profile yourprofile
デプロイに成功したら、呼び出してみましょう。
aws lambda invoke \
--cli-binary-format raw-in-base64-out \
--function-name rustTest \
--payload '{"command": "Hello World"}' \
--profile yourprofile \
output.json
cat output.json
serverless frameworkのプラグインが存在する。
softprops/serverless-rust: ⚡ 🦀 a serverless framework plugin for rustlang applications
内部ではソースコードのビルドにsoftprops/lambda-rust:latest
を使用している。
上述した理由と同じ理由でコンパイルエラーが発生してビルド出来ない。(2021年5月24日現在)
ソースコードのビルドに使用するDockerイメージを指定できるので、ローカルのRust 1.51版を指定したらデプロイできるかも(未検証)
awslabs/aws-lambda-rust-runtime: A Rust runtime for AWS Lambda
softprops/lambda-rust: 🐳 🦀 a dockerized lambda build env for rust applications
softprops/serverless-rust: ⚡ 🦀 a serverless framework plugin for rustlang applications