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 | shJust 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-lambdaAlternative 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-cliVerify installation:
which sam$ /opt/homebrew/bin/sam
sam --versionSAM 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 .envRun the docker compose in console in daemon mode:
docker compose up -dOther usefull commands:
List containers running
docker compose psShut down container
docker compose down #To shut down container and remove volumes - persisted databases and tables.
docker compose down -vNext 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 -dcommand.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 -pzukaYou 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.jsonGeneral 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.jsonsam local start-api --host localhost --port 9001 --env-vars .env.sam.local.jsonThis 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-dbFor deployment of the changes currently we use SAM CLI. The flow looks like this:
- Compile application
- Validate SAM template
- Deploy to required stage.
make buildsam validate --profile aws-rust-poc --lintIf there are some errors or suggestions please fix them.
sam deploy --config-file samconfig-<stage-name>.toml
sam deploy --config-file samconfig-staging.tomlsam deploy --config-file samconfig-prod.toml