Step Functionsでパラメータをバリデーションする方法
こんにちは、ヤギです。
今回の記事は 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ステートで、パラメータが存在するかを確認するようにしましょう。