aws-step-functions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

AWS Step Functions

AWS Step Functions

Overview

概述

AWS Step Functions uses Amazon States Language (ASL) to define state machines as JSON. With AWS Step Functions, you can create workflows, also called state machines, to build distributed applications, automate processes, orchestrate microservices, and create data and machine learning pipelines.
This skill provides comprehensive guidance for writing state machines in ASL, covering:
  • ASL structure and JSONata expression syntax
  • Details on the eight available workflow states
  • The
    $states
    reserved variable
  • Workflow variables with
    Assign
  • Error handling
  • AWS Service integration patterns
  • Example code for data transformation and architecture
  • Validation and testing of state machines
  • How to migrate from JSONPath to JSONata
The AWS MCP server is recommended for sandboxed execution and audit logging when following this skill, but all steps use AWS CLI syntax and work without it.
AWS Step Functions 使用 Amazon States Language (ASL) 以JSON格式定义状态机。借助AWS Step Functions,您可以创建工作流(也称为状态机),以构建分布式应用、自动化流程、编排微服务以及创建数据与机器学习管道。
本技能提供了编写ASL状态机的全面指导,涵盖:
  • ASL结构与JSONata表达式语法
  • 八种可用工作流状态的详细说明
  • $states
    保留变量
  • 使用
    Assign
    定义工作流变量
  • 错误处理
  • AWS服务集成模式
  • 数据转换与架构的示例代码
  • 状态机的验证与测试
  • 如何从JSONPath迁移至JSONata
遵循本技能操作时,推荐使用AWS MCP服务器进行沙箱执行与审计日志记录,但所有步骤均使用AWS CLI语法,无需MCP服务器也可运行。

When to Load Reference Files

何时加载参考文件

Load the appropriate reference file based on what the user is working on:
  • ASL structure, state types, Task, Pass, Choice, Wait, Succeed, Fail, Parallel, Map → see
    references/asl-state-types.md
  • Error handling, troubleshooting, Retry, Catch, fallback, error codes, States.Timeout, States.ALL → see
    references/error-handling.md
  • Service integrations, Lambda invoke, DynamoDB, SNS, SQS, SDK integrations, Resource ARN, sync, async → see
    references/service-integrations.md
  • Migrating from JSONPath to JSONata, migration, JSONPath to JSONata, InputPath, Parameters, ResultSelector, ResultPath, OutputPath, intrinsic functions, Iterator, payload template → see
    references/migrating-from-jsonpath-to-jsonata.md
  • Validation, linting, testing, TestState, test state, mock, mocking, unit test, inspection level, DEBUG, TRACE, validate state, test in isolation → see
    references/validation-and-testing.md
  • Architecture patterns, examples, polling, saga, compensation, scatter-gather, semaphore, lock, human-in-the-loop, escalation, Express to Standard → see
    references/architecture-patterns.md
  • Data transformation, JSONata expressions, filtering, aggregation, string operations, $reduce, $lookup, $toMillis, $partition, $parse, $hash, $uuid → see
    references/transforming-data.md
  • State input/output, $states, Assign, Output, Arguments, variable scope, variable limits, evaluation order, passing data between states → see
    references/processing-state-inputs-and-outputs.md
根据用户的工作内容加载相应的参考文件:
  • ASL结构状态类型TaskPassChoiceWaitSucceedFailParallelMap → 查看
    references/asl-state-types.md
  • 错误处理故障排查RetryCatch回退错误代码States.TimeoutStates.ALL → 查看
    references/error-handling.md
  • 服务集成Lambda调用DynamoDBSNSSQSSDK集成资源ARNsyncasync → 查看
    references/service-integrations.md
  • 从JSONPath迁移至JSONata迁移JSONPath转JSONataInputPathParametersResultSelectorResultPathOutputPath内置函数Iterator负载模板 → 查看
    references/migrating-from-jsonpath-to-jsonata.md
  • 验证代码检查测试TestState测试状态模拟单元测试检查级别DEBUGTRACE验证状态隔离测试 → 查看
    references/validation-and-testing.md
  • 架构模式示例轮询saga补偿分散-聚合信号量人工介入升级Express转Standard → 查看
    references/architecture-patterns.md
  • 数据转换JSONata表达式过滤聚合字符串操作$reduce$lookup$toMillis$partition$parse$hash$uuid → 查看
    references/transforming-data.md
  • 状态输入/输出$statesAssignOutputArguments变量作用域变量限制求值顺序状态间数据传递 → 查看
    references/processing-state-inputs-and-outputs.md

