AWS Lambda Rust: How to Deploy AWS Lambda Functions Built with Rust code

Master the deployment of Rust functions on AWS Lambda & learn to set up your environment, use cargo-lambda, and launch your Rust code in the cloud.

Subscribe

Subscribe

Deploying AWS Lambda functions with Rust is a game-changer for cloud computing. Rust is still an emerging language in the cloud ecosystem. Thanks to the “custom runtime” feature in AWS Lambda, you can deploy functions using unofficially supported languages. This guide will walk you through the process using cargo-lambda, a Rust community tool that simplifies implementation of Rust as a custom runtime for AWS Lambda.


Setting Up Your Development Environment

For the purposes of this article, we will assume that your local development workstation is running the latest version of Canonical’s Ubuntu Linux Desktop. However, these steps can be adapted to Microsoft Windows, Apple MacOS, and other Linux distributions.

  • MacOS Users: Consider the UTM app for a Linux desktop VM.
  • Windows Users: Hyper-V or Oracle VirtualBox are great for Ubuntu VMs.
  • Advanced Users: Try Vagrant utility from HashiCorp or Quickemu for launching graphical VMs.

Essential Development Tools

In order to develop and deploy AWS Lambda functions, you’ll want to install a few dev tools first.

  • Microsoft Visual Studio Code: A powerful, cross-platform editor.
  • Rust Toolchain: The backbone for Rust development.
  • Cargo Lambda: A specialized tool for deploying Rust functions to AWS Lambda.

Let’s go through the installation and validation steps for each of these individually!

Installation Steps for Visual Studio Code

The first thing we need to install is our code editor. Your editor is one of the most important tools in your tool belt, because it helps you write code more efficiently.

Visual Studio Code (VSCode) is an extensible and cross-platform code editor for writing nearly any language, including plain text formats like Markdown. The Rust community provides an extension for VSCode called Rust Analyzer, which provides advanced language features for Rust. To install VSCodefrom the Snapcraft store, along with the Rust Analyzer extension, you can run the following commands.

sudo snap install code --classic

code --install-extension rust-lang.rust-analyzer

You should be able to launch VSCode from your Activities bar in Ubuntu Linux desktop. The default VSCode window should look substantially similar to the following screenshot.

AWS Lambda Rust- How to Deploy AWS Lambda Functions Built with Rust code1 (1)

Install Rust Toolchain

Now that we’ve got our code editor installed, we need Rust itself!

The Rust toolchain provides the necessary components to initialize Rust projects, add crates (libraries) as project dependencies, and compile your Rust applications or libraries. Run the shell commands below, to install the curl utility and the Rust toolchain.

sudo apt update;

sudo apt-get install curl --yes;

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

During installation of the Rust toolchain, you’ll be prompted to confirm the default configuration, or have the option of customizing the installation. For now, just accept the default by hitting ENTER on your keyboard.

Next up, we need to install the cargo-lambda tool!

Install Cargo Lambda CLI

Finally, the cargo-lambda open source tool greatly simplifies the process of deploying your Lambda function code to your AWS account. You can install cargo-lambda with the command below.

sudo apt update

sudo apt-get install python3-pip --yes

pip3 install cargo-lambda

If it seems odd to use Python’s pip package manager to install a Rust tool, you’d be right! However, this is the documented approach to installing it, so just go with it.

You’ll need to ensure that your Bash shell is able to locate the cargo-lambda tool. To do that, we need to modify the PATH environment variable. We’ll include the entire directory where pip installs binaries to, under your home directory.

Run the following command in Bash, and then restart your terminal.

echo "export PATH=$(pwd)/.local/bin:$PATH" >> ~/.bashrc

Let’s verify that cargo-lambda is present! You should now be able to launch cargo-lambda with the following command.

cargo lambda

As you can see, the lambda command has automatically become a new sub-command of the Cargo CLI! By default, Cargo doesn’t have a lambda sub-command.

You can also run this Linux command to verify cargo-lambda’s existence:

ls -lG ~/.local/bin/cargo-lambda

Explore Cargo Lambda CLI

The best way to familiarize yourself with the capabilities of the cargo-lambda CLI is to run the following command.

cargo lambda

The above command will display a list of sub-commands supported by cargo-lambda. The list of commands is fairly straightforward. Most of the operations available include:

  • Create a new Lambda project directory (new)
  • Build your Lambda function locally, without publishing (build)
  • Invoke a local development Lambda server (watch)
  • Publish your Lambda function to your AWS account (deploy)
  • Test your Lambda function against the local dev server (invoke)

Let’s step through the usage of this tool by creating a new project, first!

Creating and Testing Your AWS Lambda Project

One of the things that the cargo-lambda tool helps you accomplish is creating a new AWS Lambda project from a template. This initialization process reduces the amount of setup time required for you to start writing Lambda code.

Let’s create a new project with the following command.

cd ~; cargo lambda new get-recipe

When you run the above command, you’ll be prompted with a couple questions. The first question posed is if your Lambda function will be triggered behind an HTTP front-end, such as Amazon API Gateway or a Lambda URL. In many serverless architectures, the answer will be yes (y), but for now let’s keep things simple by just hitting ENTER to accept the default of “no” (N).

