はじめに
依存先の一時的な失敗は復旧する場合がありますが、無効な注文は失敗したままにすべきです。選択的な再試行と永続的な失敗の経路を設定し、実際の試行と保存された結果を観察します。
先に 複数ステップの注文ワークフローを構築する を完了してください。この新しい VM は、独自のワーカーと空のテーブルを提供します。以前のステートマシン、ロール、実行は再利用しません。
認定試験との関連
このラボでは、次の試験トピックに関連する実践的な演習を行います。
- Solutions Architect – Associate (SAA-C03) · タスク 2.1: ワークフローのエラー処理、回数を限定したリトライ、失敗結果。
- Developer – Associate (DVA-C02) · タスク 1.1: ワークフローのエラー処理、回数を限定したリトライ、失敗結果。
- DevOps Engineer – Professional (DOP-C02) · タスク 5.1: 基礎演習:ワークフローのエラー処理、回数を限定したリトライ、失敗結果。
- Solutions Architect – Professional (SAP-C02) · タスク 2.4: 基礎演習:ワークフローのエラー処理、回数を限定したリトライ、失敗結果。
ワークフローによるワーカー呼び出しを認可する
このステップでは、提供された業務ワーカーを確認し、Step Functions 用の独立した実行ロールを作成します。
Terminal の隣で AWS View を使い、CLI クエリをこのラボの実際のリソースと結果と比較します。提供された参照データを保持してください。
この新しい VM は、ワーカー関数と独立した注文・診断・参照テーブルを提供します。ステートマシンやワークフローロールはまだありません。ワーカーは注文を受け取り、数量と合計を書き込み、後でサマリーを読み取れます。合成障害のテストでは、flaky モードが最初の試行で業務書き込み前に TransientOrderError を発生させ、permanent モードが書き込み前に InvalidOrder を発生させます。診断用の試行記録は業務注文とは別です。Lambda 実行ロールは、ワークフロー自体の操作とは別の、これらのテーブル操作をすでに認可しています。
プロジェクトディレクトリから始めます。シェルの代入は返された識別子を保存します。--query はレスポンスフィールドを選択し、--output text は再利用可能な文字列を生成します。
cd /home/labex/project
WORKER_NAME=labex-ev04-worker
WORKER_ARN=$(aws lambda get-function-configuration \
--function-name labex-ev04-worker \
--query FunctionArn \
--output text)
aws lambda get-function-configuration \
--function-name labex-ev04-worker \
--query '{Name:FunctionName,Role:Role,Runtime:Runtime,Timeout:Timeout}'
aws stepfunctions list-state-machines
ワーカーは Python3.12 と独自の Lambda ロールを使い、ステートマシン一覧は空です。Step Functions には自身の実行ロールが必要です。信頼ポリシーは Step Functions サービスによるそのロールの引き受けを許可し、権限ポリシーは、生成されたセッションがこのワーカーだけを呼び出すことを許可します。引用符付きのヒアドキュメントは 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-ev04-workflow-role \
--assume-role-policy-document file://workflow-trust.json \
--query Role.Arn \
--output text)
通常の権限ドキュメントを書き込みます。シェルは $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-ev04-workflow-role \
--policy-name InvokeWorker \
--policy-document file://workflow-invoke.json
aws iam get-role-policy --role-name labex-ev04-workflow-role --policy-name InvokeWorker
ポリシーには 1 つの正確な関数 ARN があります。Step Functions はワーカーの DynamoDB 権限を受け取りません。ワーカーは独立した Lambda ロールでそれらの呼び出しを行います。認可の検証を実行してください。
回数を限定した再試行と永続的な失敗の経路を設定する
このステップでは、選択的な復旧動作を持つ、実際の 2 タスクのワークフローを構築します。

