🦀

Rust Lambda 関数を AWS SAM を使って Hello World してみる

2023/07/17に公開

Cargo Lambda を使用した Rust Lambda 関数の構築 を参考に、何もわからん状態で Linux 環境から Cargo Lambda を使って Rust Lambda 関数構築してみた、備忘録。
基本的にドキュメントに従っているだけです


前提条件

  • Rust 言語のインストール

Rust をインストール に書いてあるとおり、素直に rustup を使ってインストールする。下のコマンド打つだけ

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • AWS SAM のインストール

Cargo Lambda は AWS SAM CLI から動かすらしい、 AWS SAM って何?と思ったらこんな感じらしい。

AWS サーバーレスアプリケーションモデル (SAM、Serverless Application Model) は、サーバーレスアプリケーション構築用のオープンソースフレームワークです。迅速に記述可能な構文で関数、API、データベース、イベントソースマッピングを表現できます。リソースごとにわずか数行で、任意のアプリケーションを定義して YAML を使用してモデリングできます。デプロイ中、SAM が SAM 構文を AWS CloudFormation 構文に変換および拡張することで、サーバーレスアプリケーションの構築を高速化することができます。

インストールは AWS SAM から SAM CLI をインストールする に従えば良さそう

  • Homebrew のインストール

Cargo Lambda をインストールするには Linux でも Homebrew を使うらしい、 apt にパッケージあれ、と思ったけれど仕方ないのでインストールします

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

実行後の Next steps も忘れずに

(echo; echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"') >> /home/ユーザ名/.profile
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
sudo apt-get install build-essential # sudo アクセス権限がある場合
brew install gcc
  • Zig のインストール

Cargo Lambda は Zig 使ってるらしい、 rust だけで完結してほしい
Homebrew 入れたので brew から入れる

brew install zig
  • やっと Cargo Lambda のインストール

Installation 通りにやる。
brew コマンド打つだけ

brew tap cargo-lambda/cargo-lambda
brew install cargo-lambda
  • Docker

コンテナでテストとデプロイできるらしい
AWS SAM CLI で Docker を使用するためのインストール方法

Docker はマシン上でコンテナを実行するアプリケーションです。Docker を使用すると、サーバーレスアプリケーションを構築、テスト、デバッグできるコンテナとしての AWS Lambda に近いローカル環境を AWS SAM で利用できます。

Docker 手順が長いのと、いろんなリファレンスあるから割愛

  • AWS SAM CLI ベータ機能にオプトインする

この機能はプレビュー段階にあるため、次のいずれかの方法を使用してオプトインする必要があります。

  1. 次の環境変数を使用します: SAM_CLI_BETA_RUST_CARGO_LAMBDA=1。
  2. 次のコードを samconfig.toml ファイルに追加します。
[default.build.parameters]
beta_features = true
[default.sync.parameters]
beta_features = true

環境汚したくないから samconfig.toml に追加することにする。
samcomnfig.toml って何だ?と思ったけれど、どうやら sam アプリケーション作るときの設定ファイルみたいなやつ、後でやる


Hello World アプリの構築

環境構築が終わったので、 Hello World してみる。

任意のディレクトリで以下のコマンドを実行

sam init

テンプレートを使うか聞かれるので、テンプレートを使う(1を選択)

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

どのテンプレートを使うか聞かれるので Hello world Example を選択

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        ...
Template: 1

Pythonパッケージ使う?って聞かれるので無視

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

どのランタイムを使うか聞かれるので、21 rust を選択

Which runtime would you like to use?
        1 - aot.dotnet7 (provided.al2)
        2 - dotnet6
        3 - dotnet5.0
        ...
        18 - python3.7
        19 - python3.10
        20 - ruby2.7
        21 - rust (provided.al2)
Runtime: 21

X-Ray トレーシングを使うか聞かれるので、無視

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

AWS X-Ray はアプリケーションが処理するリクエストに関するデータを収集するサービスです。データを表示、フィルタリング、洞察を取得して問題の識別や最適化の機会を識別するために使用するツールを提供します。

CloudWatch APplication Insights使うか聞かれるので、無視

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

CloudWatch Application Insights は、他のアプリケーションリソースとともに Amazon EC2 インスタンスを使用するアプリケーションをモニターリングするのに役立ちます。

プロジェクト名に好きな名前を入れる

Project name [sam-app]: hello-rust

完了するとアプリケーションの雛形が作成できている

hello-rust/
├── README.md
├── events
│   └── event.json
├── rust_app
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── samconfig.toml
└── template.yaml

ここのsamconfig.tomlに前提条件の設定を追記すればいいんだな

[default.build.parameters]
cached = true
parallel = true
beta_features = true
...
[default.sync.parameters]
watch = true
beta_features = true 

これでひとまず hello-world できるようになったはず、build してみる
(コンテナのフェッチに時間)

cd hello-rust
sam build --beta-features

deploy してみる

hello-rust$ sam deploy --guided

色々聞かれるが、authorization が定義されてないけどいい?のところを Yes にする以外は Enter で大丈夫そう

HelloWorldFunction may not have authorization defined, Is this okay? [y/N]:y
Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [hello-rust]: ENTER
        AWS Region [us-west-2]: ENTER
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [Y/n]: ENTER
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: ENTER
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: ENTER
        HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: ENTER
        SAM configuration file [samconfig.toml]: ENTER
        SAM configuration environment [default]: ENTER

待ってると、CloudFormation changeset が作成されるので、これでデプロイしていいか?に対してYesを選択

Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: 

待っているとデプロイが終わって、Lambda に関数が作成されてる
API Gateway も作ってもらえてる

API Gateway から呼び出してみる

curl https://*****.execute-api.<region>.amazonaws.com/Prod/hello
Hello World!

ローカルで関数をテストしてみる。
必要に応じてtemplate.yamlArchitecturesを自分のローカルマシンと一致するように変更する

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Metadata:
      BuildMethod: rust-cargolambda # More info about Cargo Lambda: https://github.com/cargo-lambda/cargo-lambda
    Properties:
      CodeUri: ./rust_app   # Points to dir of Cargo.toml
      Handler: bootstrap    # Do not change, as this is the default executable name produced by Cargo Lambda
      Runtime: provided.al2
      Architectures:
        - x86_64
sam local invoke

Invoking bootstrap (provided.al2)                                               
Local image was not found.                                                      
Removing rapid images for repo public.ecr.aws/sam/emulation-provided.al2        
Building image..............................................
Using local image: public.ecr.aws/lambda/provided:al2-rapid-x86_64.             
                                                                                
Mounting                                                                        
/path/to/application/hello-rust/.aws-sam/build/HelloWorldFuncti
on as /var/task:ro,delegated, inside runtime container                          
START RequestId: 1657b857-3687-4c92-a177-0ba971160680 Version: $LATEST
END RequestId: 1657b857-3687-4c92-a177-0ba971160680
REPORT RequestId: 1657b857-3687-4c92-a177-0ba971160680	Init Duration: 0.12 ms	Duration: 2.51 ms	Billed Duration: 3 ms	Memory Size: 128 MB	Max Memory Used: 128 MB	
{"statusCode":200,"body":"Hello World!"}

まとめ

  • Cargo Lambda を使って Rust Lambda 関数をデプロイした
  • cargo-lambda の場合 sam build --use-containerだと失敗して、sam build --beta-featuresらしい ( 裏ではDocker動いてるっぽい)
  • 結構かんたんに色々やってくれて助かる
  • hello world だと味気ないので、なにか引数を使った処理を試したいですね

Discussion