The second question posed is which service will be responsible for triggering the Lambda function. As you may know, AWS Lambda functions can be invoked by a wide variety of other AWS services that are directly integrated with it.

You should have a new folder named get-recipe in your home directory, so switch into it. Now, to open up this project in Visual Studio Code, you can run:

code ~/get-recipe

Updating Your Lambda Function Code

Now that we have a new Lambda project, let’s customize the code. Let’s first open up the src/main.rs file, and tweak the main function to print some custom text.

Inside the file, find the async function called function_handler. Inside that function body, add a call to the println macro. This will simply serve to customize the Lambda handler function, but feel free to be more creative.

println!("Retrieving a recipe!");

Save the file and close it.

Testing Rust Lambda Function Locally

Now that your function has been customized, it’s time to test it out locally, before we push it up to your AWS account! The cargo-lambda tool has local testing built into it. First, we launch the development server, and then open up a secondary shell to send requests to the local dev server.

To launch the development server, use this command from your project directory:

cargo lambda watch

Once the Lambda function is compiled, it will pause your shell. This is your indication that the development server is up and running. 

Next, we need to invoke the function that’s running inside the development server. We must pass a JSON payload, that matches the struct named Request, as input to the Lambda function. Open up a second shell, and navigate to your project directory. Use the command below:

cargo lambda invoke --data-ascii "{\"command\": \"test-cmd\"}"

You should see a response from the Lambda function that corresponds to the Rust struct named Response. On my local system, it looks like this:

{"req_id":"4d193de7-bf7b-4ec0-9315-c4fbf7d76d56","msg":"Command test-cmd."}

You can also specify a JSON payload with the parameters --data-file and --data-example. However, passing the JSON payload in-line with --data-ascii is a bit easier in a demo situation.

NOTE: If you want to customize the inputs and outputs for the Lambda function, you can update the struct fields declared on both the Request and Response structs in main.rs.

Generating AWS User Credentials

At this point, you are probably chomping at the bit to deploy your Rust function into the AWS Lambda service. In order to do that, we will need to generate some static AWS user credentials, so that we can publish the Lambda function from our local development system.

  1. Open the AWS IAM web management console
  2. Create a new IAM user
  3. Choose Attach Policies Directly option
  4. Search for the AWSLambda_FullAccess policy and check it
  5. Finish the user creation wizard, and open the user details
  6. Open the Security Credentials tab
  7. Under Access Keys, select the Create Access Key button
  8. Choose the Other option, and skip the Description field
  9. Copy the Access Key and Secret Access Key values

After you’ve generated the credentials, configure the environment variables for the AWS SDK for Rust below. You can also set your target deployment region this way. In the Bash shell, you can use the following syntax.

export AWS_ACCESS_KEY_ID=<access_key>

export AWS_SECRET_ACCESS_KEY=<secret_key>

export AWS_REGION=us-west-2

If you’re using PowerShell on Linux, instead of Bash, you’d use this:

$env:AWS_ACCESS_KEY_ID = '<access_key>'

$env:AWS_SECRET_ACCESS_KEY = '<secret_key>'

$env:AWS_REGION = 'us-west-2'

If you restart your shell, you’ll need to run these commands again. Environment variables only apply to the current shell session, unless you otherwise configure them.

Deploying Rust Lambda Function

After configuring your AWS credentials in your shell, it’s finally time to deploy the Lambda function! This is really easy, with a couple of commands, thanks to the cargo-lambda project.

cargo lambda build

cargo lambda deploy

After running these commands, the cargo-lambda CLI will create an IAM role for your AWS Lambda function to execute as, and then publish the function package. Congratulations, you’ve just published your first Rust function to AWS Lambda!

Testing Your Lambda Function

Now that your Rust function has been published to the AWS Lambda service, you can test out execution of it. The easiest way to do this is by accessing the AWS Lambda service in the AWS Management Console.

  1. Open the AWS Lambda web console
  2. Select the get-recipe function from the list
  3. Click on the Test tab
  4. Change the Event Name field to something like test1
  5. In the JSON payload, enter something like: { "command": "test-input" }
  6. Click the Save button, followed by the Test button

If everything worked, you should see some output in the green execution details section. Check out the screenshot below, and yours should look similar. Also note that under Log Output, you should see the log message that you printed out with the println macro, in an earlier step.

AWS Lambda Rust- How to Deploy AWS Lambda Functions Built with Rust code2 (1)

Innovate with Rust and AWS Lambda

We've introduced you to the tools and processes for deploying Rust functions to AWS Lambda. Now, it's your turn to innovate. Consider building an image processing service, a record batch processor, or a load-testing client. As a software developer, it's up to you to apply your creative freedom to explore solutions that you can build using Rust and AWS Lambda. The possibilities with Rust and AWS Lambda are endless.

Below are some ideas to help jumpstart your brain cells as you think up new project ideas!

  • Image processing service
  • Record batch processing
  • Video metadata extraction
  • Demo database data generation
  • Load testing client
  • Query and store time-series data

Thanks for reading through this article, and make sure to contact us for help writing high-performance software solutions in the cloud!

BONUS: Find Out if Your Organization is Ready for The Cloud ⤵️

FinOps

Similar posts