Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Création de fonctions Rust Lambda avec Cargo Lambda in AWS SAM
Utilisez l'interface de ligne de AWS Serverless Application Model commande (AWS SAMCLI) avec vos AWS Lambda fonctions Rust.
Rubriques
Conditions préalables
- Langage Rust
-
Pour installer Rust, consultez la section Installer Rust
sur le site web du langage Rust. - Cargo Lambda
-
La CLI AWS SAM nécessite l'installation de Cargo Lambda
, une sous-commande pour Cargo. Pour les instructions d'installation, consultez la rubrique Installation dans la documentation Cargo Lambda. - Docker
-
La création et le test de fonctions Lambda Rust nécessitent Docker. Pour obtenir des instructions d’installation, consultez Installation de Docker.
Configuration AWS SAM à utiliser avec les fonctions Rust Lambda
Étape 1 : Configurez votre AWS SAM modèle
Configurez votre AWS SAM modèle à l'aide des éléments suivants :
-
Binaire : facultatif. Spécifiez quand un seul Cargo package définit plus d'un binaire, afin d'identifier le binaire à créer pour cette fonction. Vous n'avez pas besoin de cette propriété lorsque chaque fonction est son propre Cargo package, par exemple dans un Cargo espace de travail.
-
BuildMethod –
rust-cargolambda. -
CodeUri— chemin d'accès à votre
Cargo.tomlfichier. -
Gestionnaire :
bootstrap. -
Exécution :
provided.al2023.
Pour en savoir plus sur les environnements d'exécution personnalisés, consultez la section AWS Lambda Runtimes personnalisés dans le Guide du AWS Lambda développeur.
Voici un exemple de AWS SAM modèle configuré :
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 ...
Étape 2 : utilisez AWS SAM INTERFACE DE LIGNE DE COMMANDE (CLI) avec votre fonction Rust Lambda
Utilisez n'importe quelle AWS SAMCLI commande avec votre AWS SAM modèle. Pour de plus amples informations, veuillez consulter AWS SAM CLI.
Exemples
Exemple Hello World
Dans cet exemple, nous créons l'exemple d'application Hello World en utilisant Rust comme notre exécution.
Tout d'abord, nous initialisons une nouvelle application sans serveur en utilisant sam init. Au cours du flux interactif, nous sélectionnons l'application Hello World et choisissons l'exécution Rust.
$sam init... Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice:1Choose an AWS Quick Start application template 1 - Hello World Example 2 - Multi-step workflow 3 - Serverless API ... Template:1Use the most popular runtime and package type? (Python and zip) [y/N]:ENTERWhich 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:24Based 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]:ENTERWould 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]:ENTERProject 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
Voici la structure de notre application Hello World :
hello-rust ├── README.md ├── events │ └── event.json ├── rust_app │ ├── Cargo.toml │ └── src │ └── main.rs ├── samconfig.toml └── template.yaml
Dans notre AWS SAM modèle, notre Rust fonction est définie comme suit :
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
Ensuite, nous exécutons sam build pour créer notre application et préparer son déploiement. La CLI AWS SAM crée un répertoire .aws-sam et organise nos artefacts de création. Notre fonction est construite en utilisant Cargo Lambda et stockée sous forme de binaire exécutable à l'emplacement suivant : .aws-sam/build/HelloWorldFunction/bootstrap.
Note
Si vous envisagez d'exécuter la sam local invoke commande sous macOS, vous devez créer des fonctions différentes avant de l'appeler. Pour ce faire, utilisez la commande suivante :
SAM_BUILD_MODE=debug sam build
Cette commande n'est nécessaire que si des tests locaux doivent être effectués. Cela n'est pas recommandé lors de la création en vue du déploiement.
hello-rust$sam buildStarting 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
Ensuite, nous déployons notre application en utilisant sam deploy --guided.
hello-rust$sam deploy --guidedConfiguring SAM deploy ====================== Looking for config file [samconfig.toml] : Found Reading default arguments : Success Setting default arguments for 'sam deploy' ========================================= Stack Name [hello-rust]:ENTERAWS 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]:ENTERHelloWorldFunction may not have authorization defined, Is this okay? [y/N]:ySave arguments to configuration file [Y/n]:ENTERSAM configuration file [samconfig.toml]:ENTERSAM configuration environment [default]:ENTERLooking 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]:y2023-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
Pour tester, nous pouvons appeler notre fonction Lambda à l'aide du point de terminaison de l'API.
$curl https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/Hello World!%
Pour tester notre fonction localement, nous devons d'abord nous assurer que la propriété Architecturesde notre fonction correspond à notre ordinateur local.
... 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 ...
Comme nous avons modifié notre architecture en passant de x86_64 à arm64 dans cet exemple, nous exécutons sam build pour mettre à jour nos artefacts de création. Nous exécutons ensuite sam local invoke pour appeler notre fonction localement.
hello-rust$sam local invokeInvoking 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
Projet de fonction Lambda unique
Voici un exemple d'application sans serveur contenant une fonction Lambda Rust.
Structure du répertoire du projet :
. ├── Cargo.lock ├── Cargo.toml ├── src │ └── main.rs └── template.yaml
AWS SAM modèle :
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 ...
Projet de fonctions Lambda multiples
Voici un exemple d'application sans serveur contenant plusieurs fonctions Rust Lambda, organisées comme un Cargo espace de travail.
Nous recommandons un Cargo espace de travail pour les applications dotées de plusieurs fonctions Rust Lambda. Chaque fonction est son propre package, de sorte que les fonctions peuvent déclarer des dépendances indépendantes tout en partageant du code commun via un package de bibliothèque. Chaque package produit un fichier binaire unique nommé d'après le package, vous n'avez donc pas besoin de définir la propriété Binary build.
Structure du répertoire du projet :
. ├── Cargo.lock ├── Cargo.toml ├── function_a │ ├── Cargo.toml │ └── src │ └── main.rs ├── function_b │ ├── Cargo.toml │ └── src │ └── main.rs └── template.yaml
Cargo.tomlFichier de l'espace de travail, à la racine du projet :
[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.tomlfichier pour chaque fonction, tel que 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 modèle. Le CodeUri de chaque fonction pointe vers le répertoire du package de cette fonction :
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
Note
AWS SAMCLIConstruit chaque fonction de l'espace de travail dans le target répertoire partagé de l'espace de travail, Cargo compile donc les dépendances partagées une fois au lieu d'une pour chaque fonction. Ce comportement nécessite AWS SAMCLI la version 1.165.0 ou ultérieure. Dans les versions précédentes, chaque fonction était créée dans son propre target répertoire et l'arbre de dépendances complet était recompilé pour chaque fonction, ce qui ralentissait les compilations au fur et à mesure que vous ajoutiez des fonctions.
Attribuez à chaque package de fonctions un nom binaire unique. Les noms de packages sont uniques dans un espace de travail, de sorte que le nom binaire par défaut est déjà unique. Si vous remplacez le nom binaire par une [[bin]] section, ne donnez pas le même nom binaire à deux packages. Ils se compilent sur le même chemin dans le target répertoire partagé et s'écrasent les uns les autres. Le AWS SAMCLI journal enregistre un avertissement lorsqu'il le détecte.
Alternativement, un seul package peut définir plusieurs fichiers binaires. Dans ce cas, utilisez la propriété Binary build pour sélectionner le binaire de chaque fonction :
Resources: FunctionA: Type: AWS::Serverless::Function Metadata: BuildMethod: rust-cargolambda BuildProperties: Binary: function_a Properties: CodeUri: ./ Handler: bootstrap Runtime: provided.al2023
L'optimisation des builds de Rust GitHub Actions
Les builds Rust sont gourmands en ressources de calcul et un lanceur d'intégration continue démarre sans aucun artefact compilé. Les applications dotées de plusieurs fonctions qui partagent de grandes dépendances, comme un AWSSDK, peuvent passer la majeure partie de leur temps de construction à compiler les mêmes dépendances. Les pratiques suivantes permettent de réduire le temps d'intégrationGitHub Actions.
- Utilisez AWS SAMCLI la version 1.165.0 ou ultérieure pour les espaces de travail
-
Les versions 1.165.0 et ultérieures intègrent chaque membre d'un Cargo espace de travail dans le
targetrépertoire partagé de l'espace de travail, de sorte que les dépendances partagées sont compilées une fois par build au lieu d'une fois pour chaque fonction. Spécifiez la version minimale lorsque vous installez le AWS SAMCLI afin qu'une compilation ne revienne pas silencieusement au comportement le plus lent. - Mettre en cache le Cargo registre et le
targetrépertoire -
Mettez en cache le Cargo registre (
~/.cargo/registryet~/.cargo/git/db) et letargetrépertoire de l'espace de travail entre les exécutions, afin que les dépendances inchangées soient restaurées au lieu d'être recompilées. Utilisez un cache distinct pour chaque cible de compilation. Une tâche qui compile des artefacts de version de manière croiséearm64produit des artefacts différents de ceux d'une tâche pour laquelle la compilation est nativex86_64, de sorte qu'un cache partagé ne correspond jamais. - Inclure les paramètres de génération dans la clé de cache
-
Cargoinclut des paramètres tels que
opt-leveletcodegen-unitsdans l'empreinte digitale qu'il utilise pour décider si un artefact compilé peut être réutilisé. Si vous modifiez la[profile.release]section de votreCargo.tomlfichier d'espace de travail sans modifier la clé de cache, le cache est restauré mais chaque caisse est quand même recompilée. Incluez un hachage duCargo.tomlfichier de l'espace de travail dans la clé de cache afin que la modification d'un paramètre de profil ouvre un nouveau cache. - Validez votre
Cargo.lockfichier -
Les fonctions Lambda sont des exécutables, alors validez votre fichier.
Cargo.lockCela vous donne des versions reproductibles et une clé de cache stable qui ne change que lorsque vos dépendances changent. - Réglez le profil de version pour le temps de construction et le démarrage à froid
-
Le code de votre fonction est recompilé à chaque exécution, car il change plus souvent que vos dépendances. Le profil de version par défaut optimise le débit d'exécution, dont de nombreuses fonctions Lambda n'ont pas besoin. L'optimisation de la taille produit des fichiers binaires plus petits, ce qui réduit également le temps de démarrage à froid, et l'augmentation du nombre d'unités de génération de code augmente le parallélisme lors de la compilation. Laissez l'optimisation du temps de liaison (
lto) désactivée, car cela ralentit la compilation. Ajoutez les éléments suivants à votreCargo.tomlfichier d'espace de travail :[profile.release] opt-level = "s" codegen-units = 256 lto = false strip = trueMesurez l'effet sur votre propre application. Ces paramètres échangent une petite partie des performances d'exécution en termes de temps de génération et de taille binaire.
- Évitez les exécutions de flux de travail en double
-
Un flux de travail qui s'exécute à la fois sur les
pull_requestévénementspushet sur les événements s'exécute deux fois pour le même commit. GitHub Actionsles caches sont délimités par branche et par requête d'extraction, de sorte que les deux exécutions écrivent dans des étendues de cache différentes et aucune ne réutilise le cache de l'autre. Utilisez un groupe de simultanéité saisi sur le commit principal, de sorte qu'une seule exécution génère chaque commit.
Le flux de travail suivant crée un Cargo espace de travail composé de fonctions Rust Lambda pour arm64 et applique les pratiques précédentes :
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
L'restore-keysentrée permet de démarrer à partir du cache le plus récent lorsque la clé ne correspond pas exactement, de sorte qu'un changement de dépendance réutilise les caisses qui n'ont pas changé au lieu de tout compiler à nouveau.