Quick Reference

快速参考

Standard vs Express Workflows

Standard与Express工作流对比

StandardExpress
Max duration1 year5 minutes
Execution semanticsExactly-onceAt-least-once (async) / At-most-once (sync)
Execution historyRetained 90 days, queryable via APICloudWatch Logs only
Max throughput2,000 exec/sec100,000 exec/sec
Pricing modelPer state transitionPer execution count + duration
.sync
/
.waitForTaskToken
SupportedNot supported
Best forAuditable, non-idempotent operationsHigh-volume, idempotent event processing
Choose Standard for: payment processing, order fulfillment, compliance workflows, anything that must never execute twice.
Choose Express for: IoT data ingestion, streaming transformations, mobile backends, high-throughput short-lived processing.
When recommending Express, the single limitation you must always state — even for fire-and-forget / high-throughput pipelines — is that Express does NOT support
.sync
or
.waitForTaskToken
(no callbacks, no nested
.sync
waits, no human-approval or job-completion waits). Also note: 5-minute max duration, no queryable execution history (CloudWatch Logs only), and at-least-once (async) / at-most-once (sync) execution — so non-idempotent work can run twice. If any of these matter, choose Standard (exactly-once, up to 1 year, full history).
特性StandardExpress
最长持续时间1年5分钟
执行语义恰好一次至少一次(异步)/至多一次(同步)
执行历史保留90天,可通过API查询仅存储于CloudWatch Logs
最大吞吐量2000次执行/秒100000次执行/秒
定价模型按状态转换次数计费按执行次数+持续时间计费
支持
.sync
/
.waitForTaskToken
适用场景可审计、非幂等操作高吞吐量、幂等事件处理
选择Standard的场景:支付处理、订单履行、合规工作流等任何绝对不能重复执行的操作。
选择Express的场景:IoT数据采集、流转换、移动后端、高吞吐量短生命周期处理。
推荐Express时必须说明的唯一限制——即便是用于“即发即弃”或高吞吐量管道——Express 不支持
.sync
.waitForTaskToken
(无回调、无嵌套
.sync
等待、无人工审批或作业完成等待)。此外需注意:最长持续时间为5分钟,无可查询的执行历史(仅CloudWatch Logs),执行语义为至少一次(异步)/至多一次(同步)——因此非幂等工作可能会运行两次。如果上述任何限制对您的场景有影响,请选择Standard(恰好一次执行、最长1年、完整历史记录)。

Setting the State Machine Query Language

设置状态机查询语言

