Skip to content

palpalani/aws-microservices-reference

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

aws-microservices-reference

Reference implementation of three microservices patterns on AWS: Outbox, Idempotency, and Saga. Companion artifact to the FactualMinds blog post Microservices Design Patterns on AWS (2026).

What this is

A working order-fulfillment system across four Lambda-based microservices (Order, Payment, Inventory, Shipping), wired together with DynamoDB Streams, EventBridge, and Step Functions. Deploy it, place an order, watch the saga run, and break a step to see compensation fire.

The point of the repo is to show how the three patterns connect. Each of them shipped many times in isolation — the value here is seeing them work together in one stack.

Patterns demonstrated

Outbox — DynamoDB Streams → EventBridge

The order service writes the order entity and the event record in a single TransactWriteItems call. A DynamoDB stream filtered for pk prefix OUTBOX# invokes the publisher Lambda, which forwards to EventBridge and starts the saga. Trade-off: no separate outbox table, so the orders table holds two row-types, but the transactional write stays trivial. Look at services/order_service/handler.py.

Idempotency — AWS Lambda Powertools

Every saga task uses @idempotent_function with a DynamoDB persistence layer and a JMESPath of idempotency_key. The saga derives a deterministic key per step from the order ID, so the same order replayed end-to-end never double-charges, double-reserves, or double-ships. Trade-off: Powertools adds a ~12 MB layer to your function bundle and one DynamoDB lookup per invocation. Worth it. Look at services/payment_service/handler.py.

Saga — Step Functions Standard

A standard workflow orchestrates payment → inventory → shipping with Retry (full-jitter exponential backoff) and Catch blocks that route to compensation tasks. Compensation runs in reverse order: a shipping failure releases inventory then refunds payment; an inventory failure just refunds payment. Trade-off: orchestration centralises state but introduces a single coordinator (acceptable in 2026 — Step Functions Standard is durable and auditable). Look at state_machines/order_saga.asl.json.

Architecture

See architecture.md for the data-flow diagram and the rationale behind each AWS service choice.

Prerequisites

  • AWS account with permission to create Lambda, DynamoDB, EventBridge, Step Functions, IAM roles, and CloudWatch log groups
  • AWS SAM CLI ≥ 1.130
  • Python 3.12 (only needed for sam build to package the functions)
  • jq (for bin/start-saga.sh)
  • The Powertools layer ARN for your region. The default in template.yaml is the us-east-1 / Python 3.12 / x86_64 layer; substitute your own at deploy time with --parameter-overrides PowertoolsLayerArn=.... The current ARNs are at https://docs.powertools.aws.dev/lambda/python/latest/.

Quickstart

make build
make deploy        # first run is interactive; subsequent runs reuse samconfig.toml
make start-saga    # POSTs a sample order; prints the Step Functions execution ARN
make tail-logs FN=OrderService
make destroy       # tear it all down

Open the printed Step Functions execution ARN in the AWS Console to see the saga visualisation. Force a failure by editing services/inventory_service/handler.py to raise RuntimeError("simulated stock-out") inside _reserve_stock, redeploy, and run make start-saga again — you'll see the RefundPayment compensation branch fire.

What this is NOT

This is a pattern reference, not a production stack. Specifically:

  • Not multi-region. Active-passive replication, route 53 failover, and cross-region DynamoDB global tables are out of scope. See the blog's Bulkhead and multi-region sections.
  • Not multi-account. A real org would split prod / staging / dev across AWS accounts and use VPC Lattice for cross-account service connectivity.
  • No production auth. The API Gateway is open to the internet — add Cognito, an IAM authoriser, or API keys before exposing this anywhere.
  • No chaos / failure-injection tests. The saga is correct on paper; validate it under real failure with FIS or Gremlin before betting a business on it.
  • No DLQ on the EventBridge bus. Attach SQS DLQs to each rule before production traffic.
  • Mocked side-effects. Payment, inventory, and shipping write to DynamoDB instead of calling Stripe / a WMS / a carrier API. Replace the inner functions; keep the wrapping idempotency decorators.

For each gap above, the corresponding pattern in the FactualMinds blog post explains the production-grade fix.

Versions tested

Component Version
AWS SAM CLI 1.130.0
Python 3.12.4
aws-lambda-powertools[tracer] ≥ 3.0
boto3 ≥ 1.34
Powertools Lambda layer AWSLambdaPowertoolsPythonV3-python312-x86_64:6 (us-east-1 default)
Region tested us-east-1

Last updated: 2026-05-02

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors