Skip to content

Commit 0296371

Browse files
authored
Merge pull request #2937 from kothsidh/kothsidh-feature-lambda-durable-invoke-lambda-sam-python
New serverless pattern - lambda-durable-invoke-lambda-sam-python
2 parents 731ef20 + 0f0fd5e commit 0296371

7 files changed

Lines changed: 367 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Lambda durable functions invoking AWS Lambda function (Python)
2+
3+
This pattern demonstrates how an AWS Lambda durable function can invoke a standard AWS Lambda function using `context.invoke()` from the durable execution SDK. The invocation is automatically checkpointed, so if the durable function is interrupted after the invoked function completes, it resumes with the stored result without re-invoking the target function.
4+
5+
Learn more about this pattern at Serverless Land Patterns: [https://serverlessland.com/patterns/lambda-durable-invoke-lambda-sam-python](https://serverlessland.com/patterns/lambda-durable-invoke-lambda-sam-python)
6+
7+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
8+
9+
## Requirements
10+
11+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
12+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
13+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14+
* [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) (AWS SAM) installed
15+
* Python 3.14
16+
17+
## Deployment Instructions
18+
19+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
20+
```
21+
git clone https://github.com/aws-samples/serverless-patterns
22+
```
23+
1. Change directory to the pattern directory:
24+
```
25+
cd lambda-durable-invoke-lambda-sam-python
26+
```
27+
1. From the command line, use AWS SAM to build and deploy the AWS resources for the pattern as specified in the template.yaml file:
28+
```
29+
sam build
30+
sam deploy --guided
31+
```
32+
1. During the prompts:
33+
* Enter a stack name
34+
* Enter the desired AWS Region (durable functions are available in supported regions)
35+
* Allow SAM CLI to create IAM roles with the required permissions.
36+
37+
Once you have run `sam deploy --guided` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy` in future to use these defaults.
38+
39+
1. Note the outputs from the SAM deployment process. These contain the resource names and/or ARNs which are used for testing.
40+
41+
## How it works
42+
43+
This pattern deploys two Lambda functions:
44+
45+
1. **DurableLambdaFunction** - A durable Lambda function that orchestrates the workflow. It uses the `@durable_execution` decorator and performs two checkpointed operations:
46+
- A `@durable_step` that prepares and validates input values.
47+
- A `context.invoke()` call that invokes the ProcessorFunction and waits for its result.
48+
49+
2. **ProcessorFunction** - A standard Lambda function that receives a list of numeric values and returns computed statistics (sum, average, max, min).
50+
51+
The AWS Lambda durable function uses automatic checkpointing. Each step and invoke operation creates a checkpoint. If the function is interrupted (e.g., due to a transient failure), it replays from the beginning but skips completed checkpoints, resuming execution from where it left off.
52+
53+
54+
## Testing
55+
56+
1. After deployment, invoke the durable function using the alias ARN from the stack outputs:
57+
58+
```bash
59+
aws lambda invoke \
60+
--function-name <DurableLambdaFunctionAliasArn> \
61+
--payload '{"values": [10, 20, 30, 40, 50]}' \
62+
--cli-binary-format raw-in-base64-out \
63+
output.json
64+
```
65+
66+
2. Check the response:
67+
68+
```bash
69+
cat output.json
70+
```
71+
72+
Expected output:
73+
```json
74+
{"statusCode": 200, "body": "{\"message\": \"Durable orchestration completed successfully\", \"input_values\": [10, 20, 30, 40, 50], \"processing_result\": {\"operation\": \"sum_and_average\", \"count\": 5, \"sum\": 150, \"average\": 30.0, \"max\": 50, \"min\": 10}}"}
75+
```
76+
77+
3. Monitor the durable execution steps in the Lambda console under the **Durable executions** tab of the DurableLambdaFunction.
78+
79+
## Cleanup
80+
81+
1. Delete the stack
82+
```bash
83+
sam delete
84+
```
85+
86+
----
87+
Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
88+
89+
SPDX-License-Identifier: MIT-0
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"title": "AWS Lambda durable function invoking an AWS Lambda Function",
3+
"description": "Lambda durable function invokes a standard Lambda function using context.invoke() with automatic checkpointing.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "SAM",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This pattern deploys an AWS Lambda durable function and a standard AWS Lambda function. The durable function uses the durable execution SDK to orchestrate a workflow that prepares input data in a checkpointed step and then invokes the standard Lambda function using context.invoke().",
11+
"The context.invoke() call creates a checkpoint so that if the durable function is interrupted after the invoked function completes, it resumes with the stored result without re-invoking the processor function.",
12+
"This pattern deploys two Lambda functions with the required IAM permissions for durable execution and cross-function invocation."
13+
]
14+
},
15+
"gitHub": {
16+
"template": {
17+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/lambda-durable-invoke-lambda-sam-python",
18+
"templateURL": "serverless-patterns/lambda-durable-invoke-lambda-sam-python",
19+
"projectFolder": "lambda-durable-invoke-lambda-sam-python",
20+
"templateFile": "template.yaml"
21+
}
22+
},
23+
"resources": {
24+
"bullets": [
25+
{
26+
"text": "AWS Lambda durable functions",
27+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html"
28+
},
29+
{
30+
"text": "Durable execution SDK for Python",
31+
"link": "https://github.com/aws/aws-durable-execution-sdk-python"
32+
},
33+
{
34+
"text": "Chained invocations across functions",
35+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-examples.html"
36+
}
37+
]
38+
},
39+
"deploy": {
40+
"text": [
41+
"sam build",
42+
"sam deploy --guided"
43+
]
44+
},
45+
"testing": {
46+
"text": [
47+
"See the GitHub repo for detailed testing instructions."
48+
]
49+
},
50+
"cleanup": {
51+
"text": [
52+
"Delete the stack: <code>sam delete</code>."
53+
]
54+
},
55+
"authors": [
56+
{
57+
"name": "Sidharth Kothari",
58+
"image": "https://drive.google.com/file/d/1sUXFJLHYuCmadcu4Q7mhb0mBnWfTcrtT/view",
59+
"bio": "Cloud Engineer II at AWS with expertise in serverless, GenAI, event-driven and microservice-based applications",
60+
"linkedin": "sidharthkothari"
61+
}
62+
]
63+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
{
2+
"title": "AWS Lambda durable function invoking an AWS Lambda Function",
3+
"description": "Lambda durable function invokes a standard Lambda function using context.invoke() with automatic checkpointing.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "AWS SAM",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This pattern deploys an AWS Lambda durable function and a standard AWS Lambda function. The durable function uses the durable execution SDK to orchestrate a workflow that prepares input data in a checkpointed step and then invokes the standard Lambda function using context.invoke().",
11+
"The context.invoke() call creates a checkpoint so that if the durable function is interrupted after the invoked function completes, it resumes with the stored result without re-invoking the processor function.",
12+
"This pattern deploys two Lambda functions with the required IAM permissions for durable execution and cross-function invocation."
13+
]
14+
},
15+
"gitHub": {
16+
"template": {
17+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/lambda-durable-invoke-lambda-sam-python",
18+
"templateURL": "serverless-patterns/lambda-durable-invoke-lambda-sam-python",
19+
"projectFolder": "lambda-durable-invoke-lambda-sam-python",
20+
"templateFile": "template.yaml"
21+
}
22+
},
23+
"services": {
24+
"from": {
25+
"serviceName": "AWS Lambda",
26+
"serviceURL": "/lambda/"
27+
},
28+
"to": {
29+
"serviceName": "AWS Lambda",
30+
"serviceURL": "/lambda/"
31+
}
32+
},
33+
"patternArch": {
34+
"icon1": {
35+
"x": 20,
36+
"y": 50,
37+
"service": "lambda",
38+
"label": "Lambda durable function"
39+
},
40+
"icon2": {
41+
"x": 80,
42+
"y": 50,
43+
"service": "lambda",
44+
"label": "Lambda function"
45+
},
46+
"line1": {
47+
"from": "icon1",
48+
"to": "icon2"
49+
}
50+
},
51+
"resources": {
52+
"bullets": [
53+
{
54+
"text": "AWS Lambda durable functions",
55+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html"
56+
},
57+
{
58+
"text": "Durable execution SDK for Python",
59+
"link": "https://github.com/aws/aws-durable-execution-sdk-python"
60+
},
61+
{
62+
"text": "Chained invocations across functions",
63+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-examples.html"
64+
}
65+
]
66+
},
67+
"deploy": {
68+
"text": [
69+
"sam build",
70+
"sam deploy --guided"
71+
]
72+
},
73+
"testing": {
74+
"text": [
75+
"See the GitHub repo for detailed testing instructions."
76+
]
77+
},
78+
"cleanup": {
79+
"text": [
80+
"Delete the stack: <code>sam delete</code>."
81+
]
82+
},
83+
"authors": [
84+
{
85+
"name": "Sidharth Kothari",
86+
"image": "https://drive.google.com/file/d/1sUXFJLHYuCmadcu4Q7mhb0mBnWfTcrtT/view",
87+
"bio": "Cloud Engineer II at AWS with expertise in serverless, GenAI, event-driven and microservice-based applications",
88+
"linkedin": "sidharthkothari"
89+
}
90+
],
91+
"patternType": "Serverless"
92+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import json
2+
import os
3+
from aws_durable_execution_sdk_python import (
4+
DurableContext,
5+
StepContext,
6+
durable_execution,
7+
durable_step,
8+
)
9+
10+
PROCESSOR_FUNCTION_NAME = os.environ["PROCESSOR_FUNCTION_NAME"]
11+
12+
13+
@durable_step
14+
def prepare_input(step_ctx: StepContext, raw_values: list) -> dict:
15+
"""Prepare and validate input values before invoking the processor function."""
16+
step_ctx.logger.info("Preparing input values for processing")
17+
return {
18+
"values": raw_values,
19+
"operation": "sum_and_average",
20+
}
21+
22+
23+
@durable_execution
24+
def lambda_handler(event: dict, context: DurableContext) -> dict:
25+
"""Durable function that orchestrates processing by invoking another Lambda."""
26+
raw_values = event.get("values", [10, 20, 30, 40, 50])
27+
context.logger.info("Starting durable orchestration", extra={"values": raw_values})
28+
29+
# Step 1: Prepare the input (checkpointed)
30+
prepared = context.step(prepare_input(raw_values), name="prepare_input")
31+
32+
# Step 2: Invoke the processor Lambda function (checkpointed)
33+
# If the durable function is interrupted after this completes,
34+
# it resumes with the stored result without re-invoking the processor.
35+
result = context.invoke(
36+
function_name=PROCESSOR_FUNCTION_NAME,
37+
payload=prepared,
38+
name="invoke_processor",
39+
)
40+
41+
context.logger.info("Processing complete", extra={"result": result})
42+
43+
return {
44+
"statusCode": 200,
45+
"body": json.dumps({
46+
"message": "Durable orchestration completed successfully",
47+
"input_values": raw_values,
48+
"processing_result": result,
49+
}),
50+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
def lambda_handler(event, context):
2+
"""Standard Lambda function that processes sample values."""
3+
values = event.get("values", [])
4+
operation = event.get("operation", "sum_and_average")
5+
6+
if not values:
7+
return {"error": "No values provided"}
8+
9+
total = sum(values)
10+
average = total / len(values)
11+
maximum = max(values)
12+
minimum = min(values)
13+
14+
return {
15+
"operation": operation,
16+
"count": len(values),
17+
"sum": total,
18+
"average": average,
19+
"max": maximum,
20+
"min": minimum,
21+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
aws-durable-execution-sdk-python==1.3.0
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: >
4+
Serverless pattern - Lambda durable function invoking another AWS Lambda function (Python).
5+
Demonstrates how a Lambda durable function can use context.invoke() to call a standard
6+
Lambda function as a checkpointed step in its workflow.
7+
8+
Globals:
9+
Function:
10+
Timeout: 30
11+
MemorySize: 128
12+
13+
Resources:
14+
# Standard AWS Lambda function that processes sample values
15+
ProcessorFunction:
16+
Type: AWS::Serverless::Function
17+
Properties:
18+
Handler: processor_function.lambda_handler
19+
Runtime: python3.14
20+
CodeUri: src/
21+
22+
# Lambda durable function that orchestrates the workflow
23+
DurableLambdaFunction:
24+
Type: AWS::Serverless::Function
25+
Properties:
26+
Handler: durable_lambda_function.lambda_handler
27+
Runtime: python3.14
28+
CodeUri: src/
29+
Timeout: 600
30+
DurableConfig:
31+
ExecutionTimeout: 600
32+
RetentionPeriodInDays: 7
33+
AutoPublishAlias: live
34+
Environment:
35+
Variables:
36+
PROCESSOR_FUNCTION_NAME: !Ref ProcessorFunction
37+
Policies:
38+
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicDurableExecutionRolePolicy
39+
- LambdaInvokePolicy:
40+
FunctionName: !Ref ProcessorFunction
41+
42+
Outputs:
43+
DurableLambdaFunctionArn:
44+
Description: ARN of Lambda durable function
45+
Value: !GetAtt DurableLambdaFunction.Arn
46+
DurableLambdaFunctionAliasArn:
47+
Description: Alias ARN of the Lambda durable function (use this for invocations)
48+
Value: !Ref DurableLambdaFunction.Alias
49+
ProcessorFunctionArn:
50+
Description: ARN of the processor Lambda function
51+
Value: !GetAtt ProcessorFunction.Arn

0 commit comments

Comments
 (0)