View a markdown version of this page

Cargo Lambda で を使用して Rust Lambda 関数を構築する AWS SAM - AWS Serverless Application Model

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Cargo Lambda で を使用して Rust Lambda 関数を構築する AWS SAM

Rust AWS Lambda 関数で AWS Serverless Application Model コマンドラインインターフェイス (AWS SAM CLI) を使用します。

前提条件

Rust 言語

Rust をインストールするには、Rust 言語ウェブサイトの「Rust をインストールする」を参照してください。

Cargo Lambda

AWS SAM CLI では、Cargo のサブコマンドである Cargo Lambda のインストールが必要です。インストール手順については、「Cargo Lambda ドキュメント」で「Installation」を参照してください。

Docker

Rust Lambda 関数の構築とテストには Docker が必要です。インストール手順については、「Docker のインストール」を参照してください。

Rust Lambda 関数で使用する AWS SAM ための の設定

ステップ 1: AWS SAM テンプレートを設定する

以下を使用して AWS SAM テンプレートを設定します。

  • Binary – オプション。1 つのCargoパッケージが複数のバイナリを定義するタイミングを指定して、この関数用に構築するバイナリを特定します。Cargo ワークスペースなど、各関数が独自のCargoパッケージである場合、このプロパティは必要ありません。

  • BuildMethodrust-cargolambda

  • CodeUriCargo.toml ファイルへのパス。

  • Handlerbootstrap

  • Runtimeprovided.al2023

カスタムランタイムの詳細については、「 AWS Lambda デベロッパーガイド」の「カスタム AWS Lambda ランタイム」を参照してください。

設定済み AWS SAM テンプレートの例を次に示します。

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 ... Resources: MyFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda BuildProperties: function_a Properties: CodeUri: ./rust_app Handler: bootstrap Runtime: provided.al2023 ...

ステップ 2: Rust Lambda 関数で AWS SAM CLI を使用する

AWS SAM テンプレートで任意の AWS SAM CLIコマンドを使用します。詳細については、「AWS SAM CLI」を参照してください。

Hello World の例

この例では、ランタイムとして Rust を使用してサンプルの Hello World アプリケーションを構築します。

まず、sam init を使用して新しいサーバーレスアプリケーションを初期化します。インタラクティブフロー中に、[Hello World アプリケーション] を選択し、[Rust] ランタイムを選択します。

$ sam init ... Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 Choose an AWS Quick Start application template 1 - Hello World Example 2 - Multi-step workflow 3 - Serverless API ... Template: 1 Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER Which runtime would you like to use? 1 - dotnet8 2 - dotnet6 3 - go (provided.al2) ... 18 - python3.11 19 - python3.10 20 - ruby4.0 21 - ruby3.3 22 - ruby3.2 23 - rust (provided.al2) 24 - rust (provided.al2023) Runtime: 24 Based on your selections, the only Package type available is Zip. We will proceed to selecting the Package type as Zip. Based on your selections, the only dependency manager available is cargo. We will proceed copying the template using cargo. Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: ENTER 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 Project name [sam-app]: hello-rust ----------------------- Generating application: ----------------------- Name: hello-rust Runtime: rust (provided.al2023) Architectures: x86_64 Dependency Manager: cargo Application Template: hello-world Output Directory: . Configuration file: hello-rust/samconfig.toml Next steps can be found in the README file at hello-rust/README.md Commands you can use next ========================= [*] Create pipeline: cd hello-rust && sam pipeline init --bootstrap [*] Validate SAM template: cd hello-rust && sam validate [*] Test Function in the Cloud: cd hello-rust && sam sync --stack-name {stack-name} --watch

Hello World アプリケーションの構造を次に示します。

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

AWS SAM テンプレートでは、Rust関数は次のように定義されます。

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 ... Resources: HelloWorldFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda Properties: CodeUri: ./rust_app Handler: bootstrap Runtime: provided.al2023 Architectures: - x86_64 Events: HelloWorld: Type: Api Properties: Path: /hello Method: get

