Skip to content

Add lambda.DurableFunction blueprint (vs2026)#2445

Open
GarrettBeatty wants to merge 4 commits into
durabletesting2from
gcbeatty/durable-function-blueprint
Open

Add lambda.DurableFunction blueprint (vs2026)#2445
GarrettBeatty wants to merge 4 commits into
durabletesting2from
gcbeatty/durable-function-blueprint

Conversation

@GarrettBeatty

@GarrettBeatty GarrettBeatty commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Provides two dotnet new templates under Blueprints/BlueprintDefinitions/vs2026 for Lambda durable execution workflows, following the existing lambda.* / serverless.* convention (e.g. SimpleS3Function / SimpleS3FunctionServerless):

Template Programming model Deploys via Ships
lambda.DurableFunction Static wrapper (DurableFunction.WrapAsync), class-library dotnet lambda deploy-function no CloudFormation
serverless.DurableFunction Annotations ([LambdaFunction] + [DurableExecution]) dotnet lambda deploy-serverless serverless.template

Both target the managed dotnet10 runtime (durable execution requires dotnet10) and scaffold the same sample ProcessOrder workflow demonstrating the core durable primitives:

  • StepAsync — checkpointed step
  • StepAsync + RetryStrategy.Exponential with StepSemantics.AtMostOncePerRetry
  • WaitAsync — suspend timer (no compute charge while suspended)
  • RunInChildContextAsync — grouping related steps

Each ships a test project that drives the workflow locally via Amazon.Lambda.DurableExecution.Testing (no AWS resources needed). vs2026 only (matches the existing layout convention).

Why two templates

The original single blueprint was labeled lambda.DurableFunction but shipped a serverless.template and deployed via deploy-serverless — a naming/convention mismatch. This splits it so the lambda.* name actually deploys straight to Lambda, and the CloudFormation path keeps its own serverless.* name.

Using the templates

lambda.DurableFunction — deploy straight to Lambda

dotnet new lambda.DurableFunction --name MyDurableApp
cd MyDurableApp/src/MyDurableApp
dotnet lambda deploy-function
  • Class-library static-wrapper model: Handler delegates to DurableFunction.WrapAsync<OrderRequest, OrderResult>(ProcessOrder, …); the serializer is declared with [assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]. No Main, no [DurableExecution], no serverless.template.
  • aws-lambda-tools-defaults.json carries function-runtime: dotnet10, the Assembly::Type::Method function-handler, and durable-execution-timeout.
  • When deploy-function creates the execution role for you, it auto-attaches AWSLambdaBasicDurableExecutionRolePolicy (the checkpoint permissions). If you pass --function-role, attach that policy yourself.
  • Requires the deploy-function durable support from aws-extensions-for-dotnet-cli PR #447 (the durable-execution-timeout switch + IAM auto-attach). Until that ships in a released Amazon.Lambda.Tools, deploy-function won't apply the durable config.

serverless.DurableFunction — deploy via CloudFormation

dotnet new serverless.DurableFunction --name MyDurableApp
cd MyDurableApp/src/MyDurableApp
dotnet lambda deploy-serverless
  • Annotations model: annotate the workflow with [LambdaFunction] + [DurableExecution]. The source generator emits the handler wrapper and keeps serverless.template in sync — DurableConfig plus the AWSLambdaBasicDurableExecutionRolePolicy managed policy.
  • No CLI dependency beyond a published Amazon.Lambda.Annotations that supports [DurableExecution].

Run the local tests (either template)

dotnet test

Testing

  • ✅ Both template projects build on net10.0; both test projects pass (2/2 each), no warnings.
  • lambda.DurableFunction instantiated (placeholder substitution) and built against the published durable preview packages.
  • End-to-end on real AWS (managed dotnet10): deployed the instantiated lambda.DurableFunction with the PR Running dotnet lambda list-functions results in Error listing Lambda functions: Request headers must contain only ASCII characters. #447 CLI build → DurableConfig.ExecutionTimeout set, AWSLambdaBasicDurableExecutionRolePolicy auto-attached to the tool-created role, and the workflow ran to SUCCEEDED (all six operations checkpointed, including the WaitAsync suspend/resume). Resources torn down afterward.

Notes

  • lambda.DurableFunction is gated on aws-extensions-for-dotnet-cli PR #447 landing in a released Amazon.Lambda.Tools.
  • Amazon.Lambda.DurableExecution / .Testing are preview packages; the templates reference 0.1.1-preview / 0.0.1-preview. Restores once those are published (or via a local feed).
  • Blueprint-only change — no .autover change file needed (autover tracks Libraries/src projects only).

Adds a new 'dotnet new' template (shortName: lambda.DurableFunction) under
Blueprints/BlueprintDefinitions/vs2026 that scaffolds a Lambda durable
execution workflow using the Annotations class-library programming model on
the managed dotnet10 runtime.

