

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Cargo Lambda中使用 建置 Rust Lambda 函數 AWS SAM
<a name="building-rust"></a>


|  | 
| --- |
| 此功能目前為 的預覽版本 AWS SAM ，可能會有所變更。 | 

使用 AWS Serverless Application Model 命令列界面 (AWS SAM CLI) 搭配 Rust AWS Lambda 函數。

**Topics**
+ [先決條件](#building-rust-prerequisites)
+ [設定 AWS SAM 搭配 Rust Lambda 函數使用](#building-rust-configure)
+ [範例](#building-rust-examples)

## 先決條件
<a name="building-rust-prerequisites"></a>

**Rust 語言**  
若要安裝 Rust，請參閱*Rust語言網站*中的[安裝Rust](https://www.rust-lang.org/tools/install)。

**Cargo Lambda**  
 AWS SAM CLI 需要安裝 [https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html)，這是 的子命令Cargo。如需安裝說明，請參閱 *Cargo Lambda 文件*中的[安裝](https://www.cargo-lambda.info/guide/installation.html)。

**Docker**  
建置和測試 Rust Lambda 函數需要 Docker。如需安裝指示，請參閱[安裝 Docker](install-docker.md)。

**選擇加入 AWS SAM CLI Beta 版功能**  
由於此功能處於預覽狀態，您必須使用下列其中一種方法選擇加入：  

1. 使用環境變數：`SAM_CLI_BETA_RUST_CARGO_LAMBDA=1`。

1. 將以下內容新增到您的 `samconfig.toml` 檔案：

   ```
   [default.build.parameters]
   beta_features = true
   [default.sync.parameters]
   beta_features = true
   ```

1. 使用支援的 AWS SAM CLI命令時，請使用 `--beta-features`選項。例如：

   ```
   $ sam build --beta-features
   ```

1. 當 提示您選擇加入`y`時 AWS SAM CLI，請選擇選項。以下是範例：

   ```
   $ sam build
   Starting Build use cache
   Build method "rust-cargolambda" is a beta feature.
   Please confirm if you would like to proceed
   You can also enable this beta feature with "sam build --beta-features". [y/N]: y
   ```

## 設定 AWS SAM 搭配 Rust Lambda 函數使用
<a name="building-rust-configure"></a>

### 步驟 1：設定您的 AWS SAM 範本
<a name="building-rust-configure-template"></a>

使用下列項目設定您的 AWS SAM 範本：
+ **二進位** – 選用。指定您的範本何時包含多個 Rust Lambda 函數。
+ **BuildMethod** – `rust-cargolambda`。
+ **CodeUri** – `Cargo.toml` 檔案的路徑。
+ **處理常**式 – `bootstrap`。
+ **執行時間** – `provided.al2`。

若要進一步了解自訂執行期，請參閱《 *AWS Lambda 開發人員指南*》中的[自訂 AWS Lambda 執行期](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html)。

以下是已設定 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.al2
...
```

### 步驟 2：搭配 Rust Lambda 函數使用 AWS SAM CLI
<a name="building-rust-configure-cli"></a>

將任何 AWS SAM CLI命令與 AWS SAM 範本搭配使用。如需詳細資訊，請參閱[AWS SAM CLI](using-sam-cli.md)。

## 範例
<a name="building-rust-examples"></a>

### Hello World 範例
<a name="building-rust-examples-hello"></a>

**在此範例中，我們使用 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 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 22

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.al2)
    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.al2
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
            Path: /hello
            Method: get
```

接下來，我們會執行 `sam build`來建置應用程式並準備部署。 AWS SAM CLI 會建立`.aws-sam`目錄，並在其中組織我們的建置成品。我們的函數是使用 建置，Cargo Lambda並存放在 做為可執行的二進位檔`.aws-sam/build/HelloWorldFunction/bootstrap`。

**注意**  
如果您打算在 MacOS 中執行 **sam local invoke**命令，則需要在叫用之前建置不同的函數。若要執行此作業，請使用下列命令：  
**SAM\$1BUILD\$1MODE=debug sam build**
只有在完成本機測試時，才需要此命令。建置 以進行部署時，不建議這麼做。

```
hello-rust$ sam build
Starting Build use cache
Build method "rust-cargolambda" is a beta feature.
Please confirm if you would like to proceed
You can also enable this beta feature with "sam build --beta-features". [y/N]: y

Experimental features are enabled for this session.
Visit the docs page to learn more about the AWS Beta terms https://aws.amazon.com/service-terms/.

Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../hello-rust/rust_app runtime: provided.al2 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.al2
      Architectures:
        - arm64
...
```

由於我們在此範例中`arm64`將架構從 修改`x86_64`為 ，因此我們執行 `sam build`來更新建置成品。然後，我們會執行 `sam local invoke`以本機叫用函數。

```
hello-rust$ 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-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 函數專案
<a name="building-rust-examples-single"></a>

**以下是包含一個 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.al2
...
```

### 多個 Lambda 函數專案
<a name="building-rust-examples-multiple"></a>

**以下是包含多個 Rust Lambda 函數的無伺服器應用程式範例。**

專案目錄結構：

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

AWS SAM 範本：

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

`Cargo.toml` 檔案：

```
[package]
name = "test-handler"
version = "0.1.0"
edition = "2021"

[dependencies]
lambda_runtime = "0.6.0"
serde = "1.0.136"
tokio = { version = "1", features = ["macros"] }
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }

[[bin]]
name = "function_a"
path = "src/function_a.rs"

[[bin]]
name = "function_b"
path = "src/function_b.rs"
```