MCPcopy Index your code
hub / github.com/aws/aws-lambda-rust-runtime

github.com/aws/aws-lambda-rust-runtime @lambda_runtime-v1.2.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release lambda_runtime-v1.2.1 ↗ · + Follow
1,512 symbols 2,522 edges 194 files 127 documented · 8%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Rust Runtime for AWS Lambda

Build Status

This package makes it easy to run AWS Lambda Functions written in Rust. This workspace includes multiple crates:

  • Docs lambda-runtime is a library that provides a Lambda runtime for applications written in Rust.
  • Docs lambda-http is a library for writing HTTP Lambda functions in Rust, with support for upstream API Gateway, ALB, Lambda Function URLs, and VPC Lattice.
  • Docs lambda-extension is a library that makes it easy to write Lambda Runtime Extensions in Rust.
  • Docs lambda-events is a library with strongly-typed Lambda event structs in Rust.
  • Docs lambda-runtime-api-client is a shared library between the lambda runtime and lambda extension libraries that includes a common API client to talk with the AWS Lambda Runtime API.

Getting started

The easiest way to start writing Lambda functions with Rust is by using Cargo Lambda, a related project. Cargo Lambda is a Cargo plugin, or subcommand, that provides several commands to help you in your journey with Rust on AWS Lambda.

The preferred way to install Cargo Lambda is by using a package manager.

1- Use Homebrew on MacOS:

brew tap cargo-lambda/cargo-lambda
brew install cargo-lambda

2- Use Scoop on Windows:

scoop bucket add cargo-lambda https://github.com/cargo-lambda/scoop-cargo-lambda
scoop install cargo-lambda/cargo-lambda

Or PiP on any system with Python 3 installed:

pip3 install cargo-lambda

Alternatively, you can install the pip package as an executable using uv

uv tool install cargo-lambda

See other installation options in the Cargo Lambda documentation.

Your first function

To create your first function, run Cargo Lambda with the subcommand new. This command will generate a Rust package with the initial source code for your function:

cargo lambda new YOUR_FUNCTION_NAME

Example function

If you'd like to manually create your first function, the code below shows you a simple function that receives an event with a firstName field and returns a message to the caller.

```rust,no_run use lambda_runtime::{service_fn, LambdaEvent, Error}; use serde_json::{json, Value};

[tokio::main]

async fn main() -> Result<(), Error> { let func = service_fn(func); lambda_runtime::run(func).await?; Ok(()) }

async fn func(event: LambdaEvent) -> Result { let (event, _context) = event.into_parts(); let first_name = event["firstName"].as_str().unwrap_or("world");

Ok(json!({ "message": format!("Hello, {}!", first_name) }))

}


## Understanding Lambda errors

when a function invocation fails, AWS Lambda expects you to return an object that can be serialized into JSON structure with the error information. This structure is represented in the following example:

```json
{
  "error_type": "the type of error raised",
  "error_message": "a string description of the error"
}

The Rust Runtime for Lambda uses a struct called Diagnostic to represent function errors internally. The runtime implements the conversion of several general error types, like std::error::Error, into Diagnostic. For these general implementations, the error_type is the name of the value type returned by your function. For example, if your function returns lambda_runtime::Error, the error_type will be something like alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>, which is not very descriptive.

Implement your own Diagnostic

To get more descriptive error_type fields, you can implement From for your error type. That gives you full control on what the error_type is:

use lambda_runtime::{Diagnostic, Error, LambdaEvent};

