How to Use AWS Lambda Secrets Manager + Sample Code
Learn how to use AWS Lambda Secrets Manager efficiently! Get sample code and step-by-step guidance. Keep reading to enhance your AWS security posture!
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.
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.
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.
In order to develop and deploy AWS Lambda functions, you’ll want to install a few dev tools first.
Let’s go through the installation and validation steps for each of these individually!
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.
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!
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
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:
Let’s step through the usage of this tool by creating a new project, first!
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
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.
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.
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.
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.
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!
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.
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.
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!
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 ⤵️
Learn how to use AWS Lambda Secrets Manager efficiently! Get sample code and step-by-step guidance. Keep reading to enhance your AWS security posture!
Streamline Redis performance with StratusGrid's Lambda module, automating slow log analysis to AWS CloudWatch for optimal efficiency.
Optimize AWS CPU performance with StratusGrid's Lambda Event Handler, ensuring efficient CPU credit management and stable instance operation.