Deprecated Package Version
Reason: Legacy
Changed to Hardened.Aws namespace
Install
| Product | Versions |
|---|---|
| .NET |
README
Hardened.Amz
Runs Hardened applications on AWS Lambda. The handlers, parameter binding, configuration and tests are the core framework's. This repository supplies what runs underneath: the Lambda runtimes, response streaming, the local emulator session, the test harnesses, a DynamoDB client and CDK constructs.
AWS documentation: ipjohnson.github.io/Hardened.Docs/aws
Start here
The Framework templates generate Lambda projects directly:
dotnet new install Hardened.Templates
dotnet new hardened-web -n Todos --host aws-lambda # web API behind API Gateway
dotnet new hardened-function -n OrderQueue --trigger sqs # SQS batch processor
The first generates the same todo API the Kestrel host does. A Lambda application is an ordinary Hardened application with a runtime module on it, and the module is the only line that differs from the Kestrel bootstrap:
[HardenedModule]
[LambdaWebModule] // [KestrelRuntime] in the Kestrel host
[TodosLibrary]
public partial class Application;
No handler, service or test in the library project knows which of the two it is running under. That is the whole migration.
The function template is a different shape: a handler marked [HardenedFunction] rather than a
route, invoked with the message body bound to its parameter.
[HardenedModule]
[LambdaFunctionModule]
[SqsLambda]
public partial class Application;
public class OrderHandler(OrderLog log) {
[HardenedFunction]
public Task Process(Order order) {
log.Record(order);
return Task.CompletedTask;
}
}
The runtime module is not optional. An application without one compiles, then throws
'Application' is missing [LambdaFunctionModule] the moment it is constructed.
Lambda application types
covers the project shape, handler and test setup for each transport.
Pick your trigger
| You are handling | Module | Runtime package |
|---|---|---|
| HTTP behind API Gateway or a function URL | [LambdaWebModule] |
Hardened.Amz.Web.Lambda.Runtime |
| Direct invocation | [LambdaFunctionModule] |
Hardened.Amz.Function.Lambda.Runtime |
| SQS batches | [LambdaFunctionModule] + [SqsLambda] |
Hardened.Amz.Function.Sqs.Runtime |
| DynamoDB Streams | [LambdaFunctionModule] + [DynamoStreamLambda] |
Hardened.Amz.Function.DDB.Runtime |
SQS and DynamoDB Streams take a second attribute because they are event sources layered on the direct-invoke path. The SQS runtime deserialises each message body into your handler's parameter type and reports partial batch failures, so a throwing handler fails one message rather than the batch.
Every application runs on Amazon.Lambda.RuntimeSupport's bootstrap through a generated Main.
Response streaming is a deployment setting rather than a separate host: with
HARDENED_LAMBDA_RESPONSE_MODE=stream behind a function URL in RESPONSE_STREAM invoke mode,
every response opens a stream at its first body byte, and a handler returning
IAsyncEnumerable<T> writes one chunk per item. Hardened.Amz.Cdk sets the variable and the
invoke mode together; see
Response mode.
Running locally
Run the application project, from the IDE or with dotnet run. When nothing has set
AWS_LAMBDA_RUNTIME_API, the generated Main starts the
AWS Lambda Test Tool
as a child process and points the bootstrap at it. A web application answers on
http://localhost:5080 through the tool's API Gateway emulator, the same address the Kestrel
host uses; a function is invoked from the tool's UI at http://localhost:5050. PORT and
HARDENED_LAMBDA_EMULATOR_PORT move them. The debugger is on the process the Lambda service would
start, running the same Main, bootstrap and event serialiser.
The tool is a dotnet tool, pinned in .config/dotnet-tools.json here and in the templates, so
dotnet tool restore is the only setup. A tool left running by the debugger's stop button is found
and reused by the next start. Until 2026-09-05 this took a second project,
Hardened.Amz.Web.Lambda.Harness, which wrapped the application in ASP.NET Core and never ran
the generated Main; it is gone. The tool has no response streaming, so stream mode is exercised
by the tests below and by a deployment.
Testing without AWS
Each runtime has a matching harness that drives the real pipeline in-process. No deployed function, and no mocked SDK types:
LambdaTestApp(Hardened.Amz.Function.Lambda.Testing) invokes function handlers.TestSqsApp(Hardened.Amz.Function.Sqs.Testing) delivers batches and asserts partial failures.Hardened.Amz.Function.DDB.Testingfeeds stream records.[LocalDynamoDb](Hardened.Amz.DynamoDbClient.Testing) runs DynamoDB in Testcontainers.
See testing AWS handlers and testing conventions.
Clients and infrastructure
Hardened.Amz.DynamoDbClient provides IDynamoDbClientProvider and DynamoDB extensions
(docs). There is no SQS client package β
the SQS runtime consumes a queue; writing to one means taking a direct AWSSDK.SQS dependency.
Hardened.Amz.Cdk carries the CDK constructs
(docs).
All packages ship to nuget.org as Hardened.Amz.*, releasing in step with the Framework's version
line. The full list is in the
package reference.
Building from source
dotnet build Hardened.Amz.sln
dotnet test Hardened.Amz.sln
src/Directory.Build.targets prefers a sibling ../Hardened.Framework checkout over the pinned
packages when one exists, so the two repositories can be edited together. A checkout at an
incompatible commit fails the build with errors in the other repository's files. Force either side
explicitly:
dotnet build Hardened.Amz.sln -p:UseLocalHardenedFramework=false # pinned packages, as CI builds
dotnet build Hardened.Amz.sln -p:UseLocalHardenedFramework=true # sibling checkout
CI adds -p:ContinuousIntegrationBuild=true, which turns warnings into errors β run a build with
it set before opening a pull request. The DynamoDB client tests need a running Docker daemon, and
fail rather than skip without one β see testing conventions.
Related repositories
- Hardened.Framework β the core framework: contracts, routing, DI, testing
- Hardened.Docs β the documentation site
Changes from Previous Version
Adoption Assessment
Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.