Skill 116 · AWS Step Functions
Subchapter 116.1
references/architecture-patterns.mdMarkdown5 KBView on GitHub
Some AWS operations and user-defined tasks are asynchronous. The states pattern is: Start Task → initial wait (what is the expected time it takes to complete the task?) → call describe/status API → check result → short wait → loop back.
See assets/polling-loop-wait-check-choice.asl.json
Security: Enable server-side encryption on the
FulfillmentQueue(SSE-SQS or SSE-KMS) and encryption at rest on theOrdersTable(KMS).
Step Functions has no built-in rollback. The saga pattern chains compensating actions in reverse order. Each forward step has a Catch that records which step failed, then routes to the appropriate compensation entry point.
See assets/compensation-saga-pattern.asl.json
Compensation chain: ReserveInventory fails → OrderFailed. ChargePayment fails → ReleaseInventory → OrderFailed. ShipOrder fails → RefundPayment → ReleaseInventory → OrderFailed. Each Catch records $failedStep and $errorInfo. Compensation states use variables from forward steps ($chargeId, $reservedQty) to know what to undo.
Security: Enable encryption at rest (KMS) on the
InventoryTableand any DynamoDB tables this workflow touches, since they hold order and inventory data.
Map and Parallel states can be nested in any order to create multiple layers. The key constraint is understanding variable scope and data flow at each nesting boundary.
See assets/nested-map-parallel-structures.asl.json
See processing-state-inputs-and-outputs.md for details about variable scopes
When calling unreliable external APIs per-item, use ToleratedFailurePercentage on a Map to continue with whatever succeeded, then post-process the results to separate successes from failures. Failed iterations return objects with Error and Cause fields.
See assets/scatter-gather-with-partial-results.asl.json
Key elements:
ToleratedFailurePercentage: 100 lets the Map complete even if every item fails. Lower the threshold to bail out early.$exists(Error) to separate failed from successful iterations.$type/$exists/[] pattern — JSONata returns a single object (not a 1-element array) when exactly one item matches, and undefined when nothing matches.Security: Use TLS for the external API calls and store any API credentials in AWS Secrets Manager. Encrypt at rest (KMS) any data store that holds the per-item inputs or results.
Step Functions has no native mutual exclusion. Use DynamoDB conditional writes as a distributed lock when only one execution should process a given resource at a time. Pattern: acquire lock → do work → release lock, with Catch ensuring release on failure.
See assets/semaphore-concurrency-lock.asl.json
Key elements:
ConditionExpression with attribute_not_exists ensures only one writer wins. The expiresAt check provides stale-lock recovery if an execution crashes without releasing.executionId on the lock item lets ReleaseLock conditionally delete only its own lock.ConditionalCheckFailedException acts as a spin-wait. Tune MaxAttempts and IntervalSeconds based on expected hold time.DoProtectedWork routes to ReleaseLock so the lock is always released. After releasing, CheckWorkResult re-raises the error path.expiresAt to a reasonable TTL (here 15 min). Use a DynamoDB TTL attribute to auto-clean expired locks.Security: The
LocksTablestores customer identifiers, so enable encryption at rest with a customer-managed KMS key (aws/dynamodbor a CMK) for key-rotation control and audit visibility.
Chain multiple .waitForTaskToken states with States.Timeout catches to build escalation: primary approver → manager → auto-reject.
See assets/human-in-the-loop-with-timeout-escalation.asl.json
Security: Enable server-side encryption (KMS) on the escalation SNS topic and the approval SQS queue. Escalation notifications should reference an order ID rather than embedding customer PII or financial amounts in the message body; have recipients look up details through an authorized interface. Restrict SNS topic subscriptions to verified, authorized recipients via the topic access policy, and do not subscribe shared or unmonitored endpoints.
Express workflows are more cost-effective for high volume State Machine Invocations, but don’t support callbacks or long waits. Standard workflows handle those but cost per state transition. Use Express for fast, high-volume ingest and kick off a Standard execution for the long-running tail.
See assets/express-standard-handoff.asl.json
Security: Encrypt at rest (KMS) the data stores both workflows read or write (e.g.
CustomersTable), enable CloudWatch Logs encryption on the Express workflow, and scope each workflow’s execution role to least privilege for the cross-workflowStartExecutioncall.