介绍
履约系统必须先保存订单,再读取其完成后的摘要。你将通过工作流连接这些任务,并将执行历史与实际业务结果对比。
请先完成 通过 Lambda 读取和写入 DynamoDB,以及它要求的 IAM 角色和日志前置实验。这个独立 VM 提供工作程序和表;工作流由你创建。EventBridge 路由属于独立的学习支线。
相关认证考点
本实验为以下认证考点提供动手练习。
- Solutions Architect – Associate (SAA-C03) · 任务 2.1: Step Functions 任务编排与业务结果验证。
- Developer – Associate (DVA-C02) · 任务 1.1: Step Functions 任务编排与业务结果验证。
- DevOps Engineer – Professional (DOP-C02) · 任务 5.1, 任务 2.3: 基础练习:Step Functions 任务编排与业务结果验证。
- Solutions Architect – Professional (SAP-C02) · 任务 2.4: 基础练习:Step Functions 任务编排与业务结果验证。
授权工作流调用其工作程序
本步骤中,检查提供的业务工作程序,并为 Step Functions 创建独立执行角色。

工作流角色调用函数。独立的 Lambda 角色执行表操作。
使用 Terminal 旁的 AWS View,将 CLI 查询与本实验的实际资源和结果对比。保留提供的参考数据。
工作流连接任务和决策。状态机定义这些状态;一次执行使用特定输入运行该定义。这个全新 VM 提供工作程序函数和独立的订单、诊断及参考表。尚无状态机或工作流角色。工作程序接受订单,写入数量和总金额,稍后还能读取摘要。其 Lambda 执行角色已授权这些作为配套环境的表操作。
从项目目录开始。shell 赋值保存返回的标识符;--query 选择响应字段,--output text 生成可复用字符串。
cd /home/labex/project
WORKER_NAME=labex-ev03-worker
WORKER_ARN=$(aws lambda get-function-configuration \
--function-name labex-ev03-worker \
--query FunctionArn \
--output text)
aws lambda get-function-configuration \
--function-name labex-ev03-worker \
--query '{Name:FunctionName,Role:Role,Runtime:Runtime,Timeout:Timeout}'
aws stepfunctions list-state-machines
工作程序使用 Python3.12 和自己的 Lambda 角色;状态机列表为空。Step Functions 需要自己的执行角色。信任策略允许 Step Functions 服务代入该角色;权限策略允许所得会话只调用这个工作程序。带引号的 here-document 写入字面 JSON,file:// 将其读入请求。
cat > workflow-trust.json <<'JSON'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "states.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
JSON
ROLE_ARN=$(aws iam create-role \
--role-name labex-ev03-workflow-role \
--assume-role-policy-document file://workflow-trust.json \
--query Role.Arn \
--output text)
写入普通权限文档。shell 插入 $WORKER_ARN,将此授权限定为提供的工作程序。
cat > workflow-invoke.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "$WORKER_ARN"
}
]
}
EOF
aws iam put-role-policy \
--role-name labex-ev03-workflow-role \
--policy-name InvokeWorker \
--policy-document file://workflow-invoke.json
aws iam get-role-policy --role-name labex-ev03-workflow-role --policy-name InvokeWorker
策略只有一个精确的函数 ARN。Step Functions 不会获得工作程序的 DynamoDB 权限:工作程序使用独立的 Lambda 角色执行这些调用。运行授权检查。
定义决策和两个实际任务
本步骤中,定义订单工作流,验证数量、存储订单并读取实际摘要。

