2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS Lambda を Rust で実装して Serverless Framework でデプロイするまで

Last updated at Posted at 2021-01-11

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<dyn StdError>> {
        lambda!(handler);
        Ok(())
    }
    
    fn handler(
        event: CustomEvent,
        _context: Context,
    ) -> Result<CustomOutput, HandlerError> {
        Ok(CustomOutput {
            message: format!("Hello, {}!", event.first_time),
        })
    }
    
  • 手元でビルドをしてみる。ビルドには softprops/lambda-rust の Docker イメージを利用する

    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
    
  • ビルドとデプロイのコマンドは先程と同じ。

    • 複数の関数は関連した関数としてデプロイされる。

参考資料

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?