次に、sam build を実行してアプリケーションを構築し、デプロイの準備をします。 AWS SAM CLI は .aws-sam ディレクトリを作成し、そこにビルドアーティファクトを整理します。関数は Cargo Lambda を使用して構築され、実行可能バイナリとして .aws-sam/build/HelloWorldFunction/bootstrap に保存されます。

注記

MacOS で sam local invoke コマンドを実行する予定がある場合は、呼び出す前に関数を別の方法で構築する必要があります。これを行うには、次のコマンドを使用します。

  • SAM_BUILD_MODE=debug sam build

このコマンドは、ローカルテストが行われる場合にのみ必要です。これは、デプロイ用に構築する場合は推奨されません。

hello-rust$ sam build Starting Build use cache Cache is invalid, running build and copying resources for following functions (HelloWorldFunction) Building codeuri: /Users/.../hello-rust/rust_app runtime: provided.al2023 metadata: {'BuildMethod': 'rust-cargolambda'} architecture: x86_64 functions: HelloWorldFunction Running RustCargoLambdaBuilder:CargoLambdaBuild Running RustCargoLambdaBuilder:RustCopyAndRename Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Validate SAM template: sam validate [*] Invoke Function: sam local invoke [*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch [*] Deploy: sam deploy --guided

次に、sam deploy --guided を使用してアプリケーションをデプロイします。

hello-rust$ sam deploy --guided 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 Looking for resources needed for deployment: ... Uploading to hello-rust/56ba6585d80577dd82a7eaaee5945c0b 817973 / 817973 (100.00%) Deploying with following values =============================== Stack name : hello-rust Region : us-west-2 Confirm changeset : True Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisam-s3-demo-bucket-1a4x26zbcdkqr Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to hello-rust/a4fc54cb6ab75dd0129e4cdb564b5e89.template 1239 / 1239 (100.00%) Waiting for changeset to be created.. CloudFormation stack changeset --------------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement --------------------------------------------------------------------------------------------------------- + Add HelloWorldFunctionHelloW AWS::Lambda::Permission N/A orldPermissionProd ... --------------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:us-west-2:012345678910:changeSet/samcli-deploy1681427201/f0ef1563-5ab6-4b07-9361-864ca3de6ad6 Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: y 2023-04-13 13:07:17 - Waiting for stack create/update to complete CloudFormation events from stack operations (refresh every 5.0 seconds) --------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason --------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation ... --------------------------------------------------------------------------------------------------------- CloudFormation outputs from deployed stack --------------------------------------------------------------------------------------------------------- Outputs --------------------------------------------------------------------------------------------------------- Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::012345678910:role/hello-rust-HelloWorldFunctionRole-10II2P13AUDUY Key HelloWorldApi Description API Gateway endpoint URL for Prod stage for Hello World function Value https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/ Key HelloWorldFunction Description Hello World Lambda Function ARN Value arn:aws:lambda:us-west-2:012345678910:function:hello-rust-HelloWorldFunction- yk4HzGzYeZBj --------------------------------------------------------------------------------------------------------- Successfully created/updated stack - hello-rust in us-west-2

テストするには、API エンドポイントを使用して Lambda 関数を呼び出します。

$ curl https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/ Hello World!%

関数をローカルでテストするには、まず関数の Architectures プロパティがローカルマシンと一致するようにします。

... 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.al2023 Architectures: - arm64 ...

この例ではアーキテクチャを x86_64 から arm64 に変更したため、ビルドアーティファクトを更新するために sam build を実行します。その後、ローカルで関数を呼び出すために sam local invoke を実行します。

hello-rust$ sam local invoke Invoking bootstrap (provided.al2023) Local image was not found. Removing rapid images for repo public.ecr.aws/sam/emulation-provided.al2023 Building image..................................................................................................................................... Using local image: public.ecr.aws/lambda/provided:al2023-rapid-arm64. Mounting /Users/.../hello-rust/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6 Version: $LATEST {"statusCode":200,"body":"Hello World!"}END RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6 REPORT RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6 Init Duration: 0.68 ms Duration: 130.63 ms Billed Duration: 131 ms Memory Size: 128 MB Max Memory Used: 128 MB

単一 Lambda 関数プロジェクト

1 つの Rust Lambda 関数を含むサーバーレスアプリケーションの例を次に示します。

プロジェクトのディレクトリ構造:

.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── main.rs
└── template.yaml

AWS SAM テンプレート:

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 ... Resources: MyFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda Properties: CodeUri: ./ Handler: bootstrap Runtime: provided.al2023 ...

複数の Lambda 関数プロジェクト

Cargoワークスペースとして整理された複数の Rust Lambda 関数を含むサーバーレスアプリケーションの例を次に示します。

複数の Rust Lambda 関数を持つアプリケーションにはCargoワークスペースをお勧めします。各関数は独自のパッケージであるため、関数はライブラリパッケージを介して共通コードを共有しながら、独立した依存関係を宣言できます。各パッケージはパッケージにちなんで という名前の単一のバイナリを生成するため、Binaryビルドプロパティを設定する必要はありません。

プロジェクトのディレクトリ構造:

.
├── Cargo.lock
├── Cargo.toml
├── function_a
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── function_b
│   ├── Cargo.toml
│   └── src
│       └── main.rs
└── template.yaml

プロジェクトのルートにある Workspace Cargo.toml ファイル:

[workspace] resolver = "2" members = [ "function_a", "function_b", ] [workspace.dependencies] lambda_runtime = "0.13" serde = { version = "1", features = ["derive"] } tokio = { version = "1", features = ["macros", "rt"] }

Cargo.toml など、各関数の ファイルfunction_a/Cargo.toml:

[package] name = "function_a" version = "0.1.0" edition = "2021" [dependencies] lambda_runtime = { workspace = true } serde = { workspace = true } tokio = { workspace = true }

AWS SAM テンプレート。各関数CodeUriの は、その関数のパッケージディレクトリを指します。

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 ... Resources: FunctionA: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda Properties: CodeUri: ./function_a Handler: bootstrap Runtime: provided.al2023 FunctionB: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda Properties: CodeUri: ./function_b Handler: bootstrap Runtime: provided.al2023
注記

はワークスペース内のすべての関数をワークスペースの共有targetディレクトリに AWS SAM CLI構築するため、 は関数ごとに 1 回ではなく、共有依存関係を 1 回Cargoコンパイルします。この動作には、バージョン 1.165.0 以降が必要です AWS SAM CLI。以前のバージョンでは、各関数は独自のtargetディレクトリに構築され、すべての関数に対して完全な依存関係ツリーが再コンパイルされるため、関数を追加するとビルドが遅くなります。

各関数パッケージに一意のバイナリ名を付けます。パッケージ名はワークスペース内で一意であるため、デフォルトのバイナリ名は既に一意です。バイナリ名を[[bin]]セクションで上書きする場合は、2 つのパッケージに同じバイナリ名を付けないでください。共有targetディレクトリ内の同じパスにコンパイルされ、相互に上書きされます。は、これを検出すると警告を AWS SAM CLIログに記録します。

または、1 つのパッケージで複数のバイナリを定義することもできます。この場合、Binaryビルドプロパティを使用して、各関数のバイナリを選択します。

Resources: FunctionA: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda BuildProperties: Binary: function_a Properties: CodeUri: ./ Handler: bootstrap Runtime: provided.al2023

での Rust ビルドの最適化 GitHub Actions

Rust ビルドは計算負荷が高く、継続的インテグレーションランナーはコンパイルされたアーティファクトなしで始まります。など、大きな依存関係を共有する複数の関数を持つアプリケーションは AWS SDK、ビルド時間のほとんどを同じ依存関係のコンパイルに費やすことができます。以下のプラクティスは、 のビルド時間を短縮しますGitHub Actions。

ワークスペースに AWS SAM CLIバージョン 1.165.0 以降を使用する

バージョン 1.165.0 以降では、Cargoワークスペースのすべてのメンバーがワークスペースの共有targetディレクトリにビルドされるため、共有依存関係は、関数ごとに 1 回ではなく、ビルドごとに 1 回コンパイルされます。をインストールする AWS SAM CLIときに最小バージョンを指定し、ビルドが低速の動作にサイレントにフォールバックしないようにします。

Cargo レジストリとtargetディレクトリをキャッシュする

実行の合間にCargoレジストリ (~/.cargo/registry~/.cargo/git/db) とワークスペースtargetディレクトリをキャッシュして、変更されていない依存関係が再コンパイルされるのではなく復元されるようにします。コンパイルターゲットごとに個別のキャッシュを使用します。のリリースアーティファクトをクロスコンパイルするジョブは、 用にネイティブにコンパイルするジョブとは異なるアーティファクトarm64を生成するためx86_64、共有キャッシュが一致しません。

キャッシュキーにビルド設定を含める

Cargo には、コンパイルされたアーティファクトを再利用できるかどうかを判断するために使用するフィンガープリントcodegen-unitsopt-levelや などの設定が含まれています。キャッシュキーを変更せずにワークスペースCargo.tomlファイルの [profile.release]セクションを変更すると、キャッシュは復元されますが、いずれのクレートも再コンパイルされます。プロファイル設定を変更すると新しいキャッシュが開始されるように、キャッシュキーにワークスペースCargo.tomlファイルのハッシュを含めます。

Cargo.lock ファイルをコミットする

Lambda 関数は実行可能ファイルであるため、Cargo.lockファイルをコミットします。これにより、再現性のあるビルドと、依存関係が変更された場合にのみ変化する安定したキャッシュキーが得られます。

ビルド時間とコールドスタートに合わせてリリースプロファイルを調整する

関数コードは、依存関係よりも頻繁に変更されるため、実行のたびに再コンパイルされます。デフォルトのリリースプロファイルは、多くの Lambda 関数が不要なランタイムスループットを最適化します。サイズに合わせて最適化するとバイナリが小さくなり、コールドスタート時間にも役立ち、コード生成ユニットの数を増やすとコンパイル中の並列性が向上します。リンク時間の最適化 (lto) は、コンパイルが遅くなるため、無効にしておきます。ワークスペースCargo.tomlファイルに以下を追加します。

[profile.release] opt-level = "s" codegen-units = 256 lto = false strip = true

独自のアプリケーションへの影響を測定します。これらの設定は、ビルド時間とバイナリサイズに少量のランタイムパフォーマンスをトレードします。

ワークフロー実行の重複を回避する

push と の両方のpull_requestイベントで実行されるワークフローは、同じコミットに対して 2 回実行されます。 GitHub Actionsキャッシュはブランチリクエストとプルリクエストによってスコープされるため、2 つの実行は異なるキャッシュスコープに書き込み、もう 1 つのキャッシュは再利用されません。ヘッドコミットでキー指定された同時実行グループを使用して、各コミットをビルドする実行が 1 つだけになるようにします。

次のワークフローは、 の Rust Lambda 関数のCargoワークスペースを構築しarm64、前述のプラクティスを適用します。

name: Build on: push: branches: [main] pull_request: # Collapse the push and pull_request runs for the same commit into a single run. concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.head.sha || github.sha }} cancel-in-progress: true jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@stable with: targets: aarch64-unknown-linux-gnu # Cache the Cargo registry and the workspace target directory. The key covers # the compilation target, Cargo.lock, and the workspace Cargo.toml, so that # changing a dependency or a release profile setting starts a new cache # instead of restoring one whose artifacts Cargo discards. - uses: actions/cache@v4 with: path: | ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db target key: cargo-arm64-${{ hashFiles('Cargo.lock', 'Cargo.toml') }} restore-keys: | cargo-arm64- - name: Install build tools run: pip install cargo-lambda 'aws-sam-cli>=1.165.0' - name: Build run: sam build

restore-keys エントリを使用すると、キーが完全に一致しないときに最新のキャッシュから実行を開始できるため、依存関係の変更により、すべてを再度コンパイルする代わりに、変更されなかった木箱が再利用されます。