JSONata is the preferred way to reference and transform data in ASL. It replaces the five JSONPath I/O fields (
InputPath
,
Parameters
,
ResultSelector
,
ResultPath
,
OutputPath
) with just two:
Arguments
(inputs) and
Output
.
Enable at the top level to apply to all states:
json
{ "QueryLanguage": "JSONata", "StartAt": "...", "States": {...} }
Or per-state to migrate from JSONPath incrementally:
json
{ "Type": "Task", "QueryLanguage": "JSONata", ... }
JSONPath is supported and is the default if
QueryLanguage
is omitted — existing state machines do not need to be migrated.
Field mapping (JSONPath → JSONata):
JSONPath fieldJSONata equivalent
Parameters
(keys use
key.$
)
Arguments
— drop the
.$
suffix and wrap each value in
{% %}
ResultSelector
and
OutputPath
Output
(reference the raw result via
$states.result
)
ResultPath
Assign
(preferred) or
Output
InputPath
not needed — reference
$states.input
directly
A state uses one query language, not both. Never mix JSONPath fields (
InputPath
/
Parameters
/
ResultSelector
/
ResultPath
/
OutputPath
) with JSONata fields (
Arguments
/
Output
) in the same state — this is the most common migration error. See
references/migrating-from-jsonpath-to-jsonata.md
for full details.
JSONata是ASL中引用和转换数据的首选方式。它将五个JSONPath输入输出字段(
InputPath
Parameters
ResultSelector
ResultPath
OutputPath
)替换为仅两个字段:
Arguments
(输入)和
Output
在顶层启用以应用于所有状态:
json
{ "QueryLanguage": "JSONata", "StartAt": "...", "States": {...} }
或按状态启用以逐步从JSONPath迁移:
json
{ "Type": "Task", "QueryLanguage": "JSONata", ... }
JSONPath受支持,若省略
QueryLanguage
则默认使用JSONPath——现有状态机无需迁移。
字段映射(JSONPath → JSONata):
JSONPath字段JSONata等效字段
Parameters
(键使用
key.$
Arguments
—— 去掉
.$
后缀并将每个值包裹在
{% %}
ResultSelector
OutputPath
Output
(通过
$states.result
引用原始结果)
ResultPath
Assign
(首选)或
Output
InputPath
无需使用——直接引用
$states.input
一个状态仅使用一种查询语言,不可混用。 切勿在同一状态中同时使用JSONPath字段(
InputPath
/
Parameters
/
ResultSelector
/
ResultPath
/
OutputPath
)与JSONata字段(
Arguments
/
Output
)——这是最常见的迁移错误。详细信息请查看
references/migrating-from-jsonpath-to-jsonata.md

How Assign and Output Are Evaluated (Parallel, Not Sequential)

Assign与Output的求值方式(并行,而非顺序)

Within a single state,
Assign
and
Output
are evaluated at the same time — in parallel — both reading the same data (the state input plus the task result). They are NOT evaluated one after the other. Because they run together, a variable you set in
Assign
is not visible in that same state's
Output
: there is no ordering in which
Output
could observe the just-assigned value. The assigned value becomes available only to subsequent states.
So if you set a variable in
Assign
and reference it in the same state's
Output
, you get the old/undefined value — not because
Output
runs "before"
Assign
, but because both evaluate concurrently from the same snapshot. To use the value immediately, reference it in the next state (variables persist across states); to shape the current state's output from the task result, use
$states.result
directly in
Output
.
在单个状态内,
Assign
Output
同时求值——并行执行——均读取相同的数据(状态输入加上任务结果)。它们并非按顺序求值。由于二者同时运行,您在
Assign
中设置的变量不会在同一状态的
Output
中可见:不存在
Output
可以观测到刚赋值的变量的顺序。赋值后的变量仅对后续状态可用。
因此,如果您在
Assign
中设置变量并在同一状态的
Output
中引用它,您将得到旧值/未定义值——并非因为
Output
Assign
之前运行,而是因为二者从同一快照并发求值。要立即使用该值,请在下一个状态中引用它(变量在状态间持久化);要根据任务结果调整当前状态的输出,请在
Output
中直接使用
$states.result

Unit Testing a State with TestState

使用TestState对单个状态进行单元测试

Test a single state without deploying the state machine or calling the real service using the TestState API (
aws stepfunctions test-state
) with
--mock
. A complete answer covers all four points:
  • Mock the service response exactly — the
    --mock
    result
    MUST match the target AWS service's API response schema exactly (field names are case-sensitive). For a Lambda
    invoke
    Task that is
    StatusCode
    and
    Payload
    :
    --mock '{"result":"{\"StatusCode\":200,\"Payload\":{...}}"}'
    .
  • All three inspection levels (
    --inspection-level
    ):
    INFO
    (default —
    output
    ,
    status
    ,
    nextState
    ),
    DEBUG
    (adds data flow:
    afterArguments
    ,
    result
    ,
    variables
    — use to debug JSONata/data flow),
    TRACE
    (adds raw HTTP
    request
    /
    response
    , for HTTP Task).
  • .sync
    and
    .waitForTaskToken
    integrations still require a mock
    — for
    .sync
    , mock the polling API (e.g.
    DescribeExecution
    , not the initial call); for
    .waitForTaskToken
    , also pass
    --context '{"Task":{"Token":"..."}}'
    .
  • No deployment or real invocation is needed — the state is tested in isolation.
See
references/validation-and-testing.md
for per-service mock structures and error/retry/Map/Parallel testing.
使用带
--mock
参数的TestState API(
aws stepfunctions test-state
)测试单个状态无需部署状态机或调用真实服务。完整的测试方案需涵盖以下四点:
  • 精确模拟服务响应——
    --mock
    result
    必须完全匹配目标AWS服务的API响应架构(字段名称区分大小写)。对于返回
    StatusCode
    Payload
    的Lambda
    invoke
    任务:
    --mock '{"result":"{\"StatusCode\":200,\"Payload\":{...}}"}'
  • 三种检查级别
    --inspection-level
    ):
    INFO
    (默认——包含
    output
    status
    nextState
    )、
    DEBUG
    (添加数据流:
    afterArguments
    result
    variables
    ——用于调试JSONata/数据流)、
    TRACE
    (添加原始HTTP
    request
    /
    response
    ,适用于HTTP任务)。
  • .sync
    .waitForTaskToken
    集成仍需模拟
    ——对于
    .sync
    ,模拟轮询API(例如
    DescribeExecution
    ,而非初始调用);对于
    .waitForTaskToken
    ,还需传递
    --context '{"Task":{"Token":"..."}}'
  • 无需部署或真实调用——状态是隔离测试的。