このワーカーの一時的なエラーは再試行で復旧できます。永続的なエラーは Catch を通り、明示的な失敗結果になります。
ASL の Retry は、再試行できるタスクエラーを列挙します。ErrorEquals は関数のエラー型に一致する必要があります。IntervalSeconds:1 は 1 秒の遅延から始め、BackoffRate:2 は次の遅延を倍にします。MaxAttempts:2 は、最初の試行後に最大 2 回の再試行を許可します。この再試行は、あらゆる失敗ではなく、TransientOrderError だけを扱います。
Catch は、タスクが復旧できなかったエラーに対して、別の状態を選択します。ResultPath はエラーを failure の下に記録し、Next は明示的な Fail 状態へ進みます。エラーを処理したからといって、業務ジョブが成功したとは限りません。永続的な InvalidOrder は、注文を完了したふりをせず、OrderRejected を伴う FAILED で終了します。
引用符付きのヒアドキュメントは JSON をそのまま書き込みます。既存の Choice は正ではない数量を拒否します。2 つの Task は、保存とその後のサマリー読み取りを行います。Payload.$ は現在の入力を渡し、ResultSelector は実際の関数ペイロードを保持し、ResultPath はそれを saved の下に保存し、OutputPath は実際のサマリーを返します。
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",
"Retry": [
{
"ErrorEquals": [
"TransientOrderError"
],
"IntervalSeconds": 1,
"BackoffRate": 2,
"MaxAttempts": 2
}
],
"Catch": [
{
"ErrorEquals": [
"InvalidOrder"
],
"Next": "Rejected",
"ResultPath": "$.failure"
}
],
"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": "Order could not be completed"
}
}
}
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-ev04-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,Definition:definition}'
定義には、選択的な retry と catch のブロックが含まれます。AWS View にも同じ設定が表示され、実行や業務注文はまだありません。復旧定義の検証を実行してください。
実際の Retry、Catch、権限の結果を観察する
このステップでは、一時的な失敗、永続的な失敗、拒否される呼び出しを実行します。
ワーカーの最初の flaky 試行は、診断用試行カウンターを更新し、注文を書き込む前にエラーを発生させます。次の試行は成功できます。回数を限定したシェルループは、実行中でなくなるまで 2 秒ごとに状態を読み取ります。$(...) は出力を取得し、break はループを終了します。ループ後も実行が RUNNING の場合は、先へ進む前に確認してください。
RETRY_ARN=$(aws stepfunctions start-execution \
--state-machine-arn "$MACHINE_ARN" \
--name retry-order \
--input '{"id":"retry-order","quantity":2,"mode":"flaky"}' \
--query executionArn \
--output text)
for attempt in $(seq 1 60); do
STATUS=$(aws stepfunctions describe-execution \
--execution-arn "$RETRY_ARN" \
--query status \
--output text)
if test "$STATUS" != RUNNING; then break; fi
sleep 2
done
aws stepfunctions describe-execution \
--execution-arn "$RETRY_ARN" \
--query '{Status:status,Output:output}'
aws stepfunctions get-execution-history \
--execution-arn "$RETRY_ARN" \
--query 'events[?type==`TaskFailed` || type==`TaskSucceeded`].{Type:type,Error:taskFailedEventDetails.error}'
aws dynamodb get-item \
--table-name labex-ev04-orders \
--key '{"id":{"S":"retry-order"}}' \
--query Item
aws dynamodb get-item \
--table-name labex-ev04-attempts \
--key '{"id":{"S":"retry-order"}}' \
--query Item
最終状態は SUCCEEDED で、完了したサマリーは 2/600 です。履歴には、TransientOrderError の TaskFailed が 1 件あり、その後に保存成功とサマリー読み取りの 2 件の TaskSucceeded イベントがあります。ネイティブな注文は数量 2、合計 600 で、診断用試行回数は 2 です。再試行と業務書き込みの回数は異なります。
次に、ワーカーの永続的な失敗モードを使います。
PERMANENT_ARN=$(aws stepfunctions start-execution \
--state-machine-arn "$MACHINE_ARN" \
--name permanent-order \
--input '{"id":"permanent-order","quantity":2,"mode":"permanent"}' \
--query executionArn \
--output text)
for attempt in $(seq 1 30); do
STATUS=$(aws stepfunctions describe-execution \
--execution-arn "$PERMANENT_ARN" \
--query status \
--output text)
if test "$STATUS" != RUNNING; then break; fi
sleep 2
done
aws stepfunctions describe-execution \
--execution-arn "$PERMANENT_ARN" \
--query '{Status:status,Error:error}'
aws stepfunctions get-execution-history \
--execution-arn "$PERMANENT_ARN" \
--query 'events[?type==`TaskFailed` || type==`FailStateEntered`].{Type:type,Error:taskFailedEventDetails.error,State:stateEnteredEventDetails.name}'
aws dynamodb get-item \
--table-name labex-ev04-orders \
--key '{"id":{"S":"permanent-order"}}' \
--query Item
1 回の実際のワーカー呼び出しが InvalidOrder で失敗します。Catch は Rejected に進み、実行は OrderRejected を伴う FAILED で終了します。一時的な失敗の再試行は、この永続的なエラーに一致しません。permanent-order の業務アイテムはありません。
最後に、ワークフローの呼び出し権限付与だけを削除します。操作担当者は実行を開始できますが、ワークフローロールはワーカーを呼び出せません。
aws iam delete-role-policy --role-name labex-ev04-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,"mode":"flaky"}' \
--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-ev04-orders \
--key '{"id":{"S":"denied-order"}}' \
--query Item
aws iam put-role-policy \
--role-name labex-ev04-workflow-role \
--policy-name InvokeWorker \
--policy-document file://workflow-invoke.json
このアクセス拒否の実行は、ワーカーを呼び出さず、診断データも業務データも作成せずに失敗します。指定したアプリケーションエラーの再試行では、認可の不足を修復できません。意図する権限付与は復元されます。AWS View には、成功した再試行のサマリーと 2 つの失敗が、1 件の注文の隣に表示されます。
以下の例は、実際の再試行のサマリー、永続的な失敗、拒否された実行を、保存された注文とともに示します。

