View a markdown version of this page

Creación de funciones de Rust Lambda con Cargo Lambda in AWS SAM - AWS Serverless Application Model

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Creación de funciones de Rust Lambda con Cargo Lambda in AWS SAM

Utilice la interfaz de línea de AWS Serverless Application Model comandos (AWS SAMCLI) con sus AWS Lambda funciones de Rust.

Requisitos previos

Lenguaje Rust

Para instalar Rust, consulta Instalar Rust en el sitio web del lenguaje Rust.

Cargo Lambda

La CLI de AWS SAM requiere la instalación de Cargo Lambda, un subcomando para Cargo. Para obtener instrucciones sobre la instalación, consulta Instalación en la Documentación de Cargo Lambda.

Docker

Para crear y probar funciones de Lambda Rust es necesario disponer de Docker. Para obtener las instrucciones de instalación, consulta Instalar Docker.

Configuración AWS SAM para usar con las funciones de Rust Lambda

Paso 1: Configure su AWS SAM plantilla

Configure su AWS SAM plantilla con lo siguiente:

  • Binario: opcional. Especifique cuándo un solo Cargo paquete define más de un binario para identificar qué binario crear para esta función. No necesitas esta propiedad cuando cada función es su propio Cargo paquete, como en un Cargo espacio de trabajo.

  • BuildMethodrust-cargolambda.

  • CodeUri— ruta a tu Cargo.toml archivo.

  • Controlador: bootstrap.

  • Tiempo de ejecución: provided.al2023.

Para obtener más información sobre los tiempos de ejecución personalizados, consulte los tiempos de AWS Lambda ejecución personalizados en la Guía para AWS Lambda desarrolladores.

Este es un ejemplo de una plantilla configurada 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 ...

Paso 2: Usa el AWS SAM CLI con su función Lambda de Rust

Usa cualquier AWS SAMCLI comando con tu AWS SAM plantilla. Para obtener más información, consulte AWS SAM CLI.

Ejemplos

Ejemplo de Hello World

En este ejemplo, creamos la aplicación de muestra Hello World usando Rust como nuestro tiempo de ejecución.

En primer lugar, inicializamos una nueva aplicación sin servidor utilizando sam init. Durante el flujo interactivo, seleccionamos la aplicación Hello World y elegimos el tiempo de ejecución de 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

La siguiente es la estructura de nuestra aplicación Hello World:

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

En nuestra AWS SAM plantilla, nuestra Rust función se define de la siguiente manera:

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

A continuación, ejecuta sam build para crear e implementar la aplicación. La CLI de AWS SAM crea un directorio de .aws-sam y organiza allí nuestros artefactos de construcción. Nuestra función se crea utilizando Cargo Lambda y se almacena como un archivo binario ejecutable en .aws-sam/build/HelloWorldFunction/bootstrap.

nota

Si planea ejecutar el comando sam local invoke en macOS, tiene que crear funciones diferentes antes de la invocación. Para ello, utilice el siguiente comando:

  • SAM_BUILD_MODE=debug sam build

Este comando solo es necesario si se van a realizar pruebas locales. No se recomienda al compilar para la implementación.

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

A continuación, implementamos nuestra aplicación usando 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

Para realizar las pruebas, podemos invocar nuestra función de Lambda mediante el punto de conexión de la API.

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

Para probar nuestra función localmente, primero nos aseguramos de que la propiedad Architectures de nuestra función coincida con nuestro equipo 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 ...

Como ya modificamos nuestra arquitectura de x86_64 a arm64 en este ejemplo, ejecutamos sam build para actualizar nuestros artefactos de construcción. A continuación, ejecutamos sam local invoke para invocar nuestra función de forma local.

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

Proyecto de función de Lambda única

Este es un ejemplo de una aplicación sin servidor que contiene una función Rust de Lambda.

Estructura del directorio del proyecto:

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

AWS SAM plantilla:

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

Proyecto de función de Lambda múltiple

Este es un ejemplo de una aplicación sin servidor que contiene varias funciones de Rust Lambda, organizadas como un Cargo espacio de trabajo.

Recomendamos un Cargo espacio de trabajo para aplicaciones con varias funciones de Rust Lambda. Cada función es su propio paquete, por lo que las funciones pueden declarar dependencias independientes mientras comparten código común a través de un paquete de biblioteca. Cada paquete produce un único binario con el nombre del paquete, por lo que no es necesario establecer la propiedad de Binary compilación.

Estructura del directorio del proyecto:

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

Cargo.tomlArchivo de espacio de trabajo, en la raíz del proyecto:

