Your Lambdas, in Rust!

Luciano Mammino (@loige)

Cloud Native 2023
2023-03-30

👋 I'm Luciano (🇮🇹🍕🍝🤌)

👨‍💻 Senior Architect @ fourTheorem

📔 Co-Author of Node.js Design Patterns  👉

Let's connect!

  loige.co (blog)

  @loige (twitter)

  loige (twitch)

  lmammino (github)

Grab the slides

$ ~ whoami

Always re-imagining

We are a pioneering technology consultancy focused on AWS and serverless

✉️ Reach out to us at  hello@fourTheorem.com

😇 We are always looking for talent: fth.link/careers

We can help with:

Cloud Migrations

Training & Cloud enablement

Building high-performance serverless applications

Cutting cloud costs

We host a weekly podcast about AWS

Agenda

  • Serverless and its benefits
  • AWS Lambda and its pricing model
  • Why Rust
  • Cargo Lambda example
  • Using it with SAM
  • Lambda tuning
  • Closing notes

⚡️Serverless

Serverless, in a nutshell 🥜

  • A way of running applications in the cloud

  • Of course, there are servers... we just don't manage them

  • You pay for what you use

  • Small units of compute (functions), triggered by events

Serverless... with benefits 🎁

  • More focus on the business logic (generally)

  • Increased team agility (mostly)

  • Automatic scalability (sorta)

  • Not a universal solution, but it can work well in many situations!

AWS Lambda

FaaS offering in AWS

Can be triggered by different kinds of events

  • HTTP Requests
  • New files in S3
  • Jobs in a Queue
  • Orchestrated by Step Functions
  • On a schedule
  • Manually invoked

AWS Lambda Pricing 💸

Cost = Allocated Memory 𝒙 time

AWS Lambda Pricing 💸

Cost = Allocated Memory 𝒙 time

512 MB = $0.0000000083/ms

Executing a lambda for 15 mins...

0.0000000083 * 900000 = 0.007 $

AWS Lambda... what about CPU? 🙄

You don't explicitly configure it:

CPU scales based on memory

AWS Lambda... what about CPU? 🙄

You don't explicitly configure it:

CPU scales based on memory

Memory vCPUs
128 - 3008 MB 2
3009 - 5307 MB 3
5308 - 7076 MB 4
7077 - 8845 MB 5
8846+ MB 6

Writing Lambdas

in Node.js

export const handler = async(event, context) => {
  // ... get data from event
  // ... run business logic
  // ... return a result
}
export const handler = async(event, context) => {
  // ... get data from event
  const { url } = event

  // ... run business logic
  const res = await fetch(url)
  console.info(`Status of ${url} : ${res.status}`)

  // ... return a result  
  return res.status
}

Supported runtimes

  • Node.js

  • Python

  • Java

  • .NET

  • Go

  • Ruby

  • Custom

Supported runtimes

  • Node.js

  • Python

  • Java

  • .NET

  • Go

  • Ruby

  • Custom

RUST?!

Rust Runtime for Lambda

use lambda_runtime::{service_fn, LambdaEvent, Error};
use serde_json::{json, Value};

#[tokio::main]
async fn main() -> Result<(), Error> {
    let func = service_fn(func);
    lambda_runtime::run(func).await?;
    Ok(())
}

async fn func(event: LambdaEvent<Value>) -> Result<Value, Error> {
    let (event, _context) = event.into_parts();
    let first_name = event["firstName"].as_str().unwrap_or("world");

    Ok(json!({ "message": format!("Hello, {}!", first_name) }))
}

Your Rust Lambda handler

Runs the handler

Extra boilerplate 🤷‍♀️

Y Rust tho?

Rust

  • Relatively new language (2015)
  • It's a compiled language
  • Focused on performance and memory safety
  • But also providing great high-level constructs
  • Great as a general-purpose language
  • Very modern toolchain
  • Great ecosystem
  • Awesome mascot

Cargo

  • Rust built-in package manager
    (like npm but for Rust)
  • Also used for scaffolding, testing & more
  • It can be extended with third-party commands

Why Rust + Lambda = ❤️

  • Performance + Efficient memory-wise = COST SAVING 🤑
  • Multi-thread safety 💪
  • No null types + Great error primitives = fewer bugs 🐞

Cargo Lambda

  • A third-party command for Cargo that makes it easier to author, test and deploy Lambdas in Rust
  • It can cross-compile for Linux ARM (on Win/Mac/Linux)

Commands

  • cargo lambda new - scaffolds a new project
  • cargo lambda watch - starts a dev environment (lambda emulator)
  • cargo lambda invoke (sends an event to the dev environment)
  • cargo lambda build (builds the lambda)
  • cargo lambda deploy (deploys the lambda to AWS)

Cargo Lambda

DEMO 🤞

Cargo Lambda

SAM

Serverless Application Model

AWS SAM

  • YAML-based Infrastructure as code (IaC) tool focused on serverless apps
  • Great when you have to go beyond just one lambda

Some example use cases:

  • You need to provision multiple lambdas
  • You need to provision multiple pieces of infrastructure (e.g. S3 buckets, permissions, DynamoDB tables, etc)
  • It supports everything that is natively supported with CloudFormation, but with a slightly simpler syntax
  • Deploys through CloudFormation!

AWS SAM

# template.yaml

AWSTemplateFormatVersion : '2010-09-09'
Transform:
  - AWS::Serverless-2016-10-31

Description: |
  A sample Serverless project triggered from S3 CreateObject events
Resources:
  ExampleFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: nodejs18.x
      Handler: index.handler
      Events:
        S3CreateObject:
          Type: S3
          Properties:
            Bucket: !Ref MyPhotoBucket
            Events: s3:ObjectCreated:*

  MyPhotoBucket:
    Type: AWS::S3::Bucket

AWS SAM + Cargo Lambda

SAM Works with Cargo Lambda (still experimental):

  • Define IaC with the full power of SAM
  • Build and run your Rust lambdas with Cargo Lambda

Note: Cargo Lambda also works with CDK
(github.com/cargo-lambda/cargo-lambda-cdk)

SAM + Cargo Lambda, a complete example

🔧Fine Tuning

Your lambdas

Fine tuning your Lambdas

  • If you give your lambdas more memory you get more CPU
  • Sometimes having more memory (hence more CPU) can make your executions faster and you can save money
  • So how do we find the sweet spot?!

Lambda Power Tuning

A step function that can test different configurations of your Lambda

Is it easy to learn Rust?!

🤨

Is it worth learning Rust?!

🤔

Summary

  • Serverless is a great way to build apps
  • Rust is a great language (and ecosystem) to build apps
  • Serverless + Rust = ❤️
  • You can use SAM & Cargo Lambda for a great DX
  • Learning Rust is not necessarily easy, but definitely worth it

Cover picture by Amy Perez on Unsplash

Thanks to @eoins for kindly reviewing this talk!

THANKS!

Grab these slides!