# Deployment

> Serverless Rust on AWS Lambda with S3 as the system of record.

Because compute is stateless and storage is object storage, deployment is serverless by construction: the Rust engine runs as an AWS Lambda over an S3 Iceberg warehouse and scales to zero when idle. Three CLI commands drive it end to end.

## Three commands

Scaffold a repo, configure its deployment, and let CI ship the code:

```bash title="terminal"
rastack init      # template .github/workflows + .rastack/deploy.json
rastack deploy    # configure the deployment; print the one-time stack launch
rastack ci deploy # what CI runs on every push: build + update-function-code
```

`rastack init` writes two thin workflows (`ci.yml` and `deploy-backend.yml`) that call `rastack ci`, plus a `DeployConfig` at `.rastack/deploy.json` — defaulting the GitHub coordinates from your `origin` remote. Run it again any time to reconfigure.

## Infrastructure vs. code

The deploy is split by **what changes, and how often** — which is also what makes it secure. All durable infrastructure is created **once, by a human**; CI does exactly one thing on every push.

| Owned by | What |
| --- | --- |
| CloudFormation (once) | every IAM role, the Cognito pool, the KMS key, the S3 warehouse, the Lambda and its config, SSM |
| `rastack ci` (each push) | a single call — `aws lambda update-function-code` — over GitHub OIDC, no stored keys |

`rastack deploy` prints the one-time `aws cloudformation deploy` for `app.yaml`, the GitHub repo Variables to wire from the stack Outputs (`AWS_DEPLOY_ROLE_ARN`, `AWS_REGION`), and the Lambda's `RASTACK_*` runtime env — it **configures** that step, it does not silently mutate the cloud.

## The CI pipeline

Each phase of `rastack ci` is a pure function of the config, so the workflow YAML stays one line and `rastack ci --plan <phase>` prints the exact commands without running them:

| Phase | What it runs |
| --- | --- |
| `check` | `rastack compile` + `rastack check` — the manifest/graph gate |
| `build` | cross-build the arm64 Lambda, bake the Cognito JWKS in, zip the bundle |
| `deploy` | `build`, then `aws lambda update-function-code` → wait → print the API URL |

> **Note:** The function name and JWKS URL come from the config's stack outputs when wired, or are resolved live from CloudFormation at run time — so the same config works before and after the stack exists.

## Per-tenant scoping

A resource with `access: { scope: "owner" }` partitions its rows under `warehouse/tenants/{sub}/…`, and a Cognito Identity Pool role fences each tenant to its own prefix with the `${cognito-identity.amazonaws.com:sub}` IAM variable — the same partitioning enforced by [access control](https://reactapistack.com/docs/security.md) in the engine.

> **Tip:** The canonical templates live in `deploy/cloudformation/` (`bootstrap.yaml` + `app.yaml`); the full guide is `docs/serverless-deploy.md`.

---

_Source: [https://reactapistack.com/docs/deployment](https://reactapistack.com/docs/deployment) · Full docs as one file: [llms-full.txt](https://reactapistack.com/llms-full.txt)_