実際の復旧の検証を実行してください。
ワークフローリソースと合成結果を削除する
このステップでは、提供された準備リソースを保持しながら、自分の完了したステートマシン、ワークフローロール、注文、ログを削除します。
3 つの実行はすべて終了しています。ステートマシンの削除は、アクティブなステートマシン一覧からそれを取り除きます。ロールを削除する前に所有するロールポリシーを削除し、その後、合成注文と実行によって作成されたワーカーロググループを削除します。
aws stepfunctions delete-state-machine --state-machine-arn "$MACHINE_ARN"
aws iam delete-role-policy --role-name labex-ev04-workflow-role --policy-name InvokeWorker
aws iam delete-role --role-name labex-ev04-workflow-role
aws dynamodb delete-item --table-name labex-ev04-orders --key '{"id":{"S":"retry-order"}}'
aws dynamodb delete-item \
--table-name labex-ev04-attempts \
--key '{"id":{"S":"retry-order"}}'
aws logs delete-log-group --log-group-name /aws/lambda/labex-ev04-worker
成功する一覧取得で、残るものを証明します。
aws stepfunctions list-state-machines
aws iam list-roles --query 'Roles[].RoleName'
aws dynamodb scan --table-name labex-ev04-orders --query Items
aws logs describe-log-groups --query logGroups
aws dynamodb scan --table-name labex-ev04-reference --query Items
アクティブなステートマシン、注文、ロググループはありません。提供されたワーカーロールだけが残り、参照アイテムは変わりません。提供されたワーカーとテーブルは保持してください。準備時の所有範囲は、自分が作成したワークフローやリソースと異なります。ネットワークエラーや認証エラーは削除の証拠になりません。
このラボで作成した通常のファイルを削除します。
rm -f workflow-trust.json workflow-invoke.json workflow-template.json workflow.json
AWS View には、空のステートマシン・実行・注文と、保持された参照リソースが表示されます。VM を終了する前に、後片付けの検証を実行してください。
まとめ
特定の一時的な失敗に対して回数を限定した再試行を設定し、Catch で明示的な永続的失敗へ進むようにしました。ネイティブな履歴と実際の注文で、試行と業務書き込みを区別しました。権限拒否では、ワーカー実行も業務上の効果も発生しませんでした。提供された準備リソースを保持しながら、所有するワークフローリソースと結果を削除しました。
次のユニットでは、再試行すると効果が繰り返される可能性のある、業務書き込み後の失敗を扱います。



