Chris Collins

Tools · cloud

Step Functions workbench

Paste an Amazon States Language definition and see it drawn as a graph, checked for common mistakes, and run step by step with mocked Task results — every InputPath, Parameters, ResultSelector, ResultPath and OutputPath (or JSONata Arguments, Output and Assign) shown with the data it produced, intrinsic functions, variables, Retry with back-off, Catch, timeouts, Parallel and inline or distributed Map.

Added

How to use it

Step Functions definitions are easy to write and hard to reason about: five JSONPath fields reshape the data on its way through every state, a retrier’s back-off decides how long a run takes, and a typo in a path is only found when an execution fails. This page runs the definition in your browser against results you make up, so you can watch the data move without deploying anything.

How to use it

  1. Paste a definition into Definition — plain ASL JSON, the output of aws stepfunctions describe-state-machine (its definition string), or a CloudFormation/SAM template with a state machine resource. Open file… loads one. Or start from an example: input and output processing, Retry and Catch, Choice/Wait with intrinsic functions, Map and Parallel, a distributed Map, JSONata with variables, and a definition full of mistakes.

  2. The Graph draws every state; Parallel branches and Map item processors sit inside their state, Catch transitions are red and dashed, loops go round the right-hand side. Click a state to see its data (or its definition before a run).

  3. The Validator lists errors (what Step Functions would reject), warnings (common mistakes: a path without .$, .$ on a literal, no Default on a Choice, a callback task with no timeout or no task token, unreachable states, endless loops, JSONPath fields in a JSONata state) and notes (AWS’s best practices, such as retrying Lambda service exceptions).

  4. Write the execution input and the mocked task results, then Run (Ctrl/⌘+Enter). Step through the execution: each state shows its input, every processing step with the JSON it produced, the Choice rules it evaluated and why, retries with their waits, the output, what it assigned and the variables in scope.

Mocks

Mocks are keyed by state name, in the shape Step Functions Local uses:

  • {"Charge": {"Return": {"Payload": {…}}}} — what the call returns;

  • {"Charge": {"Throw": {"Error": "Lambda.TooManyRequestsException", "Cause": "…"}}} — an error;

  • a list, or {"0-1": {"Throw": …}, "2": {"Return": …}}, for successive calls (retries included); the last one repeats;

  • "Seconds": 12 on a response makes the call take that long on the simulated clock, so TimeoutSeconds and HeartbeatSeconds fire;

  • a whole Step Functions Local mock configuration file works too (the first test case is used).

A Task with no mock returns something plausible: lambda:invoke wraps its payload as {ExecutedVersion, Payload, StatusCode}, a function ARN echoes its input, SNS and SQS return a message id, anything else {}. A distributed Map with an ItemReader takes its items from the Map state’s own mock. + Tasks adds an empty mock for every Task.

What it implements

  • JSONPath processing: InputPath, Parameters and ResultSelector payload templates with .$ keys, ResultPath (including null and creating missing objects), OutputPath, the Context object (.Execution`, `.State, .Map.Item.Index/Value`, `.Task.Token) and variables ($name). Paths support names, brackets, indices, wildcards, slices, deep scan and filters, as Jayway JsonPath does.

  • Intrinsic functions: all 18, from States.Format (with its \{, \}, \' and \\ escapes) to States.Hash (MD5, SHA-1, SHA-256, SHA-384, SHA-512, computed in the page), nested up to ten deep.

  • JSONata: QueryLanguage at the top or per state, {% %} expressions anywhere in Arguments, Output, Assign, Items, ItemSelector, Condition, Seconds, Timestamp, TimeoutSeconds, Error and Cause; $states.input, .result, .errorOutput and .context; Step Functions' own $partition, $range, $hash, $random(seed), $uuid and $parse; $eval refused, and an undefined result is States.QueryEvaluationError as in the service.

  • Variables: Assign on states, Choice rules and catchers; every expression is evaluated with the values on state entry and the new values appear from the next state; Parallel branches and Map iterations see outer variables, a distributed Map doesn’t.

  • Errors: Retry with IntervalSeconds, MaxAttempts, BackoffRate, MaxDelaySeconds and JitterStrategy (seeded, so runs repeat), Catch with ResultPath or JSONata Output, States.ALL and States.TaskFailed matching as documented, States.Runtime and States.DataLimitExceeded never caught, task and execution timeouts, and the 256 KiB payload limit.

  • Map: inline and distributed, ItemsPath/Items, ItemSelector, ItemBatcher with BatchInput, ItemReader (from the mock), ToleratedFailurePercentage/Count, and ResultWriter (the output becomes the map run’s manifest location).

Everything runs one step at a time on a simulated clock: Map iterations and Parallel branches run one after another, so the order of calls to a shared mock is deterministic. What it doesn’t do: call AWS, check IAM, enforce service quotas beyond those above, or know a real service’s exact response shape — your mocks stand in for that. The engine was checked against the examples in the Step Functions Developer Guide (the tests list which); two of the guide’s own examples have slips (a SHA-1 one digit short, and a Base64Decode result that doesn’t match its input).

For the rest of a serverless design see the AWS architecture builder (diagram, cost and CDK), the EventBridge pattern tester for rules that start executions, serverless sizing for Lambda, SQS and Kinesis numbers, the DynamoDB modeller and the queueing planner. For JSON transformation on its own, jq and the JSON workbench.

Browser support

Any current browser.

Privacy

Definitions, inputs and mocks stay in this browser (saved locally so they survive a reload); a share link carries them in the URL. Nothing is sent to AWS. If a definition uses JSONata, the page loads the jsonata library (2.0.6, MIT, about 25 KB compressed) from jsDelivr — that request carries nothing of yours.

Runs entirely in your browser — network requests go only to the services named on this page.