#[derive(Debug)]
struct ErrorResponse(&'static str);

impl From<ErrorResponse> for Diagnostic {
    fn from(error: ErrorResponse) -> Diagnostic {
        Diagnostic {
            error_type: "MyErrorType".into(),
            error_message: error.0.to_string(),
        }
    }
}

async fn handler(_event: LambdaEvent<()>) -> Result<(), ErrorResponse> {
  Err(ErrorResponse("this is an error response"))
}

We recommend you to use the thiserror crate to declare your errors. You can see an example on how to integrate thiserror with the Runtime's diagnostics in our example repository

Anyhow, Eyre, and Miette

Popular error crates like Anyhow, Eyre, and Miette provide their own error types that encapsulate other errors. There is no direct transformation of those errors into Diagnostic, but we provide feature flags for each one of those crates to help you integrate them with your Lambda functions.

If you enable the features anyhow, eyre, or miette in the lambda_runtime dependency of your package. The error types provided by those crates can have blanket transformations into Diagnostic. These features expose an From<T> for Diagnostic implementation that transforms those error types into a Diagnostic. This is an example that transforms an anyhow::Error into a Diagnostic:

use lambda_runtime::{Diagnostic, LambdaEvent};

async fn handler(_event: LambdaEvent<Request>) -> Result<(), Diagnostic> {
  Err(anyhow::anyhow!("this is an error").into())
}

You can see more examples on how to use these error crates in our example repository.

Graceful shutdown

lambda_runtime offers a helper to simplify configuring graceful shutdown signal handling, spawn_graceful_shutdown_handler(). This requires the graceful-shutdown feature flag and only supports Unix systems.

You can use it by passing a FnOnce closure that returns an async block. That async block will be executed when the function receives a SIGTERM or SIGKILL.

Note that this helper is opinionated in a number of ways. Most notably: 1. It spawns a task to drive your signal handlers 2. It registers a 'no-op' extension in order to enable graceful shutdown signals 3. It panics on unrecoverable errors

If you prefer to fine-tune the behavior, refer to the implementation of spawn_graceful_shutdown_handler() as a starting point for your own.

For more information on graceful shutdown handling in AWS Lambda, see: aws-samples/graceful-shutdown-with-aws-lambda.

Complete example (cleaning up a non-blocking tracing writer):

```rust,no_run use lambda_runtime::{service_fn, LambdaEvent, Error}; use serde_json::{json, Value};

[tokio::main]

async fn main() -> Result<(), Error> { let func = service_fn(func);

let (writer, log_guard) = tracing_appender::non_blocking(std::io::stdout());
lambda_runtime::tracing::init_default_subscriber_with_writer(writer);

let shutdown_hook = || async move {
  std::mem::drop(log_guard);
};
lambda_runtime::spawn_graceful_shutdown_handler(shutdown_hook).await;

lambda_runtime::run(func).await?;
Ok(())

}

async fn func(event: LambdaEvent) -> Result { let (event, _context) = event.into_parts(); let first_name = event["firstName"].as_str().unwrap_or("world");

Ok(json!({ "message": format!("Hello, {}!", first_name) }))

}


## Building and deploying your Lambda functions

If you already have Cargo Lambda installed in your machine, run the next command to build your function:

```bash
cargo lambda build --release

There are other ways of building your function: manually with the AWS CLI, with AWS SAM, and with the Serverless framework.

1. Cross-compiling your Lambda functions

By default, Cargo Lambda builds your functions to run on x86_64 architectures. If you'd like to use a different architecture, use the options described below.

1.1. Build your Lambda functions

Amazon Linux 2023

We recommend you to use the Amazon Linux 2023 (such as provided.al2023) because it includes a newer version of GLIBC, which many Rust programs depend on. To build your Lambda functions for Amazon Linux 2023 runtimes, run:

cargo lambda build --release --arm64

2. Deploying the binary to AWS Lambda

For a custom runtime, AWS Lambda looks for an executable called bootstrap in the deployment package zip. Rename the generated executable to bootstrap and add it to a zip archive.

You can find the bootstrap binary for your function under the target/lambda directory.

2.1. Deploying with Cargo Lambda

Once you've built your code with one of the options described earlier, use the deploy subcommand to upload your function to AWS:

cargo lambda deploy

Warning Make sure to replace the execution role with an existing role in your account!

This command will create a Lambda function with the same name of your rust package. You can change the name of the function by adding the argument at the end of the command:

cargo lambda deploy my-first-lambda-function

Note See other deployment options in the Cargo Lambda documentation.

You can test the function with the invoke subcommand:

cargo lambda invoke --remote \
  --data-ascii '{"command": "hi"}' \
  --output-format json \
  my-first-lambda-function

Note CLI commands in the examples use Linux/MacOS syntax. For different shells like Windows CMD or PowerShell, modify syntax when using nested quotation marks like '{"command": "hi"}'. Escaping with a backslash may be necessary. See AWS CLI Reference for more information.

2.2. Deploying with the AWS CLI

You can also use the AWS CLI to deploy your Rust functions. First, you will need to create a ZIP archive of your function. Cargo Lambda can do that for you automatically when it builds your binary if you add the output-format flag:

cargo lambda build --release --arm64 --output-format zip

You can find the resulting zip file in target/lambda/YOUR_PACKAGE/bootstrap.zip. Use that file path to deploy your function with the AWS CLI:

$ aws lambda create-function --function-name rustTest \
  --handler bootstrap \
  --zip-file fileb://./target/lambda/basic/bootstrap.zip \
  --runtime provided.al2023 \ # Change this to provided.al2 if you would like to use Amazon Linux 2
  --role arn:aws:iam::XXXXXXXXXXXXX:role/your_lambda_execution_role \
  --environment Variables={RUST_BACKTRACE=1} \
  --tracing-config Mode=Active

Warning Make sure to replace the execution role with an existing role in your account!

You can now test the function using the AWS CLI or the AWS Lambda console

$ aws lambda invoke
  --cli-binary-format raw-in-base64-out \
  --function-name rustTest \
  --payload '{"command": "Say Hi!"}' \
  output.json
$ cat output.json  # Prints: {"msg": "Command Say Hi! executed."}

Note --cli-binary-format raw-in-base64-out is a required argument when using the AWS CLI version 2. More Information

2.3. AWS Serverless Application Model (SAM)

You can use Lambda functions built in Rust with the AWS Serverless Application Model (SAM). To do so, you will need to install the AWS SAM CLI, which will help you package and deploy your Lambda functions in your AWS account.

You will need to create a template.yaml file containing your desired infrastructure in YAML. Here is an example with a single Lambda function:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      MemorySize: 128
      Architectures: ["arm64"]
      Handler: bootstrap
      Runtime: provided.al2023
      Timeout: 5
      CodeUri: target/lambda/basic/

Outputs:
  FunctionName:
    Value: !Ref HelloWorldFunction
    Description: Name of the Lambda function

You can then deploy your Lambda function using the AWS SAM CLI:

sam deploy --guided

At the end, sam will output the actual Lambda function name. You can use this name to invoke your function:

$ aws lambda invoke
  --cli-binary-format raw-in-base64-out \
  --function-name HelloWorldFunction-XXXXXXXX \ # Replace with the actual function name
  --payload '{"command": "Say Hi!"}' \
  output.json
$ cat output.json  # Prints: {"msg": "Command Say Hi! executed."}

Local development and testing

Testing your code with unit and integration tests

AWS Lambda events are plain structures de

Extension points exported contracts — how you extend this code

IntoResponse (Interface)
Trait for generating responses Types that implement this trait can be used as return types for handler functions. [13 …
lambda-http/src/response.rs
IntoFunctionResponse (Interface)
a trait that can be implemented for any type that can be converted into a FunctionResponse. This allows us to use the `i [3 …
lambda-runtime/src/types.rs
ConfigurationFetcher (Interface)
(no doc) [2 implementers]
examples/advanced-appconfig-feature-flags/src/appconfig.rs
GetFile (Interface)
(no doc) [1 implementers]
examples/basic-s3-object-lambda-thumbnail/src/s3.rs
GetFile (Interface)
(no doc) [1 implementers]
examples/basic-s3-thumbnail/src/s3.rs
ListObjects (Interface)
(no doc) [1 implementers]
examples/basic-sdk/src/main.rs
RequestExt (Interface)
Extensions for [`lambda_http::Request`], `http::request::Parts`, and `http::Extensions` structs that provide access to [ [3 …
lambda-http/src/ext/extensions.rs
IntoRequest (Interface)
(no doc) [3 implementers]
lambda-runtime/src/requests.rs

Core symbols most depended-on inside this repo

build
called by 66
lambda-runtime-api-client/src/lib.rs
from_str
called by 43
lambda-http/src/request.rs
init_default_subscriber
called by 41
lambda-runtime-api-client/src/tracing.rs
run
called by 36
lambda-http/src/lib.rs
clone
called by 33
lambda-runtime/src/layers/api_client.rs
uri
called by 29
lambda-extension/src/requests.rs
into_parts
called by 24
lambda-runtime/src/types.rs
collect
called by 22
lambda-runtime-api-client/src/body/mod.rs

Shape

Function 627
Class 574
Method 238
Enum 60
Interface 13

Languages

Rust99%
TypeScript1%
Python1%

Modules by API surface

lambda-events/src/event/cognito/mod.rs87 symbols
lambda-events/src/event/apigw/mod.rs64 symbols
lambda-http/src/request.rs50 symbols
lambda-http/src/ext/request.rs38 symbols
lambda-http/src/ext/extensions.rs35 symbols
lambda-runtime/src/types.rs33 symbols
lambda-runtime/src/runtime.rs32 symbols
lambda-events/src/event/controltower/mod.rs32 symbols
lambda-http/src/response.rs27 symbols
lambda-extension/src/extension.rs25 symbols
lambda-events/src/encodings/http.rs25 symbols
lambda-events/src/event/cloudwatch_alarms/mod.rs24 symbols

Datastores touched

your_dbDatabase · 1 repos

For agents

$ claude mcp add aws-lambda-rust-runtime \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact