4
0

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.

Lambda+Rustのデプロイメントをコンテナイメージと.zipファイルアーカイブの両方で試す

Last updated at Posted at 2021-09-09

##はじめに
表題の通りです。
SAM CLIからカスタムランタイムを使ってLambdaをデプロイの設定情報を作っていたのですが、ImageとZipどちらがいいのかわからずどちらも試しました。
今後どちらも選択的に使えるようにまとめておきます。

##Zip
####構成

lambda_rust
  ├──.aws-sam
  ├──samconfig.yaml
  ├──stock_data
  |  ├──Cargo.lock
  |  ├──Cargo.toml
  |  ├──Makefile
  |  └──src/main.rs
  └──template.yaml

####設定

template.toml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Sample rust application for Lambda
  
Resources:
  HelloRustFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloRust
      Role: arn:aws:iam::{Lambdaを実行するロール}
      PackageType: Zip
      CodeUri: ./stock_data
      Runtime: provided.al2 # Amazon Linux 2
      Handler: bootstrap.is.real.handler
    Metadata:
      BuildMethod: makefile
Makefile
build-HelloRustFunction:
	cargo build --release --target x86_64-unknown-linux-musl

	# バイナリをbootstrapにして、Artifacts Directoryに格納する
	# Current Artifacts Directory : /workspace/stock_data/.aws-sam/build/HelloRustFunction
	cp ./target/x86_64-unknown-linux-musl/release/hello /workspace/stock_data/.aws-sam/build/HelloRustFunction/bootstrap
samconfig.toml
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "{ストック名}"
s3_bucket = "{デプロイする先のS3バケット名}"
region = "ap-northeast-1"
confirm_changeset = false
capabilities = ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
Cargo.toml
[package]
name = "stock_data"
version = "0.1.0"
authors = ["***** <****@****>"]
edition = "2018"

[dependencies]
lambda_runtime = "0.4"
lambda_http = "0.4.0"
serde_json = "1.0.59"
tokio = "1.11.0"

[[bin]]
name = "hello"
path = "src/main.rs"
main.rs
use lambda_runtime::{handler_fn, Context, Error};
use serde_json::{json, Value};

// エントリポイント
// Lambda特有のものを集約させる
#[tokio::main]
async fn main() -> Result<(), Error> {
    let func = handler_fn(my_handler);
    lambda_runtime::run(func).await?;
    Ok(())
}

async fn my_handler(event: Value, _: Context) -> Result<Value, Error> {
    let first_name = event["firstName"].as_str().unwrap_or("world");

    Ok(json!({ "message": format!("Hello, {}!", first_name) }))
}

#[cfg(test)]
mod tests {
    use super::*;

    //async関数は#[test]では使用できない
    //#[test]
    #[tokio::test]
    async fn my_handler_response() -> Result<(), Error> {
        let event = json!({
            "firstName": "AWS Lambda on Rust"
        });
        let json = json!({
            "message": "Hello, AWS Lambda on Rust!",
        });
        let response = my_handler(event, Context::default()).await?;
        assert_eq!(response, json);
        Ok(())
    }
}

####参考情報
AWS公式ブログがRust Runtime for AWSで書いています。makefileは使われていません。

こちらの資料、長いですが、219ページ目あたりからの方がブログより参考になりそう

かなり参考にさせていただきました。makefileを利用し、かつ複数関数のデプロイが行われています。

##Image
####構成

lambda_rust
  ├──.aws-sam
  ├──samconfig.yaml
  ├──stock_data
  |  ├──Cargo.lock
  |  ├──Cargo.toml
  |  ├──Dockerfile # Zipとの相違点
  |  └──src/main.rs
  └──template.yaml

####設定

template.toml(Function名も変えていますが変える必要はないです)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Sample rust application for Lambda
  
