It’s no secret that Rust has blown up in popularity in recent years. The Stack Overflow developer survey ranked it as the most loved programming language for the 6th time in a row. AWS has adopted it internally with projects like Firecracker powering AWS Lambda and Fargate and they are using it to scale critical infrastructure services like S3, EC2, and CloudFront.
Rust is a systems programming language that has performance on par with C/C++. It has unique features that make managing memory safe like Go/C#/Java — without using a garbage collector. With AWS announcing an official AWS SDK for Rust, and it gaining popularity with developers, Rust could become an important language for optimizing code where performance is critical. AWS recently added Sustainability to the Well-Architected framework and they are investing in Rust so that customers can build more sustainable energy-efficient solutions in the cloud.
Getting Started with Rust
The official way to install Rust is through a tool called Rustup. Head over to the install page to get started. Rustup will install the Rust toolchain into the '~/.cargo/bin' directory and this is where you will find the 'cargo' 'rustc' and 'rustup' binaries. 'rustc' is the Rust compiler and 'cargo' is the Rust package manager. Open source Rust libraries are published on crates.io and you use 'cargo' to download, install and compile packages. Rust packages are also referred to as “crates”.
Run the Rustup installer, then check that cargo is installed with the following command:
If you’re interested in a more in-depth introduction to Rust the learn page has links to books, tutorials, and examples. The “Rust book” has a getting started tutorial and is a good place to learn more about the language.
Setting Up VS Code
Rust has very good editor support which you can check out on the tools page.
If you’re using VS Code I recommend using the following extensions:
To create a basic rust program use the cargo new command
This generates a 'src/main.rs' file containing our hello world program, and a 'Cargo.toml' which we can use to install packages from crates.io
To compile and run the program use the cargo run command
If you want to check your program is valid use cargo check — this will perform a full compile but skip the code generation step. To do a full compile use cargo build.
Getting Started with the AWS SDK for Rust
Open the 'Cargo.toml' file and edit the section under '[dependencies]'. Once you hit “save” rust-analyzer will start downloading the crates in the background and VS Code will show a progress indicator in the status bar. If you’ve installed the 'crates' extension it will show ✅ for crates that have the latest version specified. If it shows an ❌ you can hover over it a click to upgrade to the latest version of the crate.
To ensure cargo has downloaded all the crates run 'cargo build'. The first time you build a Rust program it might take a while because it has to download all the crates and build them. On subsequent builds, it’s much faster 😊
You might be wondering what each of these crates are for, so I will give a brief explanation here:
- The tokio crate provides an asynchronous runtime for Rust. The AWS SDK is built on top of Tokio which you can read more about it here.
- The aws-config crate has credential provider implementations.
- The aws-sdk-* crates are for any AWS services you want to use. In this example we are referencing the aws-sdk-s3 crate which we will use to talk to AWS S3. Each AWS service is published as a separate crate. You can view information about the S3 crate on crates.io which has links to the Github repository and documentation. It also shows the downloads for the last 90 days which are trending up!
How to Authenticate with AWS
The simplest way to authenticate using the Rust SDK for AWS is using the 'default' credentials profile. On Linux and MacOS, this file is found at '~/.aws/credentials'. On Microsoft Windows it is found at '%USERPROFILE%\\.aws\\credentials'.
- If the credentials file doesn’t exist, create it.
- Add the following to the file, where 'YOUR-ACCESS-KEY' is the value of your access key and 'YOUR-SECRET-KEY' is the value of your secret key:
Update the code in 'src/main.rs' with the following code.
If you want to use a named credentials profile you can use the following code:
Basic SDK Example Using S3
For this example, we are going to create a bucket, upload and download some files to it, and then finally I will show you how you can empty a bucket before deleting it. Remember that bucket names are globally unique, so choose a name that nobody else has used before — I’ve highlighted the line of code with a comment ✨ to show you where to change it. If you’re feeling brave, try to type out all the code by hand. You can check if the code is valid by running 'cargo build'.
Create a Bucket
To run the program type 'cargo run'
If you get an error, perhaps the bucket name you used was already taken, the program will panic and print out the error that happened. In the example below you can see a big ugly error:
Let’s change this code and handle the error gracefully so our program doesn’t panic! There’s one important change to make, which is to remove the '?' after the '.await' call so that the error doesn’t automatically get returned up the call stack, and panic when it reaches main. Rust doesn’t have exceptions so you need to handle errors manually, you can read more about this in the error handling section of the Rust book.
This time we handle the error ourselves by printing out our own error message + the error from the S3 client.
Uploading files to S3
We will use the same bucket that we created before and to keep it simple we can use plain text for the contents of the object rather than uploading a file from disk.
Test it out by running the program, and feel free to check the file is in the bucket using the AWS console 🙂
To upload an actual file, add a 'testfile.txt' in the root of the project, in the same folder as the 'Cargo.toml' file, then change the following code:
Run the program
Downloading files from S3
In this example, we are going to download the files that we previously uploaded and print out the contents of the file.
Run the program
Deleting the Bucket
You must “empty” the S3 bucket before you can delete it. So this last example is a little bit more complicated as it shows you how you can paginate through objects returned from S3. We iterate through the keys deleting the objects for each page of results. Once all the files are deleted we can delete the bucket.
Run the program to delete the bucket 🔥
In this article, we discussed how to get started with the Rust programming language, as well as, how to run basic examples using the AWS SDK for Rust. The goal of this article was to hopefully get some readers interested in Rust — without going into too much detail about the language. In the next blog post, we will learn how to use Rust with DynamoDB and perform some basic CRUD operations. We will also cover more about this language’s better error handling in particular. After that, I’m planning to do another article on using Rust with Lambda and eventually a tutorial on how to build out a real-world example using AWS CDK.
Further reading and references
If you’re wanting to learn more about AWS SDK for Rust here are the links to the official docs