Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
rust function url example (#960)
Browse files Browse the repository at this point in the history
* init base sst project

* init rust project

* init basic axum server on lambda http

* working example

* update docs

* update folder name
  • Loading branch information
judegiordano authored Oct 7, 2024
1 parent da4a173 commit 5d350bb
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 0 deletions.
7 changes: 7 additions & 0 deletions examples/aws-rust-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

# sst
.sst

# rust
Cargo.lock
target/
23 changes: 23 additions & 0 deletions examples/aws-rust-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "aws_rust_cluster"
version = "0.1.0"
edition = "2021"

[profile.release]
debug = 0
incremental = false
panic = "abort"
opt-level = 3 # 0-3
strip = 'symbols' # strip symbols from binary
lto = true # enable link time optimization

[dependencies]
axum = "0.7.5"
lambda_http = "0.13.0"
lambda_runtime = "0.13.0"
serde = { version = "1.0.209", features = ["derive"] }
tokio = { version = ">=1.x", features = ["macros", "rt-multi-thread"] }

[[bin]]
name = "api"
path = "src/bin/handlers/api.rs"
133 changes: 133 additions & 0 deletions examples/aws-rust-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Rust Function Url Example

This example uses [cargo lambda](https://www.cargo-lambda.info/) to build rust binaries and deploy them on a provided AL2 runtime

NOTE: (cargo lambda relies on [zig](https://ziglang.org/), which it will prompt to install on first running a cargo lambda command)

```sh
cargo lambda build --release
```

you can also provide the architecture of choice

```sh
cargo lambda build --release --arm64
# or
cargo lambda build --release --x86-64
```

which can then be reflected in the `sst.config.ts`

```ts
const api = new sst.aws.Function("rust-api", {
architecture: "arm64", // or x86_64
...
});
```

by default, cargo lambda will build to a folder in `target/` called `lambda/`. The binary build will be called `bootstrap`, and it will be built in a sub folder which is the name of your binary.

For example, a rust binary `src/bin/handlers/api.rs` will be built to `target/lambda/api/bootstrap`

After building the binary, deploys can be done normally via `sst deploy --stage production`

Other services can be orchestrated in a similar manner with cargo lambda, for example a cron:
```ts
new sst.aws.Cron('MyCron', {
schedule: 'cron(0 0 * * ? *)',
job: {
architecture: 'arm64',
runtime: 'provided.al2023',
handler: 'bootstrap',
bundle: 'target/lambda/my-cron',
}
});
```

# GHA

An example to deploy using github actions with `arm64` architecture, feel free to configure as needed

```yml
name: Deploy Prod

on:
push:
branches:
- main

jobs:
deploy-prod:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pguyot/arm-runner-action@v2

- name: use Node.js
uses: actions/setup-node@v3
with:
node-version: latest

- name: use pnpm
uses: pnpm/action-setup@v4
with:
version: latest

- name: get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: setup pnpm cache
uses: actions/cache@v3
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: use Rust
uses: actions-rs/toolchain@v1

- name: use Rust cache
uses: Swatinem/rust-cache@v2

- name: use Zig
uses: korandoru/setup-zig@v1
with:
zig-version: master

- name: use Cargo Lambda
uses: jaxxstorm/[email protected]
with:
repo: cargo-lambda/cargo-lambda
platform: linux
arch: aarch64 # | x86_64

- name: cargo lint
run: cargo lint

- name: pnpm install
run: pnpm install --frozen-lockfile

- name: sst install providers
run: |
set -euxo pipefail
pnpm sst install
- name: build lambdas
run: |
set -euxo pipefail
cargo lambda build --release --arm64
- name: sst deploy
run: |
set -euxo pipefail
pnpm sst deploy --stage prod
env:
STAGE: prod
LOG_LEVEL: info
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
```
17 changes: 17 additions & 0 deletions examples/aws-rust-api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "aws-rust-cluster",
"version": "1.0.0",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"sst": "3.0.68",
"sst-linux-x64": "^3.0.66"
},
"devDependencies": {
"@types/aws-lambda": "8.10.143"
}
}
23 changes: 23 additions & 0 deletions examples/aws-rust-api/src/bin/handlers/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use axum::{http::StatusCode, response::IntoResponse, routing::get, Json};
use lambda_http::Error;
use serde::Serialize;

#[derive(Serialize)]
pub struct Ping {
message: &'static str,
}

pub async fn ping() -> impl IntoResponse {
(
StatusCode::IM_A_TEAPOT,
Json(Ping {
message: "hello from rust :)",
}),
)
}

#[tokio::main]
pub async fn main() -> Result<(), Error> {
let app = axum::Router::new().route("/", get(ping));
lambda_http::run(app).await
}
8 changes: 8 additions & 0 deletions examples/aws-rust-api/sst-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* tslint:disable */
/* eslint-disable */
import "sst"
declare module "sst" {
export interface Resource {
}
}
export {}
33 changes: 33 additions & 0 deletions examples/aws-rust-api/sst.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
app(input) {
return {
name: "aws-rust-function-url",
removal: input?.stage === "production" ? "retain" : "remove",
home: "aws",
providers: {
aws: { region: 'us-east-1' }
},
};
},
async run() {
const api = new sst.aws.Function("rust-api", {
handler: "bootstrap",
architecture: "arm64", // or x86_64
bundle: "target/lambda/api",
runtime: 'provided.al2023',
url: true,
});
const router = new sst.aws.Router("MyRouter", {
routes: {
"/*": api.url,
},
domain: "rust.dev.sst.dev",
});
return {
function: api.url,
domain: router.url
}
}
});
1 change: 1 addition & 0 deletions examples/aws-rust-api/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}

0 comments on commit 5d350bb

Please sign in to comment.