StoreOrder 将实际载荷保存到 saved.result 下;ReadSummary 选择该订单 ID 并读取完成后的摘要。
Amazon States Language(ASL)是一种 JSON 状态机定义。StartAt 选择第一个状态。Choice 在条件匹配时进入一个分支,否则进入 Default。Task 调用服务。Next 连接状态;End: true 表示成功结束,而 Fail 表示以错误结束。
优化的 Lambda 任务集成使用 arn:aws:states:::lambda:invoke。Parameters 提供函数参数:以 .$ 结尾的键会评估 JSONPath,$ 选择完整的当前输入。Lambda 集成返回元数据和 Payload。ResultSelector 只保留该载荷,ResultPath 将其插入 saved 下,同时保留原始订单输入,下一项任务再选择保存的订单 ID。它的 OutputPath 只返回实际摘要载荷。
写入字面定义,然后使用 jq --arg 替换工作程序占位符:
cat > workflow-template.json <<'JSON'
{
"StartAt": "CheckQuantity",
"States": {
"CheckQuantity": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.quantity",
"NumericGreaterThan": 0,
"Next": "StoreOrder"
}
],
"Default": "Rejected"
},
"StoreOrder": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "WORKER_NAME",
"Payload.$": "$"
},
"ResultSelector": {
"result.$": "$.Payload"
},
"ResultPath": "$.saved",
"Next": "ReadSummary"
},
"ReadSummary": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "WORKER_NAME",
"Payload": {
"stage": "summary",
"id.$": "$.saved.result.id"
}
},
"OutputPath": "$.Payload",
"End": true
},
"Rejected": {
"Type": "Fail",
"Error": "OrderRejected",
"Cause": "Quantity must be positive"
}
}
}
JSON
jq --arg worker "$WORKER_NAME" '.States.StoreOrder.Parameters.FunctionName=$worker | .States.ReadSummary.Parameters.FunctionName=$worker' workflow-template.json > workflow.json
MACHINE_ARN=$(aws stepfunctions create-state-machine \
--name labex-ev03-orders \
--type STANDARD \
--role-arn "$ROLE_ARN" \
--definition file://workflow.json \
--query stateMachineArn \
--output text)
aws stepfunctions describe-state-machine \
--state-machine-arn "$MACHINE_ARN" \
--query '{Name:name,Role:roleArn,Definition:definition}'
响应指定状态机和工作流角色,定义在两个任务中都指定提供的工作程序。尚未处理任何订单。点击 Terminal 旁的 AWS View,查看实际状态机定义以及空的执行和订单列表。运行定义检查。
验证业务结果与被拒绝的执行
本步骤中,运行有效订单、无效数量,以及缺少调用权限的执行。
start-execution 启动异步任务并返回执行 ARN。下面有次数上限的 shell 循环每两秒读取一次状态,直到执行不再运行。$(...) 捕获命令输出,seq 提供循环次数,条件匹配时 break 退出循环。如果循环后仍为 RUNNING,继续之前先检查服务。
EXECUTION_ARN=$(aws stepfunctions start-execution \
--state-machine-arn "$MACHINE_ARN" \
--name valid-order \
--input '{"id":"workflow-order","quantity":3}' \
--query executionArn \
--output text)
for attempt in $(seq 1 60); do
STATUS=$(aws stepfunctions describe-execution \
--execution-arn "$EXECUTION_ARN" \
--query status \
--output text)
if test "$STATUS" != RUNNING; then break; fi
sleep 2
done
aws stepfunctions describe-execution \
--execution-arn "$EXECUTION_ARN" \
--query '{Status:status,Output:output}'
aws stepfunctions get-execution-history \
--execution-arn "$EXECUTION_ARN" \
--query 'events[].type'
aws dynamodb get-item \
--table-name labex-ev03-orders \
--key '{"id":{"S":"workflow-order"}}' \
--query Item

