View a markdown version of this page

Erstellen von Rust Lambda-Funktionen mit Cargo Lambda in AWS SAM - AWS Serverless Application Model

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Erstellen von Rust Lambda-Funktionen mit Cargo Lambda in AWS SAM

Verwenden Sie die AWS Serverless Application Model Befehlszeilenschnittstelle (AWS SAMCLI) mit Ihren AWS Lambda Rust-Funktionen.

Voraussetzungen

RustSprache

Informationen zur Installation Rust finden Sie unter Installieren Rust auf der Rust Sprachwebsite.

Cargo Lambda

Das AWS SAMCLI erfordert die Installation von Cargo Lambda, einen Unterbefehl fürCargo. Anweisungen zur Installation finden Sie in der Cargo Lambda Dokumentation unter Installation.

Docker

Das Erstellen und Testen von Rust Lambda-Funktionen erfordertDocker. Installationsanweisungen finden Sie unter Installieren von Docker.

Konfigurieren AWS SAM zur Verwendung mit Rust Lambda-Funktionen

Schritt 1: Konfiguriere deine AWS SAM Vorlage

Konfigurieren Sie Ihre AWS SAM Vorlage wie folgt:

  • Binär — Optional. Geben Sie an, wenn ein einzelnes Cargo Paket mehr als eine Binärdatei definiert, um zu identifizieren, welche Binärdatei für diese Funktion erstellt werden soll. Sie benötigen diese Eigenschaft nicht, wenn es sich bei jeder Funktion um ein eigenes Cargo Paket handelt, z. B. in einem Cargo Workspace.

  • BuildMethodrust-cargolambda.

  • CodeUri— Pfad zu Ihrer Cargo.toml Datei.

  • Handler bootstrap.

  • Laufzeit provided.al2023.

Weitere Informationen zu benutzerdefinierten Laufzeiten finden Sie unter Benutzerdefinierte AWS Lambda Laufzeiten im AWS Lambda Entwicklerhandbuch.

Hier ist ein Beispiel für eine konfigurierte AWS SAM Vorlage:

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 ...

Schritt 2: Verwenden Sie die AWS SAM CLI mit deiner Rust Lambda-Funktion

Verwenden Sie einen beliebigen AWS SAMCLI Befehl mit Ihrer AWS SAM Vorlage. Weitere Informationen finden Sie unter AWS SAM CLI.

Beispiele

Beispiel „Hallo Welt“

In diesem Beispiel erstellen wir die Hello World-Beispielanwendung, die wir Rust als Laufzeit verwenden.

Zuerst initialisieren wir eine neue serverlose Anwendung mit. sam init Während des interaktiven Ablaufs wählen wir die Hello World-Anwendung aus und wählen die Rust-Laufzeit aus.

$ 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

Das Folgende ist die Struktur unserer Hello World-Anwendung:

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

In unserer AWS SAM Vorlage ist unsere Rust Funktion wie folgt definiert:

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

Als Nächstes erstellen wir sam build unsere Anwendung und bereiten uns auf die Bereitstellung vor. Das AWS SAMCLI erstellt ein .aws-sam Verzeichnis und organisiert unsere Build-Artefakte dort. Unsere Funktion wird unter Verwendung einer ausführbaren Binärdatei unter .aws-sam/build/HelloWorldFunction/bootstrap erstellt Cargo Lambda und gespeichert.

Anmerkung

Wenn Sie den sam local invoke Befehl in macOS ausführen möchten, müssen Sie vor dem Aufruf andere Funktionen erstellen. Verwenden Sie dazu den folgenden Befehl:

  • SAM_BUILD_MODE=debug sam build

Dieser Befehl wird nur benötigt, wenn lokale Tests durchgeführt werden. Dies wird beim Erstellen für die Bereitstellung nicht empfohlen.

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

Als Nächstes stellen wir unsere Anwendung mithilfe von bereitsam 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

Zum Testen können wir unsere Lambda-Funktion über den API-Endpunkt aufrufen.

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

