Skip to content

Commit 61d53bd

Browse files
authored
Merge pull request #2951 from luketr03/dynamodb-eventbridge-scheduler
Add DynamoDB to EventBridge Scheduler pattern
2 parents ea74212 + ef39bce commit 61d53bd

4 files changed

Lines changed: 667 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Dynamic Amazon EventBridge Scheduler from Amazon DynamoDB Streams
2+
3+
This pattern demonstrates how to dynamically create, update, and delete Amazon EventBridge Scheduler schedules based on changes in a DynamoDB table using DynamoDB Streams.
4+
5+
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns
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+
16+
## Deployment Instructions
17+
18+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
19+
```
20+
git clone https://github.com/aws-samples/serverless-patterns
21+
```
22+
2. Change directory to the pattern directory:
23+
```
24+
cd serverless-patterns/dynamodb-eventbridge-scheduler
25+
```
26+
3. From the command line, use AWS SAM to build and deploy the AWS resources for the pattern as specified in the template.yml file:
27+
```
28+
sam build
29+
sam deploy --guided
30+
```
31+
4. During the prompts:
32+
* Enter a stack name
33+
* Enter the desired AWS Region
34+
* Allow SAM CLI to create IAM roles with the required permissions.
35+
36+
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.
37+
38+
5. Note the outputs from the SAM deployment process. These contain the resource names and/or ARNs which are used for testing.
39+
40+
## How it works
41+
42+
This pattern creates a serverless solution that automatically manages EventBridge Scheduler schedules based on DynamoDB table changes:
43+
44+
1. **DynamoDB Table** (`ScheduleConfigs`) - Stores schedule configurations with streams enabled
45+
2. **Stream Processor Lambda** - Automatically triggered by DynamoDB Stream events to:
46+
- Create schedules when items are inserted
47+
- Update schedules when items are modified
48+
- Delete schedules when items are removed
49+
3. **EventBridge Scheduler** - Executes schedules at specified times
50+
4. **Target Lambda** - The function invoked by EventBridge Scheduler when schedules fire
51+
5. **Auto-Test Schedule** - Automatically creates a test schedule 2 minutes after deployment
52+
53+
### Architecture Flow
54+
55+
```
56+
User inserts item into DynamoDB
57+
58+
DynamoDB Stream captures change
59+
60+
StreamProcessorFunction triggered
61+
62+
Creates/Updates/Deletes EventBridge Schedule
63+
64+
EventBridge Scheduler invokes TargetLambdaFunction at scheduled time
65+
```
66+
67+
### DynamoDB Item Structure
68+
69+
```json
70+
{
71+
"scheduleId": "unique-schedule-id",
72+
"scheduleExpression": "at(2026-02-15T10:00:00)",
73+
"payload": "{\"key\": \"value\"}",
74+
"enabled": true
75+
}
76+
```
77+
78+
**Required Fields:**
79+
- `scheduleId` (String) - Unique identifier for the schedule
80+
- `scheduleExpression` (String) - EventBridge Scheduler expression (rate, cron, or at)
81+
82+
**Optional Fields:**
83+
- `payload` (String) - JSON string passed to the target Lambda
84+
- `enabled` (Boolean) - Whether the schedule is enabled (default: true)
85+
86+
## Testing
87+
88+
### Verify Auto-Created Test Schedule
89+
90+
After deployment, a test schedule is automatically created that fires 5 minutes later (UTC time):
91+
92+
1. Check if the schedule was created:
93+
```bash
94+
aws scheduler get-schedule --name auto-test-schedule
95+
```
96+
97+
2. View the schedule in EventBridge Console:
98+
- Navigate to EventBridge → Scheduler → Schedules
99+
- Look for `auto-test-schedule`
100+
- Note the "Next invocation" time (displayed in your local timezone)
101+
102+
3. After 5 minutes, check the Target Lambda logs:
103+
```bash
104+
aws logs tail /aws/lambda/ScheduledTaskExecutor --follow
105+
```
106+
107+
**Note:** All schedule times use UTC timezone. EventBridge Scheduler expressions use the format `at(YYYY-MM-DDTHH:MM:SS)` in UTC.
108+
109+
### Create Your Own Schedule
110+
111+
1. Get the DynamoDB table name from the stack outputs:
112+
```bash
113+
aws cloudformation describe-stacks --stack-name <your-stack-name> \
114+
--query 'Stacks[0].Outputs[?OutputKey==`TableName`].OutputValue' \
115+
--output text
116+
```
117+
118+
2. Insert a new schedule (set time to a few minutes in the future in UTC):
119+
```bash
120+
aws dynamodb put-item \
121+
--table-name ScheduleConfigs \
122+
--item '{
123+
"scheduleId": {"S": "my-test-schedule"},
124+
"scheduleExpression": {"S": "at(2026-02-12T20:00:00)"},
125+
"payload": {"S": "{\"message\": \"Hello from my schedule\"}"},
126+
"enabled": {"BOOL": true}
127+
}'
128+
```
129+
130+
**Important:** The time must be in UTC and in the future. To get current UTC time:
131+
```bash
132+
date -u +"%Y-%m-%dT%H:%M:%S"
133+
```
134+
135+
3. Verify the schedule was created:
136+
```bash
137+
aws scheduler get-schedule --name my-test-schedule
138+
```
139+
140+
4. Check StreamProcessor logs to see the creation:
141+
```bash
142+
aws logs tail /aws/lambda/ScheduleStreamProcessor --follow
143+
```
144+
145+
### Update a Schedule
146+
147+
```bash
148+
aws dynamodb update-item \
149+
--table-name ScheduleConfigs \
150+
--key '{"scheduleId": {"S": "my-test-schedule"}}' \
151+
--update-expression "SET scheduleExpression = :expr" \
152+
--expression-attribute-values '{":expr": {"S": "at(2026-02-12T21:00:00)"}}'
153+
```
154+
155+
**Note:** Time must be in UTC and in the future.
156+
157+
### Delete a Schedule
158+
159+
```bash
160+
aws dynamodb delete-item \
161+
--table-name ScheduleConfigs \
162+
--key '{"scheduleId": {"S": "my-test-schedule"}}'
163+
```
164+
165+
Verify deletion:
166+
```bash
167+
aws scheduler get-schedule --name my-test-schedule
168+
# Should return ResourceNotFoundException
169+
```
170+
171+
## Cleanup
172+
173+
1. Delete the stack
174+
```bash
175+
sam delete
176+
```
177+
178+
2. Confirm the stack has been deleted
179+
```bash
180+
aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus"
181+
```
182+
183+
## Resources
184+
185+
- [Amazon EventBridge Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html)
186+
- [DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html)
187+
- [AWS SAM Developer Guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)
188+
189+
This pattern was contributed by Luigi Napoleone Capasso
190+
191+
----
192+
Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
193+
194+
SPDX-License-Identifier: MIT-0
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
{
2+
"title": "Dynamic Amazon EventBridge Scheduler from Amazon DynamoDB Streams",
3+
"description": "Automatically create, update, and delete EventBridge Scheduler schedules based on DynamoDB table changes using DynamoDB Streams.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "AWS SAM",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This pattern demonstrates how to dynamically manage EventBridge Scheduler schedules by storing schedule configurations in a DynamoDB table.",
11+
"When items are inserted, updated, or deleted from the DynamoDB table, a Lambda function is automatically triggered via DynamoDB Streams.",
12+
"The Lambda function then creates, updates, or deletes the corresponding EventBridge Scheduler schedule.",
13+
"When the scheduled time arrives, EventBridge Scheduler invokes the target Lambda function with the configured payload.",
14+
"This pattern includes an auto-test feature that creates a sample schedule 2 minutes after deployment to verify the solution works end-to-end."
15+
]
16+
},
17+
"gitHub": {
18+
"template": {
19+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/dynamodb-eventbridge-scheduler",
20+
"templateURL": "serverless-patterns/dynamodb-eventbridge-scheduler",
21+
"projectFolder": "dynamodb-eventbridge-scheduler",
22+
"templateFile": "template.yaml"
23+
}
24+
},
25+
"resources": {
26+
"bullets": [
27+
{
28+
"text": "Amazon EventBridge Scheduler",
29+
"link": "https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html"
30+
},
31+
{
32+
"text": "DynamoDB Streams",
33+
"link": "https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html"
34+
},
35+
{
36+
"text": "AWS Lambda Event Source Mapping",
37+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html"
38+
},
39+
{
40+
"text": "Schedule expressions for EventBridge Scheduler",
41+
"link": "https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html"
42+
}
43+
]
44+
},
45+
"deploy": {
46+
"text": [
47+
"sam build",
48+
"sam deploy --guided"
49+
]
50+
},
51+
"testing": {
52+
"text": [
53+
"See the GitHub repo for detailed testing instructions."
54+
]
55+
},
56+
"cleanup": {
57+
"text": [
58+
"Delete the stack: <code>sam delete</code>."
59+
]
60+
},
61+
"authors": [
62+
{
63+
"name": "Luigi Napoleone Capasso",
64+
"bio": "Technical Account Manager @ AWS",
65+
"linkedin": ""
66+
}
67+
],
68+
"patternArch": {
69+
"icon1": {
70+
"x": 15,
71+
"y": 50,
72+
"service": "dynamodb",
73+
"label": "Amazon DynamoDB"
74+
},
75+
"icon2": {
76+
"x": 40,
77+
"y": 50,
78+
"service": "lambda",
79+
"label": "AWS Lambda"
80+
},
81+
"icon3": {
82+
"x": 65,
83+
"y": 50,
84+
"service": "eventbridge",
85+
"label": "EventBridge"
86+
},
87+
"icon4": {
88+
"x": 90,
89+
"y": 50,
90+
"service": "lambda",
91+
"label": "AWS Lambda"
92+
},
93+
"line1": {
94+
"from": "icon1",
95+
"to": "icon2",
96+
"label": "streams"
97+
},
98+
"line2": {
99+
"from": "icon2",
100+
"to": "icon3",
101+
"label": "schedules"
102+
},
103+
"line3": {
104+
"from": "icon3",
105+
"to": "icon4",
106+
"label": "invokes"
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)