官方 Console 将执行名称、状态和时间并列显示。其中的名称和工作流与本实验的 Standard 状态机不同。将你的 CLI 状态与历史和存储数据对比;使用 AWS View 查看本实验的结果。
状态为 SUCCEEDED,输出包含订单 ID、total_cents:850 和 completed:true。实际 DynamoDB 项目的数量为 3,总金额为 850。历史包含两个 TaskSucceeded 事件:存储订单和读取摘要。仅有执行状态不能证明业务结果;应对比两者。
使用数量零测试 Choice 分支:
INVALID_ARN=$(aws stepfunctions start-execution \
--state-machine-arn "$MACHINE_ARN" \
--name invalid-order \
--input '{"id":"invalid-order","quantity":0}' \
--query executionArn \
--output text)
for attempt in $(seq 1 30); do
STATUS=$(aws stepfunctions describe-execution \
--execution-arn "$INVALID_ARN" \
--query status \
--output text)
if test "$STATUS" != RUNNING; then break; fi
sleep 2
done
aws stepfunctions describe-execution \
--execution-arn "$INVALID_ARN" \
--query '{Status:status,Error:error}'
aws dynamodb get-item \
--table-name labex-ev03-orders \
--key '{"id":{"S":"invalid-order"}}' \
--query Item
状态为 FAILED,错误为 OrderRejected,且没有 invalid-order 项目。Choice 在调用工作程序之前拒绝了它。
现在只移除工作流的 Invoke 策略。工作程序的角色和数据权限仍然独立。操作员仍被允许启动执行,但工作流角色无法调用其任务:
aws iam delete-role-policy --role-name labex-ev03-workflow-role --policy-name InvokeWorker
DENIED_ARN=$(aws stepfunctions start-execution \
--state-machine-arn "$MACHINE_ARN" \
--name denied-order \
--input '{"id":"denied-order","quantity":2}' \
--query executionArn \
--output text)
for attempt in $(seq 1 30); do
STATUS=$(aws stepfunctions describe-execution \
--execution-arn "$DENIED_ARN" \
--query status \
--output text)
if test "$STATUS" != RUNNING; then break; fi
sleep 2
done
aws stepfunctions describe-execution \
--execution-arn "$DENIED_ARN" \
--query '{Status:status,Error:error}'
aws dynamodb get-item \
--table-name labex-ev03-orders \
--key '{"id":{"S":"denied-order"}}' \
--query Item
aws iam put-role-policy \
--role-name labex-ev03-workflow-role \
--policy-name InvokeWorker \
--policy-document file://workflow-invoke.json
被拒绝的执行在调用时以访问拒绝错误失败;它不创建订单,也不执行工作程序任务。预期策略已恢复。AWS View 在唯一存储的订单旁显示实际成功摘要和两次失败。
下面的示例展示实际成功摘要、被拒绝的执行,以及唯一的业务订单。

运行执行检查。
移除工作流资源与模拟结果
本步骤中,删除你已完成执行的状态机、工作流角色、订单和日志,同时保留提供的配套资源。
三次执行都已结束。删除状态机会将它从活动状态机列表中移除。删除角色之前,先移除自己创建的角色策略,然后移除执行所创建的模拟订单和工作程序日志组。
aws stepfunctions delete-state-machine --state-machine-arn "$MACHINE_ARN"
aws iam delete-role-policy --role-name labex-ev03-workflow-role --policy-name InvokeWorker
aws iam delete-role --role-name labex-ev03-workflow-role
aws dynamodb delete-item \
--table-name labex-ev03-orders \
--key '{"id":{"S":"workflow-order"}}'
aws dynamodb delete-item \
--table-name labex-ev03-attempts \
--key '{"id":{"S":"workflow-order"}}'
aws logs delete-log-group --log-group-name /aws/lambda/labex-ev03-worker
成功读取资源清单,证明剩余资源状态:
aws stepfunctions list-state-machines
aws iam list-roles --query 'Roles[].RoleName'
aws dynamodb scan --table-name labex-ev03-orders --query Items
aws logs describe-log-groups --query logGroups
aws dynamodb scan --table-name labex-ev03-reference --query Items
没有活动状态机、订单或日志组。只保留提供的工作程序角色,参考项目未改变。保留提供的工作程序和表:它们属于环境准备资源,与你创建的工作流和资源不同。网络或身份验证错误绝不能证明删除成功。
移除本实验创建的普通文件:
rm -f workflow-trust.json workflow-invoke.json workflow-template.json workflow.json
AWS View 显示状态机、执行和订单为空,参考资源仍保留。结束 VM 之前,运行清理检查。
总结
你创建了限定范围的工作流执行角色,连接 Choice 和两个实际 Lambda 任务,将实际结果传给下一项任务,并将执行历史与业务数据对比。无效输入和缺少调用权限都没有产生订单。你移除了自己创建的工作流资源和模拟结果,同时保留提供的配套资源。
下一个实验将添加针对临时失败的重试,以及对永久错误的明确处理。