Um unsere Funktion lokal zu testen, stellen wir zunächst sicher, dass die Architectures Eigenschaft unserer Funktion mit unserem lokalen Computer übereinstimmt.

... 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 ...

Da wir arm64 in diesem Beispiel unsere Architektur von x86_64 auf geändert haben, laufen wir los, sam build um unsere Build-Artefakte zu aktualisieren. Dann laufen wir lossam local invoke, um unsere Funktion lokal aufzurufen.

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

Einzelnes Lambda-Funktionsprojekt

Hier ist ein Beispiel für eine serverlose Anwendung, die eine Rust-Lambda-Funktion enthält.

Struktur des Projektverzeichnisses:

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

AWS SAM Vorlage:

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 ...

Projekt mit mehreren Lambda-Funktionen

Hier ist ein Beispiel für eine serverlose Anwendung, die mehrere Rust Lambda-Funktionen enthält und als Cargo Arbeitsbereich organisiert ist.

Wir empfehlen einen Cargo Arbeitsbereich für Anwendungen mit mehreren Rust Lambda-Funktionen. Jede Funktion ist ein eigenes Paket, sodass Funktionen unabhängige Abhängigkeiten deklarieren können und gleichzeitig gemeinsamen Code über ein Bibliothekspaket gemeinsam nutzen. Jedes Paket erzeugt eine einzelne Binärdatei, die nach dem Paket benannt ist, sodass Sie die Binary Build-Eigenschaft nicht festlegen müssen.

Struktur des Projektverzeichnisses:

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

Cargo.tomlWorkspace-Datei, im Stammverzeichnis des Projekts:

