Bean & Bark: your first deploy
Bean & Bark's wholesale orders arrive by DM and spreadsheet, and the roastery's first tasting for retail buyers is Thursday. Nadia wants orders coming through an API before then. You have a fresh laptop, an AWS dev account, and one command surface. This is where you learn the thing the CLI is built around: a deploy isn't done when the code is up — it's done when the deployment ledger has recorded exactly what shipped.
- Scaffold a deploy-ready .NET service — solution, manifest, stages, tests — with one
kanject new - Prove your machine is ready with
kanject doctor, entirely offline - Deploy to a
devstage and follow the phase ladder torecord ledger - Predict every AWS resource name from two words: the service name and the stage
One command, a whole service
kanject new scaffolds from a template that ships inside the CLI — no feed, no license, nothing to authenticate. webapi gives you an ASP.NET Core REST API on AWS Lambda with a wired xUnit project, and --yes accepts the template prompts so it runs clean in one go.
# One command: a deploy-ready servicekanject new webapi --name BeanAndBark.Orders --yes When it finishes you have a working tree, not a stub: the solution and csproj, kanject-cli/manifest.json (the service's identity), a stage file each for dev, stage, and prod under kanject-cli/stages/, and the test project. new also runs kanject init for you, so the project is already wired — you never run init on a fresh scaffold.
Prove the machine is ready
Before anything touches AWS — a guess. doctor is about to run its checks: how many of them need AWS credentials? Run it and count.
kanject doctor Kanject Doctor ───────────────────────────────────────────────── Check Status Code Fix ✓ dotnet 10.0.100 ok - - ✓ global tools on PATH (~/.dotnet/tools) ok - - ✓ kanject-cli/manifest.json (schema v2) ok - - ✓ Amazon.Lambda.Tools installed ok - - ✓ kanject-cli/manifest.lock.json in sync (no deps) ok - - ok 5 warn 0 error 0 The answer is none. Without --env, every check is offline: the .NET SDK version, the global-tools PATH, the manifest, the Lambda tooling, the lockfile. Doctor only calls AWS when you hand it a stage (kanject doctor --env dev) — so "is my laptop set up right?" and "is my AWS config right?" are separate questions you can ask separately. The exit code is honest too: warnings keep it 0; only a red ✗ row makes it 1.
Point dev at your AWS
Open kanject-cli/stages/dev.json. A stage is the whole answer to "where does this deploy?" — region, profile, stack, artifact bucket:
{ "schemaVersion": 1, "region": "eu-west-1", "profile": "default", "stack": "dev-beanandbark-orders", "artifactBucket": "dev-beanandbark-orders-artifacts", "env": { "ASPNETCORE_ENVIRONMENT": "Development" }} Look at the names. You never chose them — they're derived: service beanandbark-orders + stage dev gives stack dev-beanandbark-orders, bucket dev-beanandbark-orders-artifacts, and (when you add parameters later) the SSM path /beanandbark-orders/dev/. Two words predict every resource name, on every stage, forever.
Ship it
kanject aws deploy --env dev Deploy stage dev ────────────────────────────────────────────── ✓ sync deps (no deps) ✓ resolve env 1 key ✓ prepare artifacts ✓ write deploy config ✓ render provider artifacts ✓ deploy Lambda ok ✓ promote revision 1 → live ✓ record ledger s3 snapshot written ✓ Deployed dev-beanandbark-orders (Lambda) @ revision 1 Read the ladder from the bottom up, because the last two phases are the point. promote revision published a Lambda version and flipped the live alias to it — that number 1 is real, and it's about to matter. record ledger wrote a JSON snapshot to s3://dev-beanandbark-orders-artifacts/_ledger/versions/1.json: what shipped, who shipped it, the git commit, and content hashes of the lockfile and every resolved config value. And the ordering is a guarantee: if any phase fails, no ledger entry is written. The ledger never claims a deploy that didn't finish.
Read it back
Don't take the terminal's word for it — ask the ledger:
Deployments stage dev ───────────────────────────────────────── Revision Target Deployed Commit Status By 1 Lambda 2026-07-07 09:26 9f3c1ab ✓ stable you@beanandbark One revision, target Lambda, your commit, status stable, your name on it. Every deploy from now on — including Thursday's panicked ones — appends a row here. When something goes wrong, this table is where the recovery starts.
kanject new webapi --name <Name> --yesscaffolds a deploy-ready service — solution, manifest, three stage files, tests — and runsinitfor you.kanject doctorwithout--envis fully offline; only errors (not warnings) flip its exit code to 1.- Stage + service name derive every resource:
dev-beanandbark-orders,…-artifacts,/beanandbark-orders/dev/. The artifact bucket is the one thing you create yourself. - A deploy ends by publishing a Lambda version, flipping the
livealias, and writing an append-only ledger snapshot — and a failed deploy writes no ledger entry.
deploy Lambda phase. What does the deployment ledger show afterwards?Show solution
kanject aws deploy --env dev --dry-run beanandbark-roastery) with a qa stage. Without scaffolding anything: what are its CloudFormation stack, artifact bucket, and SSM parameter path?Show solution
qa-beanandbark-roastery, bucket qa-beanandbark-roastery-artifacts, SSM path /beanandbark-roastery/qa/. Two words really do predict everything — which is why teammates can find each other's resources without asking.