1. About
Sample Rust projects to access AWS via SDK.
2. Prerequisites
-
~/.aws/credentials
(This can be created viaaws configure
command.)
./ec2
project
3. 3.1 About
This project creates an HTTP server which does the following for each request:
-
Receive a JSON of the form
{"r": 255, "g": 255, "b": 0}
. -
Create a PNG image whose every pixel is filled with the given color.
-
Upload it to S3.
-
Log the request with its timestamp to RDS (MySQL) and DynamoDB.
-
Create and return a pre-signed URL (i.e. a public URL with expiration date) to access the object uploaded in S3.
It works locally, or you can deploy it to EC2.
3.2 Architecture
3.3 Usage
-
Access S3 console to create a bucket called
bucket-test-002-a
with the default settings. -
Access RDS console.
-
Create a MySQL instance called
test-rds-001
. Make surePublicly accessible
is turned on (to test it locally). -
Edit inbound rules to allow accesses to
3306
port. -
Connect to it via command-line to create a database called
test
.#You can NOT use a space instead of `=`. $ mysql -h <host> -P 3306 --user=<user> --password=<password>
create database test;
-
-
Access DynamoDB console to create a table called
test_dynamodb_001
, whose primary key has the nametimestamp
of the typeString
. -
Access EC2 console.
-
Create an instance whose OS is Amazon Linux 2.
-
Edit inbound rules to allow accesses to the port you want to listen (in addition to SSH).
-
-
Deploy and build the project. (Warning: If you use a free tier instance, DO skip to the step 6. Executing
cargo build
inside such an instance eats too much power to completely break the instance. After that, you cannot connect to the instance via SSH or even via browser. Rebooting the instance doesn't fix the problem: you have no chance but to create a brand new instance. This behavior was observed both for Ubuntu and Amazon Linux 2.)-
Connect to the instance via SSH.
$ ssh aws
-
Install Rust by following the official instructions:
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Install dependencies.
$ sudo yum update $ sudo yum install git gcc openssl-devel
-
Clone this repository.
$ git clone 'https://github.com/your-diary/aws_rust_samples'
-
Edit the configuration file (see below for the details).
$ cd aws_rust_samples/ec2 $ vi config.json
-
Build.
$ cargo build --release
-
-
Deploy and build the project, using cross-compilation. (If you execute the step 5, skip this step.)
-
Cross-compile the project.
$ rustup target add x86_64-unknown-linux-gnu $ cargo build --release --target x86_64-unknown-linux-gnu
-
Write a config file (see below for the details).
$ vi config.json
-
Send the config file and the built binary to the instance.
$ ssh aws 'mkdir ec2' $ rsync -auv ec2 config.json aws:./ec2/
-
-
Access EC2 console.
-
Choose the instance.
-
Select
Actions
>Security
>Modify IAM role
to attach a role to the instance to make AWS services accessible inside the instance.
-
-
Send the credential files to the instance. (Warning: Normally this is not needed to use AWS SDK, but in this project we use the third-party
rust-s3
crate and it didn't seem to support reading the credentials via IAM role.)$ rsync -auv ~/.aws aws:./
-
Check if RDS (MySQL) is accessible inside the instance.
-
Connect to the instance via SSH.
$ ssh aws
-
Install
mysql
command.$ sudo yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm $ sudo yum install -y mysql-community-client
-
Try to connect to RDS (MySQL).
#You can NOT use a space instead of `=`. $ mysql -h <host> -P 3306 --user=<user> --password=<password>
-
If connection failed, access RDS console and make sure the security group of the instance (e.g.
sg-...
) is listed in the inbound rules.
-
-
Run the server.
-
Connect to the instance.
$ ssh aws
-
Run the server.
$ cd ec2/ $ screen -d -m ./ec2 $ screen -ls
-
-
Call the API.
$ curl \ -H 'Content-Type: application/json' \ -d '{"r": 100, "g": 100, "b": 200}' \ <URL>
{ "status": "success", "url": "https://..." }
$ curl <returned URL> | imgcat
3.4 Configurations
Configurations are read from config.json
.
Example:
{
"port": 30021,
"img_width": 300,
"img_height": 200,
"s3": {
"bucket_name": "bucket-test-002-a",
"expiration_sec": 30
},
"rds": {
"host": "test-rds-001.xyz.ap-northeast-1.rds.amazonaws.com",
"port": 3306,
"user": "admin",
"password": "abcde",
"database_name": "test",
"table_name": "colors"
},
"dynamodb": {
"table_name": "test_dynamodb_001"
}
}
3.5 References
./lambda/
project
4. 4.1 About
This project creates a REST API which receives a JSON of the form {"content": <string>}
and uploads its content
as <timestamp>.txt
to S3.
4.2 Architecture
4.3 Usage
-
Run tests. We expect every test passes.
$ cargo test
-
Cross-compile the project for Amazon Linux 2.
$ cargo lambda build --release
-
Deploy the project as a lambda function. You do not have to create a lambda function from the console in advance; it automatically creates or updates the lambda function whose name is
lambda_test_001
. (The name can be customized vianame
property inCargo.toml
).$ cargo lambda deploy
-
Access S3 console to create a bucket called
bucket-test-001-a
with the default settings. -
Access Lambda console.
-
Select
lambda_test_001
. -
Select
Configuration
>Permissions
>Execution role
and click the name of the role (e.g.cargo-lambda-role-...
). -
Add
AmazonS3FullAccess
role.
-
-
Access API Gateway console.
-
Create a new REST API called
test_gateway_001
. -
Select
Actions
>Create Method
to create aPOST
method and bind it tolambda_test_001
. -
After creating the
POST
method, clickMethod Request
and change the value ofAPI Key Required
totrue
. -
Select
Actions
>Deploy API
to deploy the API. The name of a stage is arbitrary but let's usetesting
for convenience. After that, you are redirected toStage Editor
. Change the values ofRate
andBurst
as you want. You may also want to memorize theInvoke URL
which is the URL for this API. -
Select
Usage Plans
in the sidebar to start creating a usage plan calledTesting
. First setRate
,Burst
andQuota
as you want, and then clickAdd API Stage
to bind thetesting
stage oftest_gateway_001
to the plan. -
Select
API Keys
in the sidebar and selectActions
>Create API key
to create an API key. Then clickAdd to Usage Plan
to bind it to theTesting
plan.
-
-
Call the API with the key.
$ curl \ -H 'x-api-key: <API key>' \ -d '{"content": "hello"}' \ <URL>
{"status":"success","filename":"1678969418940.txt"}
4.4 References
-
Using the AWS SDK for Rust in AWS Lambda function (a bit outdated)