Rust + AWS Lambda + Windows Part 1
Let it be known that the existing tutorials are all poor and lack thoroughness. They’re fine if you already have experience cross-compiling Rust AND working with AWS Lambda. I intend to cover everything from zero. It seems to me that a chief reason for the poor tutorials is the ever-evolving landscape of these technologies. If this ever stops working, LET ME KNOW! Much of this information is based on the README.md at the aws-lambda-rust-runtime repo.
Windows Tools
You’ll need to install these on Windows.
- PowerShell
- Text editor (I like VSCode)
- git (optional)
- Rust (optional since we’re installing it in WSL)
Debian Tools
As the heading, implies, I’ll be using Debian. Ubuntu, Kali, and a few others will probably work exactly as described this tutorial since they’re Debian forks. Many of the following commands will require input; I’m not mentioning that part, but this isn’t an automated process as written. Fire up PowerShell and enter:
wsl --set-default-version 2
wsl --install -d Debian
Follow the prompts, and a few minutes later you should be presented with a typical Unix terminal. There are a few tools we’ll need to install. Let’s update first.
sudo apt update && sudo apt upgrade
sudo apt install curl
sudo apt install build-essential
The following is optional.
sudo apt install zip
Let’s now install and configure Rust for WSL.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
You’ll want to restart the WSL instance at this point. I’m not sure the following is strictly necessary, but I do it just to be sure.
rustup update
rustup target add x86_64-unknown-linux-gnu
Back to Windows
Navigate to the aws-lambda-rust-runtime repo on GitHub. Download the whole thing as a Zip or use the following git command (assuming you installed git):
git clone https://github.com/awslabs/aws-lambda-rust-runtime.git
For this tutorial, I’m extracting/cloning the files into C:\aws-lambda-rust-runtime, but anywhere should do so long as spaces are not in the path name. Let’s open up C:\aws-lambda-rust-runtime\lambda-runtime\examples\basic.rs with our text editor and make a few changes to better understand the connection between the code and the AWS Lambda environment.
#[derive(Deserialize)] struct Request { command: String, }
Change this to:
#[derive(Deserialize)] struct Request { test_name: String, }
Two more edits.
let command = event.payload.command; // prepare the response let resp = Response { req_id: event.context.request_id, msg: format!("Command {} executed.", command), };
Note the subtle differences:
let output_name = event.payload.test_name; // prepare the response let resp = Response { req_id: event.context.request_id, msg: format!("Hello {}!", output_name), };
Save the file, of course!
Back to Debian
What’s neat about WSL is that it mounts the entire C: root in its filesystem. I’m not sure about other letters however. This means we can:
cd /mnt/c/aws-lambda-rust-runtime/
The next command may seem confusing to those new to Rust, but it should work.
cargo build -p lambda_runtime --example basic --release --target x86_64-unknown-linux-gnu
If you didn’t install build-essential in Debian, this error will appear:
ERROR:
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: could not compile `futures-core` due to previous error
warning: build failed, waiting for other jobs to finish...
error: build failed
Windows or Debian
After some time, several files will be created, but we’re interested in C:\aws-lambda-rust-runtime\target\x86_64-unknown-linux-gnu\release\examples\basic (note that’s a file not a directory!) We can rename this to bootstrap (no extension) and put it in a zip file of our choosing. For the sake of this example, I stuck with the terminal command:
cp ./target/x86_64-unknown-linux-gnu/release/examples/basic ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
That copied the file into C:\aws-lambda-rust-runtime\ and changed the copied file’s name to bootstrap. Finally, it zipped it into lambda.zip and deleted the copied file.
The follow-up to this tutorial regarding AWS Lambda is now live!
Notes
I have tried several different approaches to completely eliminate the need for WSL and simply cross-compiling the Rust program directly into an x86_64-unknown-linux-gnu under Windows. I think there’s an incompatibility between Visual Studio C++ Build tools and the target OS. Hunting down clues, the solution may be to set Rust’s build environment to MingW.