Skip to content

Ras al jil feature eventbridge scheduler ses abandoned cart notification#2998

Open
ras-al-jil wants to merge 2 commits intoaws-samples:mainfrom
ras-al-jil:ras-al-jil-feature-eventbridge-scheduler-ses-abandoned-cart-notification
Open

Ras al jil feature eventbridge scheduler ses abandoned cart notification#2998
ras-al-jil wants to merge 2 commits intoaws-samples:mainfrom
ras-al-jil:ras-al-jil-feature-eventbridge-scheduler-ses-abandoned-cart-notification

Conversation

@ras-al-jil
Copy link
Copy Markdown

@ras-al-jil ras-al-jil commented Mar 17, 2026

Issue #2999, if available:

Description of changes:
This pattern demonstrates how to use Amazon EventBridge Scheduler to drive per-customer abandoned cart email notifications on an hourly cadence. A Lambda function, invoked by the scheduler, queries a DynamoDB GSI for customers with abandoned carts that have not yet been notified, sends each a personalised HTML email via Amazon SES, and marks the record as notified to prevent duplicate emails. The pattern includes idempotent notification logic, seed test data, a dead-letter queue for failed scheduler invocations, and least-privilege IAM policies scoped to the specific SES identity and DynamoDB table.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Copy link
Copy Markdown
Contributor

@marcojahn marcojahn left a comment

Choose a reason for hiding this comment

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

Hello @ras-al-jil, thank you for your contribution. I've added a few comments, pls review.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can yo please use the latest architecture icons from https://aws.amazon.com/architecture/icons/

  • Especially the DynamoDB one
    A little bit more spacing between the icons will improve readability

Comment on lines +274 to +277
resource "aws_sqs_queue" "scheduler_dlq" {
name = "${var.prefix}-cart-notify-dlq"
message_retention_seconds = 1209600 # 14 days
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The SQS dead-letter queue scheduler_dlq does not have server-side encryption enabled. Failed scheduler invocations routed to this queue may contain event payloads. AWS best practice recommends enabling encryption at rest on all SQS queues. Even it's a demo, it shoud be enabled

Suggested change
resource "aws_sqs_queue" "scheduler_dlq" {
name = "${var.prefix}-cart-notify-dlq"
message_retention_seconds = 1209600 # 14 days
}
resource "aws_sqs_queue" "scheduler_dlq" {
name = "${var.prefix}-cart-notify-dlq"
message_retention_seconds = 1209600 # 14 days
sqs_managed_sse_enabled = true
}

Comment on lines +83 to +96
EventBridge Scheduler (rate 1 hour)
├── on failure ──▶ SQS DLQ
Notification Processor Lambda
├── READ ──▶ DynamoDB (abandoned-carts)
│ query CartAbandoned = "true"
│ filter NotificationSent = "false"
└── SEND ──▶ Amazon SES
per-customer abandoned cart email
then mark NotificationSent = "true"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The ascii chars do not render well. I would suggest combining the flow informations with the architecture diagram (e.g. numbered hints) and add a short description how the architecture works, while describing the flow and linking back to the architecture diagrams with the numbers.

terraform output
```

## How it works
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This can be merged with the architecture -> textual version of the flow in combination with the architecture diagrams

```bash
terraform output
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The README does not include a dedicated section for verifying that the deployment succeeded and resources were created correctly. While the Testing section covers functional testing, there is no guidance on confirming the Terraform deployment outputs, verifying the EventBridge schedule is active, or checking that the DynamoDB table was seeded correctly.

As an example:

  ## Verify Deployment

  After `terraform apply` completes, verify the resources were created:

  1. Confirm the EventBridge schedule is active:
     ```bash
     aws scheduler get-schedule --name $(terraform output -raw schedule_name)
     ```

  2. Confirm the DynamoDB table has seed data:
     ```bash
     aws dynamodb scan --table-name $(terraform output -raw dynamodb_table_name) --select COUNT
     ```
     Expected: `Count: 3`

Comment on lines +30 to +32
```bash
aws ses verify-email-identity --email-address rajilpaloth@gmail.com
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The README and seed test data reference a personal email address (rajilpaloth@gmail.com). While this is the author's own email, pattern consumers may attempt to use it directly, and it exposes personal information in a public repository. Consider using a generic placeholder.

In total three occurences, please remove your personal email and note, that it needs to be changed to the one being used and where. (lines 37-39, 148, 165)

Suggested change
```bash
aws ses verify-email-identity --email-address rajilpaloth@gmail.com
```
```markdown
aws ses verify-email-identity --email-address recipient@example.com
```

Comment on lines +123 to +124
Email = { S = "rajilpaloth@gmail.com" }
CustomerName = { S = "Rajil Paloth" }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The Terraform seed data contains a personal email address (rajilpaloth@gmail.com) hardcoded in the DynamoDB table item. This exposes PII in the repository and may cause confusion for pattern consumers who deploy the pattern as-is.

See the same finding in README.md

@@ -0,0 +1,58 @@
{
"title": "EventBridge Scheduler + SES Integration- Per-customer notification scheduling (abandoned cart, billing reminders)",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"title": "EventBridge Scheduler + SES Integration- Per-customer notification scheduling (abandoned cart, billing reminders)",
"title": "Amazon EventBridge Scheduler to Amazon SES - Per-customer notification scheduling",

@@ -0,0 +1,58 @@
{
"title": "EventBridge Scheduler + SES Integration- Per-customer notification scheduling (abandoned cart, billing reminders)",
"description": "Create a EventBridge scheduler which sends per customer notifcations for abandoned carts and billing reminders using SES.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"description": "Create a EventBridge scheduler which sends per customer notifcations for abandoned carts and billing reminders using SES.",
"description": "Create an Amazon EventBridge Scheduler schedule that sends per-customer notifications for abandoned carts using Amazon SES.",

name = "${var.prefix}-abandoned-carts"
billing_mode = "PAY_PER_REQUEST"
hash_key = "CustomerId"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The DynamoDB table abandoned_carts does not have an explicit server_side_encryption block. While DynamoDB encrypts all tables at rest by default using AWS-owned keys, explicitly configuring encryption is a best practice for patterns that serve as educational examples, as it demonstrates security awareness.

Suggested change
server_side_encryption {
enabled = true # Uses AWS-owned key by default
}

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants