Core Concepts

View .md

The CLI persists a small set of artifacts and orchestrates AWS calls around them. Once you understand the artifacts and how deploy weaves them together, every command is obvious.

You'll learn
  • Name the artifacts the CLI persists — manifest, lockfile, stage files, deployment ledger
  • Trace how service.name derives every downstream AWS resource name
  • Understand stages and the three forms an env value can take
  • See how cross-repo dependencies and the ledger power sync and rollback

The artifacts

bash
project-root/├── kanject-cli/│   ├── manifest.json              ← service identity + cross-repo deps + stages│   ├── manifest.lock.json         ← pinned commits + content hashes (sync output)│   ├── stages/│   │   ├── dev.json               ← per-stage region/profile/stack/bucket/env│   │   ├── stage.json│   │   └── prod.json│   └── (preview.json)             ← optional: ephemeral-deployment policy└── (s3://<artifactBucket>/_ledger/versions/*.json)   ← deployment history

The first five live in git so reviewers see every change. The deployment ledger lives in S3 so every deploy is auditable independently of the working copy. The per-stage aws-lambda-tools.<stage>.json is regenerated by deploy from inputs — never hand-edit it.

For every field in manifest.json and the stage files, see the Manifest Reference.

Service identity

manifest.json → service.name is the canonical identifier for everything downstream — CloudFormation stack ({stage}-{service}), ECR repository, artifact bucket ({stage}-{service}-artifacts), Parameter Store path (/{service}/{stage}/), and the deployment-ledger prefix all derive from it. The name is normalized: lowercase, hyphens, must start with a letter.

Stages

A stage is a deployment target — typically dev, stage, prod, but the CLI doesn't care: qa-eu, staging-row, canary all work. Every stage in manifest.json → aws.stages needs a matching kanject-cli/stages/<stage>.json pinning region, profile, stack, artifact bucket, parameter-store path, and the env map.

env values come in three flavours:

bash
# Plain string — baked into Lambda env config at deployASPNETCORE_ENVIRONMENT=Development# Parameter Store reference — resolved at deploy timeDATABASE_URL=param:DATABASE_URL# Secrets Manager reference — resolved at deploy timeJWT_SIGNING_KEY=secret:kanject-analytics/dev/jwt#key

References are resolved once at deploy then baked into the Lambda function config. The Lambda runtime never calls Parameter Store / Secrets Manager — it just reads the env var. Cold-starts stay fast.

Cross-repo dependencies

Most teams have shared class libraries living in sibling repos. The traditional <ProjectReference Include="..\..\sibling\Foo.csproj" /> works only on machines with the right relative paths — CI breaks first. Kanject's answer: declare cross-repo deps in manifest.json → dependencies[] with a git URL + ref + project path:

json
"dependencies": [  {    "name": "Kanject.Identity.Data",    "repository": "git@github.com:kanject/kanject-platform.git",    "ref": "main",    "projectPath": "services/identity/src/Kanject.Identity.Data/Kanject.Identity.Data.csproj",    "consumers": ["src/Kanject.Analytics.Api/Kanject.Analytics.Api.csproj"]  }]

kanject sync resolves each ref to a SHA, clones into .kanject/cache/<repo>-<sha>/, pins every dependency/consumer edge in manifest.lock.json, and writes deterministic kanject.g.props / kanject.g.targets imports. Consumer csprojs are never edited and no local NuGet package is created.

See Dependency Sources & Resolution for the full workflow — declaring sources, the lockfile, reproducible CI, and private-repo auth.

Deployment ledger

Every successful kanject aws deploy writes a JSON snapshot to s3://<artifactBucket>/_ledger/versions/<lambda-version>.json recording the published version ARN, timestamp + identity, commit SHA, lockfile hash, and per-env-value hashes. A pointer at _ledger/current.json tracks the latest entry.

The ledger is the source of truth for audit and rollbackkanject aws rollback reads it and flips the alias to a prior immutable artifact without rebuilding. The ledger is append-only; rollback writes a new entry.

What kanject does NOT own

  • dotnet new — kanject calls it, doesn't replace it. Templates are a separate NuGet pack.
  • dotnet build / dotnet test — vanilla. The CLI doesn't proxy them.
  • dotnet lambda deploy-serverless — the deploy backend. Kanject sets up inputs, then calls the AWS-supplied tool.
  • Your CloudFormation template — kanject orchestrates the deploy, but serverless.template is yours.
  • Your CI provider — pipeline init scaffolds CodePipeline; if you want GitHub Actions or GitLab, you write the workflow.
  • Your code — kanject never edits anything in src/.
Recap
  • The CLI persists a small artifact set in git, plus an append-only deployment ledger in S3.
  • manifest.json → service.name is the canonical id every AWS resource name derives from.
  • env values are plain strings, param: references, or secret: references — resolved once at deploy, then baked into Lambda config.
  • sync turns cross-repo <ProjectReference>s into pinned packages; the ledger powers audit and alias-flip rollback.
Was this page helpful?