Resources:
  HelloRustFunctionImage:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloRustImage
      Role: arn:aws:iam::{Lambdaを実行するロール}
      MemorySize: 512
      CodeUri: ./stock_data             # Zipとの相違点
      PackageType: Image                   # Zipとの相違点
      #Runtime: provided.al2      # Zipとの相違点
      #Handler: bootstrap.is.real.handler # Zipとの相違点
    Metadata:
      Dockerfile: Dockerfile           # Zipとの相違点
      DockerContext: ./stock_data # Zipとの相違点
      DockerTag: v1                             # Zipとの相違点
Dockerfile
FROM rust:latest as build-image

WORKDIR /rust/stock_data
COPY src/ /rust/stock_data/src/
COPY Cargo.toml Cargo.lock /rust/stock_data/

RUN rustup update && \
    rustup target add x86_64-unknown-linux-musl
RUN cargo build --release --target x86_64-unknown-linux-musl

FROM public.ecr.aws/lambda/provided:al2

# 実行ファイルを起動するようにするため、ファイル名を "bootstrap" に変更する
COPY  --from=build-image /rust/stock_data/target/x86_64-unknown-linux-musl/release/hello ${LAMBDA_RUNTIME_DIR}/bootstrap

# カスタムランタイムはハンドラ名利用しないため、適当な文字列を指定する。
CMD [ "lambda-handler" ]
samconfig.toml
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "{ストック名}"
s3_bucket = "{デプロイする先のS3バケット名}"
image_repository = "{ImageをpushするECRのリポジトリ}" # Zipとの相違点
region = "ap-northeast-1"
confirm_changeset = false
capabilities = ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
Cargo.toml
# Zipと相違ないため略
main.rs
// Zipと相違ないため略

####参考情報
情報収集していて、Lambda+Rust+Imageでのデプロイは少ないように感じました。

一番参考にしたのは、AWS Toolkit for Visual Studio Codeのgo-imageのテンプレートでした。
VS CodeでコマンドではなくToolkitを使ってLambda関数を作成するとテンプレートとしてサンプルのhelloworldが生成されます。以下はそのテンプレートのgithubソースです。ビルドファイルをアップする必要があるRustにおいて、同じくビルドファイルを作成するGolangのtemplate.yamlDockerfile書き方は非常に参考になりました。

プログラムビルドとビルドファイルを埋め込んだImageの作成を分けられていますが、RustでImageデプロイしている貴重な情報。

Lambdaのカスタムランタイム イメージの構成や環境変数まわりの確認に利用

##余談
実は、これを試す前はDockerfileでかけるImageの方がデプロイ環境が把握しやすいのでImage派でした。
Zipを試してみたきっかけは、コンソールでソースが見れるのはZipという表示を見かけたからです。

Imageではソースをコンソール上からは見ることができない。
スクリーンショット 2021-09-09 14.28.53.png

RustのZipをデプロイして、コンソールを確認してみました。
スクリーンショット 2021-09-09 14.29.23.png
かなしい。

##おわりに
Zipでやりたかったコンソール上でのソースコードは見れませんでしたが、今後もZipで進めようと思います。
理由としては、Imageの場合(私の手順の場合)、Cargo build用にコンテナを立ちあげてデプロイする手順がありますが、私はVSCodeからコンテナに接続しその中でSAMを入れています。SAM実行にてさらにコンテナの中でコンテナが起動してCargo buildし、さらにもう一つコンテナを立ち上げてビルドファイルをコピーするという、SAMを実行しているコンテナと合わせて4つ同時にコンテナが起動します。実行時MacBookAirが数回死にました。
また、Zip手順ではsam buildを実行するとSAMを入れている環境、つまり私の場合だと開発環境のコンテナ内でCargo buildが行われますが、Imageでは、「SAM実行にてさらにコンテナの中でコンテナが起動してCargo build」の手順と完全に同じ事をしているに、コンテナが1つ余計に立ち上がるというデメリットしかないです。
もちろんその部分をMakefileに移し、最終的なビルドファイルの処理だけを切り替えればこれらのデメリットは無くなると思いますが、あまりにPCが死に過ぎてもうImageを試す気になれないのでZipで行こうと思います。
もう少しカスタムランタイム の中に持ち込みたい素材が増えてきたら変わってくる気がしますが、それまではZipで行こうと思います。

4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?