每个服务的模拟结构以及错误/重试/Map/Parallel测试的详细信息,请查看
references/validation-and-testing.md

Best Practices

最佳实践

  • Set
    "QueryLanguage": "JSONata"
    at the top level for new state machines unless the user wants to use JSONPath
  • Keep
    Output
    minimal — only include what the state immediately after the current state needs
  • Use
    Assign
    to store variables needed in later states instead of threading it through Output
  • Use
    $states.input
    to reference original state input
  • Assign
    and
    Output
    are evaluated in parallel from the state's entry data, NOT sequentially — a variable set in
    Assign
    is therefore NOT visible in the same state's
    Output
    (which still sees the pre-
    Assign
    values); the new value takes effect only in the next state.
  • All JSONata expressions must produce a defined value —
    $data.nonExistentField
    throws
    States.QueryEvaluationError
  • Use
    $states.context.Execution.Input
    to access the original workflow input from any state
  • Save state machine definitions with
    .asl.json
    extension when working outside the console
  • Prefer the optimized Lambda integration (
    arn:aws:states:::lambda:invoke
    ) over the SDK integration
  • 对于新状态机,在顶层设置
    "QueryLanguage": "JSONata"
    ,除非用户希望使用JSONPath
  • 保持
    Output
    简洁——仅包含当前状态的下一个状态立即需要的内容
  • 使用
    Assign
    存储后续状态需要的变量,而非通过Output传递
  • 使用
    $states.input
    引用原始状态输入
  • Assign
    Output
    从状态的初始数据并行求值,而非顺序求值——因此在同一状态的
    Output
    中无法看到
    Assign
    中设置的变量(仍会看到
    Assign
    之前的值);新值仅在下一个状态生效。
  • 所有JSONata表达式必须生成已定义的值——
    $data.nonExistentField
    会抛出
    States.QueryEvaluationError
  • 使用
    $states.context.Execution.Input
    从任何状态访问原始工作流输入
  • 在控制台外工作时,使用
    .asl.json
    扩展名保存状态机定义
  • 优先选择优化的Lambda集成(
    arn:aws:states:::lambda:invoke
    )而非SDK集成

Troubleshooting

故障排查

Common Errors

常见错误

  • States.QueryEvaluationError
    — JSONata expression failed. Check for type errors, undefined fields, or out-of-range values.
  • Mixing JSONPath fields with JSONata fields in the same state.
  • Using
    $
    or
    $$
    at the top level of a JSONata expression — use
    $states.input
    instead.
  • Forgetting
    {% %}
    delimiters around JSONata expressions — the string will be treated as a literal.
  • Assigning variables in
    Assign
    and expecting them in
    Output
    of the same state — new values only take effect in the next state.
  • Reference references/validation-and-testing.md and references/error-handling.md for detailed troubleshooting information.
  • States.QueryEvaluationError
    ——JSONata表达式执行失败。检查类型错误、未定义字段或超出范围的值。
  • 在同一状态中混用JSONPath字段与JSONata字段。
  • 在JSONata表达式顶层使用
    $
    $$
    ——请改用
    $states.input
  • 忘记在JSONata表达式周围添加
    {% %}
    分隔符——字符串将被视为字面量。
  • Assign
    中赋值变量并期望在同一状态的
    Output
    中使用——新值仅在下一个状态生效。
  • 详细故障排查信息请查看references/validation-and-testing.md和references/error-handling.md。