[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.tomlDatei für jede Funktion, z. B.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 Vorlage. Die CodeUri jeder Funktion zeigt auf das Paketverzeichnis dieser Funktion:

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
Anmerkung

Die AWS SAMCLI baut jede Funktion im Workspace in das gemeinsame target Verzeichnis des Workspace auf, Cargo kompiliert also gemeinsame Abhängigkeiten einmal statt einmal für jede Funktion. Dieses Verhalten erfordert AWS SAMCLI Version 1.165.0 oder höher. In früheren Versionen wurde jede Funktion in einem eigenen target Verzeichnis erstellt und der vollständige Abhängigkeitsbaum wird für jede Funktion neu kompiliert, wodurch Builds langsamer werden, wenn Sie Funktionen hinzufügen.

Geben Sie jedem Funktionspaket einen eindeutigen Binärnamen. Paketnamen sind innerhalb eines Arbeitsbereichs eindeutig, sodass der Standard-Binärname bereits eindeutig ist. Wenn Sie den Binärnamen mit einem [[bin]] Abschnitt überschreiben, geben Sie nicht zwei Paketen denselben Binärnamen. Sie kompilieren auf denselben Pfad im gemeinsam genutzten target Verzeichnis und überschreiben sich gegenseitig. Das AWS SAMCLI protokolliert eine Warnung, wenn es dies feststellt.

Alternativ kann ein einzelnes Paket mehrere Binärdateien definieren. Verwenden Sie in diesem Fall die Eigenschaft Binary build, um die Binärdatei für jede Funktion auszuwählen:

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

Die Optimierung von Rust-Builds ist eingebaut GitHub Aktionen

Rust-Builds sind rechenintensiv, und ein Continuous Integration Runner beginnt ohne kompilierte Artefakte. Anwendungen mit mehreren Funktionen, die große Abhängigkeiten gemeinsam haben, wie z. B. an AWSSDK, können die meiste Zeit ihrer Build-Zeit damit verbringen, dieselben Abhängigkeiten zu kompilieren. Die folgenden Methoden reduzieren die Build-Zeit inGitHub Actions.

Verwenden Sie AWS SAMCLI Version 1.165.0 oder höher für Arbeitsbereiche

Version 1.165.0 und höher bauen jedes Mitglied eines Cargo Workspace in das gemeinsame target Verzeichnis des Workspace ein, sodass gemeinsame Abhängigkeiten einmal pro Build kompiliert werden und nicht einmal für jede Funktion. Geben Sie bei der Installation von die Mindestversion an, AWS SAMCLI damit ein Build nicht stillschweigend auf das langsamere Verhalten zurückfällt.

Zwischenspeichern Sie die Cargo Registrierung und target das Verzeichnis

Zwischenspeichern Sie die Cargo Registrierung (~/.cargo/registryund~/.cargo/git/db) und das target Workspace-Verzeichnis zwischen den Ausführungen, sodass unveränderte Abhängigkeiten wiederhergestellt und nicht neu kompiliert werden. Verwenden Sie für jedes Kompilierungsziel einen separaten Cache. Ein Job, für den Release-Artefakte übergreifend kompiliert werden, arm64 erzeugt andere Artefakte als ein Job, für den nativ kompiliert wird. Ein gemeinsam genutzter x86_64 Cache passt also nie zusammen.

Fügen Sie Build-Einstellungen in den Cache-Schlüssel ein

Cargoschließt Einstellungen wie opt-level und codegen-units in den Fingerabdruck ein, anhand dessen entschieden wird, ob ein kompiliertes Artefakt wiederverwendet werden kann. Wenn Sie den [profile.release] Abschnitt Ihrer Cargo.toml Workspace-Datei ändern, ohne den Cache-Schlüssel zu ändern, wird der Cache wiederhergestellt, aber trotzdem wird jede Crate neu kompiliert. Füge einen Hash der Cargo.toml Workspace-Datei in den Cache-Schlüssel ein, sodass beim Ändern einer Profileinstellung ein neuer Cache gestartet wird.

Übermitteln Sie Ihre Cargo.lock Datei

Lambda-Funktionen sind ausführbar, also übergeben Sie Ihre Datei. Cargo.lock Dadurch erhalten Sie reproduzierbare Builds und einen stabilen Cache-Schlüssel, der sich nur ändert, wenn sich Ihre Abhängigkeiten ändern.

Passen Sie das Release-Profil an die Build-Zeit und den Kaltstart an

Ihr Funktionscode wird bei jedem Lauf neu kompiliert, da er sich häufiger ändert als Ihre Abhängigkeiten. Das Standard-Release-Profil optimiert den Laufzeitdurchsatz, den viele Lambda-Funktionen nicht benötigen. Durch die Optimierung der Größe werden kleinere Binärdateien erzeugt, was auch die Kaltstartzeit erleichtert, und eine Erhöhung der Anzahl der Codegenerierungseinheiten erhöht die Parallelität bei der Kompilierung. Lassen Sie die Linkzeitoptimierung (lto) deaktiviert, da dies die Kompilierung verlangsamt. Füge deiner Cargo.toml Workspace-Datei Folgendes hinzu:

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

Messen Sie den Effekt in Ihrer eigenen Anwendung. Bei diesen Einstellungen wird ein kleiner Teil der Laufzeitleistung gegen die Build-Zeit und die Binärgröße eingetauscht.

Vermeiden Sie doppelte Workflow-Ausführungen

Ein Workflow, der push sowohl für Ereignisse als auch für pull_request Ereignisse ausgeführt wird, wird zweimal für denselben Commit ausgeführt. GitHub ActionsCaches sind nach Branch- und Pull-Requests aufgeteilt, sodass die beiden Läufe in unterschiedliche Cache-Bereiche schreiben und keiner der beiden den Cache des anderen wiederverwendet. Verwenden Sie eine Parallelitätsgruppe, die im Head-Commit eingegeben wird, sodass nur ein Durchlauf jeden Commit erstellt.

Der folgende Workflow erstellt einen Cargo Arbeitsbereich mit Rust Lambda-Funktionen für die oben genannten arm64 Praktiken und wendet sie an:

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

Der restore-keys Eintrag ermöglicht es, einen Lauf mit dem neuesten Cache zu starten, wenn der Schlüssel nicht genau übereinstimmt, sodass bei einer Änderung der Abhängigkeit die Crates, die sich nicht geändert haben, wiederverwendet werden, anstatt alles erneut zu kompilieren.