Simple AWS lambda demo with rust
This is just a quick and dirty introduction to AWS lambda with rust, we have two goals here:
- build and upload a lambda rust function => ./lambda_test
- invoke a lambda function from rust => ./rust_aws_lambda_client
All of this can be experienced with 0$ because amazon free tier allows you to use AWS lambda for free.
As a bonus, we also showcase how to run the lambda within a local docker container for debug purpose.
https://console.aws.amazon.com/
To perform all futur tasks from your terminal install the official AWS cli.
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
Once your account is created, the best practice is to create a second user other than root to perform all daily actions. You can do it here: https://console.aws.amazon.com/iamv2/home?#/users Within this same page you have to create tokens for your AWS cli. For that create a user and select "programmatic access" instead of password. The download the generated csv and import it with AWS cli.
aws configure import --csv file://credentials.csv
More about that here => https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
Create a role that will be used by the aws lambda, this role defines the permissions of your lambda. By default it requires a AWSLambdaBasicExecutionRole to send logs to cloudtrail.
https://console.aws.amazon.com/iamv2/home?#/roles AWS Service => lambda => next => search for AWSLambdaBasicExecutionRole => next. Name it lambda-basic-execution and click create.
We want to statically compile our binary for it to be compatible with the AWS lambda system.
git clone --depth 1 https://github.com/nongiach/aws_lambda_demo_rust
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
cp ./target/x86_64-unknown-linux-musl/release/bootstrap . && zip lambda.zip bootstrap && rm bootstrap
AWS_ACCOUNT_ID=`aws sts get-caller-identity --query Account --output text` && \
aws lambda create-function \
--function-name rust_lambda \
--runtime provided \
--role arn:aws:iam::$AWS_ACCOUNT_ID:role/lambda-basic-execution \
--zip-file fileb://lambda.zip \
--description "Simple Rust function" \
--timeout 5 \
--handler main
aws lambda invoke \
--function-name=rust_lambda \
--invocation-type=RequestResponse \
--payload $(echo '{"fullName": "Martin Luther", "message": null}' | base64 ) \
output.json
cd aws_lambda_demo_rust\
cargo run -- -v --arn rust_lambda
More here about how to interact with a lambda function from rust https://docs.rs/aws-sdk-lambda/0.3.0/aws_sdk_lambda/client/struct.Client.html#method.invoke
aws lambda list
aws lambda list-functions
aws lambda delete-function --function-name rust_lambda
aws lambda update-function-code --function-name rust_lambda --zip-file fileb://lambda.zip
This runs the binary target/x86_64-unknown-linux-musl/release/bootstrap into a docker container to simulate a local AWS environment.
docker run --rm \
-e DOCKER_LAMBDA_STAY_OPEN=1 -p 9001:9001 \
-v "$PWD"/target/x86_64-unknown-linux-musl/release/bootstrap:/var/task/bootstrap:ro,delegated \
lambci/lambda:provided main
aws lambda invoke \
--endpoint http://localhost:9001 \
--no-sign-request --function-name=rust_lambda \
--invocation-type=RequestResponse \
--payload $(echo '{"fullName": "Martin Luther", "message": null}' | base64 ) \
output.json
# sudo apt install musl-tools
rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl
cp ./target/x86_64-unknown-linux-musl/release/bootstrap . && zip lambda.zip bootstrap && rm bootstrap
http://jamesmcm.github.io/blog/2020/04/19/data-engineering-with-rust-and-aws-lambda/
https://aws.amazon.com/blogs/opensource/rust-runtime-for-aws-lambda/ https://adevait.com/rust/deploying-rust-functions-on-aws-lambda https://docs.aws.amazon.com/sdk-for-rust/latest/dg/lambda.html