Security Considerations

安全注意事项

  • Least-privilege execution role. Scope the state machine's IAM role to the specific resources and actions it invokes (specific Lambda/DynamoDB/SQS/SNS ARNs). Avoid
    *FullAccess
    policies and
    service:*
    wildcards.
  • Encryption. Recommend encryption at rest and in transit for every data store a workflow touches: KMS-encrypted DynamoDB tables, server-side encryption (
    KmsMasterKeyId
    ) on SQS queues and SNS topics, and TLS for HTTP Tasks.
  • Task tokens and message bodies are sensitive. A
    .waitForTaskToken
    token is a credential — treat it as a secret. Do not place PII, financial data, or secrets in SQS/SNS message bodies or notifications; pass a reference ID and have recipients look up details through an authorized channel.
  • Validate input and fail fast. Validate required fields at the start of the workflow with a Choice (or Pass) state using
    $exists()
    and
    $type()
    , and route invalid input to a Fail state so malformed data never reaches downstream states. Protect downstream services from bursts by setting
    MaxConcurrency
    on Map states and throttling upstream (StartExecution rate limits or EventBridge).
  • Cross-account access. When using the
    Credentials
    field to assume a role in another account, include condition keys such as
    aws:SourceArn
    or
    aws:SourceAccount
    in the target role's trust policy to prevent unintended assumption.
  • External secrets. For HTTP Tasks calling third-party APIs, store API keys and tokens in AWS Secrets Manager (referenced via an EventBridge connection), never embedded in the state machine definition.
  • Observability. Enable CloudWatch Logs for executions (log level
    ALL
    or
    ERROR
    ; required for Express workflows, which have no queryable execution history), enable CloudTrail to audit Step Functions API calls, and set CloudWatch Alarms on execution failures. Always encrypt the execution log group with a customer-managed KMS key, since state input/output routinely flows through execution logs.
  • 最小权限执行角色。将状态机的IAM角色权限限定为其调用的特定资源和操作(特定Lambda/DynamoDB/SQS/SNS ARN)。避免使用
    *FullAccess
    策略和
    service:*
    通配符。
  • 加密。建议对工作流涉及的每个数据存储启用静态加密和传输中加密:KMS加密的DynamoDB表、SQS队列和SNS主题的服务器端加密(
    KmsMasterKeyId
    ),以及HTTP任务的TLS加密。
  • 任务令牌和消息体敏感
    .waitForTaskToken
    令牌是一种凭证——请将其视为机密信息。请勿在SQS/SNS消息体或通知中放置PII、财务数据或机密信息;传递参考ID,让接收方通过授权渠道查询详细信息。
  • 验证输入并快速失败。在工作流开始时使用Choice(或Pass)状态,通过
    $exists()
    $type()
    验证必填字段,并将无效输入路由至Fail状态,确保格式错误的数据永远不会到达下游状态。通过在Map状态上设置
    MaxConcurrency
    并限制上游(StartExecution速率限制或EventBridge)来保护下游服务免受突发流量影响。
  • 跨账户访问。使用
    Credentials
    字段承担另一个账户中的角色时,在目标角色的信任策略中包含
    aws:SourceArn
    aws:SourceAccount
    等条件键,防止意外的角色承担。
  • 外部机密。对于调用第三方API的HTTP任务,将API密钥和令牌存储在AWS Secrets Manager中(通过EventBridge连接引用),切勿嵌入状态机定义中。
  • 可观测性。为执行启用CloudWatch Logs(日志级别
    ALL
    ERROR
    ;Express工作流必须启用,因为其无可查询的执行历史),启用CloudTrail以审计Step Functions API调用,并为执行失败设置CloudWatch告警。始终使用客户管理的KMS密钥加密执行日志组,因为状态输入/输出通常会流经执行日志。

Resources

资源