この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、ヤギです。
今回の記事は Step Functionsのパラメータをバリデーションする方法です。
Step Functionsは、アクション間でパラメータ指定して、受け渡すことができます。
しかし、存在しないパラメータをASLで指定すると、States.Runtime
エラーが発生します。このエラーはリトライ、キャッチすることができず、ジョブが途中終了します。
また、このStates.Runtime
エラーはStates.ALL
では検出されません。
例えばCatchでエラー通知を行なっていた場合、通知処理が実行されないため、ジョブの失敗に気づくことができません。
このため、存在が保証出来ないパラメータをASLで指定する場合は、事前にパラメータが存在するかどうかのバリデーションが必要です。
TL;DR
- 存在しないパラメータをASLで指定すると
States.Runtime
が発生する States.Runtime
はキャッチ、リトライが出来ない- Choiceステートでパラメータをバリデーションする
前提
入力値$.lambdaInput
をLambda関数に渡し、エラーが起きなければ正常終了、エラーが発生すればエラーハンドリングを行う、というシンプルなステートマシンを例に検証します。
{
"StartAt": "Invoke Lambda Function",
"States": {
"Invoke Lambda Function": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-function",
"Payload.$": "$.lambdaInput"
},
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "Notify Job Failure"
}
],
"End": true
},
"Notify Job Failure": {
"Type": "Fail",
"Cause": "Job Failed"
}
}
}
存在しないパラメータをASLで参照した場合
このASLではLambdaに$.lambdaInput
を渡しています。
以下の入力値でステートマシンを実行した場合、$.lambdaInput
が存在しないため、States.Runtime
エラーが発生します。
{
"otherKey": "hogehoge"
}
ステートマシン実行結果
例外内容
エラー
States.Runtime
原因
An error occurred while executing the state 'Invoke Lambda Function' (entered at the event id #2). The JSONPath '$.lambdaInput' specified for the field 'Payload.$' could not be found in the input '{
"Comment": "Insert your JSON here"
}'
CatchでStates.ALL
を指定していますが、States.Runtime
エラーはキャッチされていません。(Notify Job Failure
が実行されてない)
公式ドキュメントでも言及されている通り、States.Runtime
はStates.ALL
ではキャッチされません。また、リトライ、キャッチ自体も行うことができません。
States.Runtime エラーは再試行可能ではなく、常に実行が失敗します。States.ALL での再試行またはキャッチでは States.Runtime エラーは検出されません。
https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/concepts-error-handling.html#states-runtime-error
このため、$.lambdaInput
が存在するかを、事前に検証する必要があります。
Choiceステートによるパラメータのバリデーション
$.lambdaInput
が存在することを保証するには、パラメータを利用するアクションの前に、Choiceステートを置き、パラメータが存在するかを確認します。
{
"StartAt": "Validate Params",
"States": {
"Validate Params": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.lambdaInput",
"IsPresent": false,
"Next": "Notify Job Failure"
}
],
"Default": "Invoke Lambda Function"
},
"Invoke Lambda Function": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-function",
"Payload.$": "$.lambdaInput"
},
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "Notify Job Failure"
}
],
"End": true
},
"Notify Job Failure": {
"Type": "Fail",
"Cause": "Job Failed"
}
}
}
これで$.lambdaInput
が存在しない場合も、エラーハンドリングが可能になりました。
実際に$.lambdaInput
パラメータがない状態で実行してみると、想定通りエラー状態にステートマシンが遷移していることがわかります。
まとめ
存在しないパラメータをASLで参照するとStates.Runtime
エラーが発生します。このエラーはStates.ALL
ではキャッチすることができず、ステートマシンの実行失敗に気づけない可能性があります。
存在が保証出来ないパラメータをASLで参照する場合は、Choiceステートで、パラメータが存在するかを確認するようにしましょう。