This project is an attempt to proof concept of building serverless application in Rust programming language.
- Rust (v1.67.1)
- Cargo (v1.67.1)
- Cargo lambda (v0.17.1)
- AWS CLI (v2.10.4)
- AWS SAM CLI (v1.75.0)
- Docker (v20.10.22)
Install Rust, by running this command in your terminal:
curl https://sh.rustup.rs -sSf | sh
Just follow CLI helper and install everything with default settings. It will install both Rust language and Cargo tool.
Verify installation:
which rustc
$ /Users/victorshinkevich/.cargo/bin/rustc
rustc --version
$ rustc 1.67.1 (d5a82bbd2 2023-02-07)
which cargo
$ /Users/victorshinkevich/.cargo/bin/cargo
cargo --version
$ cargo 1.67.1 (8ecd4f20a 2023-01-10)
Next you need to install cargo lambda. Here is command for installation via homebrew package manager.
brew tap cargo-lambda/cargo-lambda
brew install cargo-lambda
Alternative ways to install cargo lambda can be found here.
You need to have both AWS CLI and AWS SAM.
AWS CLI installer takes care of arm/x64 differences, just download and run installer.
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
Verify installation:
which aws
$ /usr/local/bin/aws
aws --version
$ aws-cli/2.10.4 Python/3.9.11 Darwin/22.3.0 exe/x86_64 prompt/off
Note: output will be different depending on your OS and CPU architecture.
Log into aws web console, open IAM and create yourself a pair of keys: public access key ID
and secret access key
. Detailed instruction is found here.
Having those keys, configure yourself an aws profile. In scripts and configs we are using named profile aws-rust-poc
Run the command to create it:
aws configure --profile aws-rust-poc
$ AWS Access Key ID:<YOUR_PUBLIC_ACCESS_KEY_ID>
$ AWS Secret Access Key: <YOUR_PRIVATE_SECRET_ACCESS_KEY>
$ Default region name: us-west-2
$ Default output format: json
Verify profile configuration:
cat ~/.aws/credentials
$ [aws-rust-poc]
$ aws_access_key_id = <YOUR_PUBLIC_ACCESS_KEY_ID>
$ aws_secret_access_key = <YOUR_PRIVATE_SECRET_ACCESS_KEY>
Now AWS CLI is configured, and we can proceed with installation of AWS SAM CLI.
For Mac users AWS SAM CLI is available via homebrew.
brew install aws/tap/aws-sam-cli
Verify installation:
which sam
$ /opt/homebrew/bin/sam
sam --version
SAM CLI, version 1.75.0
For docker installation please follow official website. You will need
- docker desktop
- docker compose plugin
And we are done with dependencies!
Before running or deploying a project we need to build it, meaning compile the code. It can be done running make command:
make build
$ Finished release [optimized] target(s) in 53.96s
Prepare an .env file for docker compose running DB:
cp .env.dist .env
Run the docker compose in console in daemon mode:
docker compose up -d
Other usefull commands:
List containers running
docker compose ps
Shut down container
docker compose down #
To shut down container and remove volumes - persisted databases and tables.
docker compose down -v
Next you need to import dump from development/staging environment.
- Download dump from bastion or ask SRE for it.
- After receiving dump copy it to the container:
docker cp <path_to_dump>/<dump-name>.sql aws-rust-poc-mysql_db-1:/
- You will need a root password for mysql for import. It can be fetched from logs when it was generated during first
docker compose up -d
command.Copy this password to clipboard.docker logs aws-rust-poc-mysql_db-1 2>&1 | grep GENERATED $ GENERATED ROOT PASSWORD: 2CB0A6A3eWgQHtJiVtRAMCd5r/XheLE1
- Open bash inside container and import DB using mysql client:
docker exec -it aws-rust-poc-mysql_db-1 /bin/bash # Replace <ROOT_PASSWORD> with password you acquired from logs on the previous step. mysql -uroot -p<ROOT_PASSWORD> zuka < <name-of-dump>.sql
While still in docker container, verify sucessfull import:
Connect to db via mysql client.
mysql -uzuka -pzuka
You should see zuka
there:
SHOW DATABASES;
You should see a list of tables:
USE ZUKA;
SHOW TABLES;
Our POC Serverless application consists of API gateway, which are http endpoinds and lambda functions that are being invoked (triggered) by API gateway and DB that is being used by functions. SAM CLI gives us ability to do both in local environment - invoking lambdas and running HTTP server that acts as API gateway. For both we need to set up local env variables.
cp .env.json.dist .env.sam.local.json
General command looks like this
sam local invoke <LambdaName> --env-vars .<env-var-file-name>.json
List of lambdas can be found in template.yaml
under Resources
section with **Lambda
name pattern.
For instance
sam local invoke PingLambda --env-vars .env.sam.local.json
sam local invoke PingDbLambda --env-vars .env.sam.local.json
sam local start-api --host localhost --port 9001 --env-vars .env.sam.local.json
This will start server on localhost listening 9001 port.
Routing from http server (gateway) to lambdas could be found in template.yaml
under Resources
-> <LambdaName>
-> Properties
-> Events
.
For instance:
curl http://localhost:9001/ping
curl http://localhost:9001/ping-db
For deployment of the changes currently we use SAM CLI. The flow looks like this:
- Compile application
- Validate SAM template
- Deploy to required stage.
make build
sam validate --profile aws-rust-poc --lint
If there are some errors or suggestions please fix them.
sam deploy --config-file samconfig-<stage-name>.toml
sam deploy --config-file samconfig-staging.toml
sam deploy --config-file samconfig-prod.toml