[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.tomlarchivo para cada función, comofunction_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 plantilla. La CodeUri de cada función apunta al directorio de paquetes de esa función:

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
nota

AWS SAMCLICompila todas las funciones del espacio de trabajo en el target directorio compartido del espacio de trabajo, por lo que Cargo compila las dependencias compartidas una vez en lugar de una para cada función. Este comportamiento requiere la AWS SAMCLI versión 1.165.0 o posterior. En las versiones anteriores, cada función se compila en su propio target directorio y se vuelve a compilar el árbol de dependencias completo para cada función, lo que hace que las compilaciones sean más lentas a medida que se agregan funciones.

Asigne a cada paquete de funciones un nombre binario único. Los nombres de los paquetes son únicos en un espacio de trabajo, por lo que el nombre binario predeterminado ya es único. Si reemplaza el nombre binario con una [[bin]] sección, no asigne a dos paquetes el mismo nombre binario. Se compilan en la misma ruta del target directorio compartido y se sobrescriben entre sí. AWS SAMCLIRegistra una advertencia cuando lo detecta.

Como alternativa, un solo paquete puede definir varios binarios. En ese caso, usa la propiedad Binary build para seleccionar el binario de cada función:

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

La optimización de Rust incorpora GitHub Acciones

Las compilaciones de Rust requieren un uso intensivo de cómputos y un ejecutor de integración continua comienza sin artefactos compilados. Las aplicaciones con varias funciones que comparten grandes dependencias, como una AWSSDK, pueden dedicar la mayor parte del tiempo de creación a compilar las mismas dependencias. Las siguientes prácticas reducen el tiempo de compilación. GitHub Actions

Usa AWS SAMCLI la versión 1.165.0 o posterior para los espacios de trabajo

La versión 1.165.0 y posteriores compilan todos los miembros de un Cargo espacio de trabajo en el target directorio compartido del espacio de trabajo, por lo que las dependencias compartidas se compilan una vez por compilación en lugar de una para cada función. Especifica la versión mínima al instalarla AWS SAMCLI para que una compilación no vuelva a tener un comportamiento más lento de forma silenciosa.

Almacene en caché el Cargo registro y el directorio target

Almacene en caché el Cargo registro (~/.cargo/registryy~/.cargo/git/db) y el target directorio del espacio de trabajo entre ejecuciones, de modo que las dependencias que no hayan cambiado se restauren en lugar de volver a compilarse. Utilice una caché independiente para cada destino de compilación. Un trabajo que compila de forma cruzada artefactos de versión para los que arm64 produce artefactos distintos a los de un trabajo para el que compila de forma nativax86_64, por lo que una caché compartida nunca coincide.

Incluye la configuración de compilación en la clave de caché

Cargoincluye ajustes como opt-level y codegen-units en la huella digital que utiliza para decidir si un artefacto compilado se puede reutilizar. Si cambias la [profile.release] sección del Cargo.toml archivo de espacio de trabajo sin cambiar la clave de caché, la caché se restaura, pero todas las cajas se vuelven a compilar de todos modos. Incluye un hash del Cargo.toml archivo de espacio de trabajo en la clave de caché para que al cambiar la configuración de un perfil se inicie una nueva caché.

Confirme su Cargo.lock archivo

Las funciones de Lambda son ejecutables, así que confirme Cargo.lock el archivo. Esto le proporciona compilaciones reproducibles y una clave de caché estable que solo cambia cuando cambian sus dependencias.

Ajusta el perfil de versión según el tiempo de compilación y el arranque en frío

El código de la función se vuelve a compilar en cada ejecución, ya que cambia con más frecuencia que las dependencias. El perfil de versión predeterminado optimiza el rendimiento del tiempo de ejecución, algo que muchas funciones de Lambda no necesitan. Al optimizar el tamaño, se obtienen binarios más pequeños, lo que también contribuye al tiempo de arranque en frío, y el aumento del número de unidades de generación de código aumenta el paralelismo durante la compilación. Deje la optimización del tiempo de enlace (lto) desactivada, ya que hace que la compilación sea más lenta. Agregue lo siguiente a su Cargo.toml archivo de espacio de trabajo:

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

Mida el efecto en su propia aplicación. Estas configuraciones intercambian una pequeña cantidad de rendimiento en tiempo de ejecución por tiempo de compilación y tamaño binario.

Evite ejecutar flujos de trabajo duplicados

Un flujo de trabajo que se ejecute en ambos pull_request eventos push y que se ejecute dos veces para la misma confirmación. GitHub Actionslas cachés se clasifican por rama y solicitud de extracción, por lo que las dos ejecuciones escriben en diferentes ámbitos de caché y ninguna reutiliza la caché de la otra. Usa un grupo de simultaneidad que tenga una clave en la confirmación principal, de modo que solo una ejecución genere cada confirmación.

El siguiente flujo de trabajo crea un Cargo espacio de trabajo con funciones de Rust Lambda para las arm64 prácticas anteriores y las aplica:

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

La restore-keys entrada permite que una ejecución comience desde la caché más reciente cuando la clave no coincide exactamente, de modo que un cambio de dependencia reutiliza las cajas que no cambiaron en lugar de volver a compilar todo.