この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS LambdaのCustom Runtimesにより、様々な言語でLambdaファンクションを実装できるようになりました。個人的にはRustを使っていきたいと思っています(趣味です)。
RustでLambdaファンクションを実装するにあたり、Lambdaファンクションのデプロイの仕組みを整えておきたいところ。私の普段使いのデプロイツールはapexなのですが、apexは現時点でCustom Runtimesのデプロイには対応していません。このため、別のやり方としてServerless Frameworkを試してみました。
今回のエントリーではServerless Frameworkを使ってRustのLambdaファンクションをデプロイする方法をご紹介します。
目次
- 検証環境
- 前提
- 新規プロジェクト(Rustのパッケージ)作成
- Serverless FrameworkとRustプラグインのインストール
- Lambdaファンクションの作成
- Rustプログラムのコンパイル
- Serverless Frameworkの設定(serverless.yml)
- AWSのクレデンシャル
- Lambdaファンクションのデプロイ
- Lambdaファンクションの実行
- まとめ
検証環境
- macOS:Mojave(v10.14.2)
- Rust:v1.31.0
- Node.js:v11.6.0
- npm:v6.5.0
- AWS CLI:v1.16.80
- Serverless Framework :v1.35.1
- Docker Desktop Community:v2.0.0.0-mac81 DockerはRustプログラムのコンパイルで使用します。
前提
Serverless FrameworkのRustプラグインが公開されているのでこれを利用します。
テンプレートもいくつか用意されています。
今回はこれらのテンプレートを参考に、一から必要な設定ファイル等を作成していきます。
Lambdaファンクションは、DynamoDBからGetItemでデータを取得するサンプルプログラムを用意します。サンプルデータは以下のAWS公式ドキュメントのチュートリアルに付属のもの(moviedata.json)を利用します(※本ブログ記事ではDynamoDBのテーブル作成とデータロードについては触れません。必要に応じてチュートリアルの手順を参考にテーブル作成&データをロードしてください)。
新規プロジェクト(Rustのパッケージ)作成
はじめにcargo new
で新規のRustプロジェクト(Rustのパッケージ)を作成します。
cargo new dynamodb-getitem-sample --bin
Cargo.toml
とmain.rs
が作成されます。
.
├── Cargo.toml
└── src
└── main.rs
Serverless FrameworkとRustプラグインのインストール
プロジェクトディレクトリに、以下のようにpackage.json
を作成します。
package.json
{
"devDependencies": {
"serverless": "1.35.1",
"serverless-rust": "0.2.0"
}
}
npm install
でserverless
とserverless-rust
をインストールします。
$ npm install
この時点でディレクトリ構成は以下のようになります。
.
├── Cargo.toml
├── node_modules
├── package-lock.json
├── package.json
└── src
└── main.rs
Lambdaファンクションの作成
DynamoDBからGetItemでデータを取得するサンプルプログラムです。Rust用のAWS SDK(非公式)であるrusotoを使ってDynamoDBにアクセスします。
Cargo.toml
は以下のように設定します。Custom Runtimesを使用する場合、バイナリをbootstrap
という名前にする必要がありますが、このあたりはServerless FrameworkのRustプラグインがよしなにやってくれるため、Cargo.toml
でバイナリ名を明示的に指定する必要はありません。
Cargo.toml
[package]
name = "dynamodb-getitem-sample"
version = "0.1.0"
authors = ["Yutaka Yawata"]
edition = "2018"
[dependencies]
lambda_runtime = "0.1"
log = "0.4.6"
env_logger = "0.6.0"
rusoto_core = "0.36.0"
rusoto_dynamodb = "0.36.0"
serde = "1.0.84"
serde_derive = "1.0.84"
serde_json = "1.0.34"
serde_dynamodb = { git = "https://github.com/mockersf/serde_dynamodb.git", rev = "79e3dd7765574dce64a283a3ffb32f45079100b4" }
Rustプログラムのコンパイル
今回利用するServerless FrameworkのRustプラグインでは、Dockerを使ってRustプログラムをコンパイルする作りになっています。このため、手元のMac上ではクロスコンパイルの環境を整える必要はありません。
ちなみにこのDockerイメージはlambci/docker-lambdatをベースにしています。
Serverless Frameworkの設定(serverless.yml)
新規にserverless.yml
を作成し、以下のように設定します。シンプルに1つのLambdaファンクションをデプロイする設定です。Lambdaファンクションに割り当てるIAMロールには、DynamoDBのGetItem権限を追加します。
serverless.yml
service: serverlss-rust-sample
provider:
name: aws
runtime: rust
memorySize: 128
region: ap-northeast-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "dynamodb:GetItem"
Resource:
- "arn:aws:dynamodb:ap-northeast-1:*:table/Movies"
package:
individually: true
plugins:
- serverless-rust
functions:
dynamodb-getitem-sample:
handler: dynamodb-getitem-sample
runtime
にはrust
を、plugins
にserverless-rust
を指定します。functions
とhandler
には、いずれもRustのパッケージ名(ここではdynamodb-getitem-sample)を指定します。
AWSのクレデンシャル
以下を参考に設定します。基本的にはAWS CLIのそれと同じものが使えますので、Serverless Framework用の特別な設定は不要です。
Lambdaファンクションのデプロイ
serverless deploy
を実行すると、Rustプログラムのコンパイル 〜 Lambdaファンクションのデプロイが実行されます。
$ AWS_PROFILE=development npx serverless deploy --conceal
Serverless: Building native Rust dynamodb-getitem-sample func...
Finished release [optimized] target(s) in 4.87s
adding: bootstrap (deflated 61%)
Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (2.34 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...............
Serverless: Stack update finished...
Service Information
service: serverless-rust-sample
stage: dev
region: ap-northeast-1
stack: serverless-rust-sample-dev
api keys:
None
endpoints:
None
functions:
dynamodb-getitem-sample: serverless-rust-sample-dev-dynamodb-getitem-sample
layers:
None
Lambdaファンクションの実行
serverless invoke
でLambdaファンクションを実行してみます。
$ AWS_PROFILE=development npx serverless invoke -f dynamodb-getitem-sample
{
"year": 2013,
"title": "Rush",
"info": {
"plot": "A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.",
"rating": 8.3
}
}
まとめ
Serverless FrameworkとそのRustプラグインを利用することで、シングルコマンドでRustプログラムのコンパイル 〜 Lambdaファンクションのデプロイまでを実行することができます。とても便利ですね。これからRust on AWS Lambdaをいろいろ試していきたいと思います。