The sample workflow demonstrates the core durable primitives: StepAsync, a
step with an exponential RetryStrategy and AtMostOncePerRetry semantics,
WaitAsync (suspend timer), and RunInChildContextAsync. The generated
serverless.template includes DurableConfig and the
AWSLambdaBasicDurableExecutionRolePolicy managed policy. A test project drives
the workflow locally via Amazon.Lambda.DurableExecution.Testing.

Also registers the template in Blueprints/README.md.
@GarrettBeatty GarrettBeatty added the Release Not Needed Add this label if a PR does not need to be released. label Jun 26, 2026
<PackageReference Include="Amazon.Lambda.Core" Version="3.1.1" />
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="3.0.0" />
<PackageReference Include="Amazon.Lambda.Annotations" Version="2.0.1" />
<PackageReference Include="Amazon.Lambda.DurableExecution" Version="0.1.1-preview" />

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will update to ga version once released

<ItemGroup>
<PackageReference Include="Amazon.Lambda.Core" Version="3.1.1" />
<PackageReference Include="Amazon.Lambda.TestUtilities" Version="4.1.0" />
<PackageReference Include="Amazon.Lambda.DurableExecution.Testing" Version="0.0.1-preview" />

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this pr isnt merged yet, i tested with local nuget feed.


  # 1. Pack the three required packages into a local feed
  FEED=/tmp/durable-feed && mkdir -p "$FEED"
  cd Libraries/src/Amazon.Lambda.Annotations            && dotnet pack -c Release -o "$FEED"
  cd ../Amazon.Lambda.DurableExecution                  && dotnet pack -c Release -o "$FEED"
  cd ../Amazon.Lambda.DurableExecution.Testing          && dotnet pack -c Release -o "$FEED"

  # 2. Install the template from the blueprint folder
  cd <repo>/Blueprints/BlueprintDefinitions/vs2026/DurableFunction/template/src/BlueprintBaseName.1
  dotnet new install .    # or install from the .template.config location

  # 3. Instantiate into a scratch dir
  mkdir /tmp/dtest && cd /tmp/dtest
  dotnet new lambda.DurableFunction --name MyOrders

  # 4. Build + test against the local feed
  dotnet test --source "$FEED" --source https://api.nuget.org/v3/index.json

@GarrettBeatty GarrettBeatty marked this pull request as ready for review June 29, 2026 17:02
@GarrettBeatty GarrettBeatty requested review from a team as code owners June 29, 2026 17:02
@GarrettBeatty GarrettBeatty requested review from normj and philasmar and removed request for a team June 29, 2026 17:02
@@ -0,0 +1,39 @@
{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intentionally only added to vs2026. didnt feel like it was worth adding to 2024 folder since dotnet8 will be end of life soon

@GarrettBeatty

Copy link
Copy Markdown
Contributor Author

The test project isn't actually bundled when doing a new project (same with other projects) but adding here to be consistent

@normj normj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern of the template library is templates that start with the lambda. prefix deploy directory to Lambda. For example using the dotnet lambda deploy-function command. For templates that deploy via CloudFormation start with serverless. and you would deploy via the dotnet lambda deploy-serverless command.

I suggest we have 2 templates. One that goes directly to Lambda and uses the static wrapper method instead of annotations so it can be deploy straight to Lambda. Then a second serverless.* template that is what you have here.

@normj

normj commented Jun 30, 2026

Copy link
Copy Markdown
Member

The test project isn't actually bundled when doing a new project (same with other projects) but adding here to be consistent

The test project is still useful when you create the template via Visual Studio.

@philasmar philasmar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving assuming you address norm's feedback

The single DurableFunction blueprint was labeled `lambda.DurableFunction` but
shipped a serverless.template and deployed via `deploy-serverless` (the
Annotations model) — a naming/convention mismatch. Follow the
SimpleS3Function / SimpleS3FunctionServerless pattern and provide both:

- DurableFunction (lambda.DurableFunction): deploys straight to Lambda with
  `dotnet lambda deploy-function`. Uses the static-wrapper, class-library
  programming model (DurableFunction.WrapAsync + [assembly: LambdaSerializer],
  no [DurableExecution], no serverless.template). aws-lambda-tools-defaults.json
  carries function-handler/function-runtime and the new durable-execution-timeout
  key. (Requires the deploy-function durable support from
  aws-extensions-for-dotnet-cli PR #447.)

- DurableFunctionServerless (serverless.DurableFunction): the existing
  Annotations + serverless.template blueprint, relabeled to the serverless.*
  identity and deployed via `dotnet lambda deploy-serverless`.

Both build and their test projects pass. The lambda.DurableFunction variant was
verified end-to-end on the managed dotnet10 runtime (DurableConfig set, durable
IAM policy auto-attached, workflow runs to SUCCEEDED).
@GarrettBeatty

Copy link
Copy Markdown
Contributor Author

@normj updated to have two templates and i retested both

@GarrettBeatty GarrettBeatty requested a review from normj June 30, 2026 15:51
@GarrettBeatty

Copy link
Copy Markdown
Contributor Author

aws/aws-extensions-for-dotnet-cli#447 needs to be merged and released first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Release Not Needed Add this label if a PR does not need to be released.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants