Lambda quick start

View .md

Create a to-do API, run it locally, then deploy it to AWS and rehearse a rollback. Complete Installation with the .NET 10 SDK first. The local steps need no AWS credentials or Kanject subscription; deployment needs a configured AWS profile. Shell examples use Bash or Zsh.

You'll learn
  • Scaffold a service with kanject new and run it locally with kanject test
  • Read what the template generated, and where the Kanject CLI files live
  • Prepare the dev stage and bind a secret to an environment variable
  • Deploy with kanject aws deploy and rehearse an alias-flip rollback

1. Scaffold the service

bash
kanject new minimal-api --name Acme.Analytics --framework net10.0 --no-parameter-store --yescd Acme.Analytics/src/Acme.Analytics.Api

kanject new runs dotnet new with the template pack bundled in the CLI, then runs kanject init on the Lambda project. You get a to-do API split into Api, Business, Common and Data projects, with integration tests:

bash
Acme.Analytics/├── Acme.Analytics.slnx├── src/│   ├── Acme.Analytics.Api/          ← the Lambda entry: run kanject here│   │   ├── Endpoints/TodoEndpoints.cs│   │   ├── Program.cs│   │   ├── template.json            ← the base SAM template deploy builds on│   │   └── kanject-cli/│   │       ├── manifest.json│   │       ├── manifest.lock.json│   │       └── stages/dev.json│   ├── Acme.Analytics.Business/│   ├── Acme.Analytics.Common/│   └── Acme.Analytics.Data/└── tests/    └── Acme.Analytics.Api.Tests/

The kanject-cli/ folder sits inside the API project, so run every kanject command from src/Acme.Analytics.Api. Building it needs the .NET 10 SDK, which minimal-api targets by default; --framework net8.0 targets .NET 8 instead.

2. Run it locally

bash
kanject test --http --watch --env dev --port 5080

Wait for Ready, then request http://localhost:5080/health in a second terminal; expect Healthy. Open http://localhost:5080/ for Swagger UI. Stop the runner with Ctrl+C, then run dotnet test ../../Acme.Analytics.slnx from the API directory.

bash
curl --fail http://localhost:5080/health

3. Read the endpoints

Endpoints are static classes marked [ApiEndpoints]. Kanject.Core.Api.Annotations generates their route registration at compile time, Program.cs maps them all with one call, and each method's XML comments become its OpenAPI description. Each endpoint hands the work to a Business service.

csharp
[ApiEndpoints("Todos", "todos", RequireAuthorization = false)]public static class TodoEndpoints{    /// <summary>Lists to-do items, oldest first.</summary>    [HttpGet]    public static async Task<Ok<IReadOnlyList<Todo>>> ListTodos(        bool? done, ITodoService todos, CancellationToken cancellationToken) =>        TypedResults.Ok(await todos.ListAsync(done, cancellationToken));​    /// <summary>Returns one to-do item.</summary>    [HttpGet("{id:guid}")]    public static async Task<Results<Ok<Todo>, NotFound>> GetTodo(        Guid id, ITodoService todos, CancellationToken cancellationToken) =>        await todos.FindAsync(id, cancellationToken) is { } todo            ? TypedResults.Ok(todo)            : TypedResults.NotFound();​    // CreateTodo, UpdateTodo and DeleteTodo follow the same shape.}

4. Prepare the dev stage

init wrote kanject-cli/stages/dev.json with names derived from the project:

json
{  "$schema": "../stage.schema.json",  "schemaVersion": 1,  "region": "eu-west-1",  "profile": "default",  "stack": "dev-acme-analytics",  "artifactBucket": "dev-acme-analytics-artifacts",  "env": { "ASPNETCORE_ENVIRONMENT": "Development" },  "entryEnv": {}}

Change the region or profile if yours differ. The CLI never creates the artifact bucket, because that is an account decision, so create it once:

bash
aws s3 mb s3://dev-acme-analytics-artifacts --region eu-west-1 --profile default

Then check the toolchain and the stage before deploying. Fix anything red first.

bash
kanject doctor --env dev

5. Add a secret (optional)

The public minimal API needs no SSM path or JWT secret. If your own application needs a secret, store one in AWS Secrets Manager and bind it to an environment variable:

bash
kanject add secret ANALYTICS_API_KEY \  acme-analytics/dev/api#key \  --value "$(openssl rand -base64 32)" \  --env dev

This creates or updates the secret, stores the value under its JSON key key, and adds ANALYTICS_API_KEY = secret:acme-analytics/dev/api#key to dev.json. Only the reference is committed, never the value. kanject env --env dev shows the binding without fetching the secret.

6. Deploy

bash
kanject aws deploy --env dev​# The API's URL is the stack's ApiURL outputaws cloudformation describe-stacks --stack-name dev-acme-analytics \  --query "Stacks[0].Outputs[?OutputKey=='ApiURL'].OutputValue" --output text --region eu-west-1 --profile default

deploy resolves every param: and secret: reference, builds and deploys the CloudFormation stack, applies the resolved values to the function, publishes a Lambda version, points the live alias at it, and records the release in the deployment ledger in S3. It finishes by printing the stack and the revision it deployed; the template publishes the API's address as the stack output ApiURL.

7. Rehearse a rollback

A rollback needs something to go back to, so ship a second version first. Then roll back while the stakes are low:

bash
# Change something small, then deploy a second versionkanject aws deploy --env dev​# Read the history, then put the first version backkanject aws deployments list --env devkanject aws rollback --env dev --to previous

Rollback points the alias back at the earlier version. Nothing is rebuilt, and that version's code and environment come back together.

Recap
  • kanject new minimal-api scaffolds a to-do API, a .slnx solution and tests, and runs kanject init inside the API project.
  • Run kanject commands from the API project, where kanject-cli/ lives. kanject test --http serves the API locally.
  • The dev stage comes pre-filled; you create its artifact bucket once, and kanject doctor --env dev checks the local configuration. It does not verify bucket access or AWS credentials for this stage.
  • kanject add secret stores a value and commits only its reference.
  • deploy publishes a version and records it in the ledger; rollback flips the alias back with no rebuild.
Was this page helpful?