AWS Step Functionsチュートリアル実践:リトライを使ったエラーハンドリングの作成と実行 #reinvent
AWS re:Invent 2016で発表された『AWS Step Functions』、Getting Startedの他にもドキュメントではチュートリアルが幾つか用意されています。当エントリではそのうちの1つ、Retryフィールドを使ってステートマシンのエラー状態を処理したものについて実践してみた結果をご紹介してみたいと思います。
AWS Step Functionsに関するエントリ一覧は下記関連シリーズをご参照ください。
目次
- Step 1:Lambda用にIAM Roleを作成
- Step 2:失敗するLambda関数を作成
- Step 3:Retryフィールドのあるステートマシンの作成
- Step 4:ステートマシンの実行
Step 1:Lambda用にIAM Roleを作成
Step FunctionsでLambdaを実行させる際にはIAM Roleが必要となります。まずはそのIAM Roleを作成するところから進めて行きましょう。管理コンソールのIAMメニューを開き、[Roles]から[Create New Role]を押下。
任意のRole Nameを設定し、[Next Step]を押下。
[Select Role Type]では[AWS Lambda]を選択します。
Policyの設定。ここは特に何も付与する必要はありません。そのまま[Next Step]を押下。
内容を確認し、[Create Role]を押下。
IAM Roleが作成出来ました。
Step 2:失敗するLambda関数を作成
次いで必ず失敗するLambda関数を作成します。入力値によらず例外を投げる、というシンプルなものです。
AWS管理コンソールより、Lambdaメニューに遷移。[Create a Lambda function]を押下。
Blueprint選択では[Blank Function]を選択。今回は特に難しい作りのものでは無いため、イチから書き上げる(というかコピペ)ためこの選択で進めます。
Configure triggersについても特に指定は行わず、そのまま[Next]を押下。
function設定について、以下内容で設定を行います。
- Name: 任意
- Description: 任意
- Runtime: Python 2.7
またLambda function codeには以下コードを貼り付けます。eventオブジェクトが関数に対して渡され、例外をraiseします。
def lambda_handler(event, context): raise Exception('Something went wrong')
Lambda関数のIAM Roleを選択します。ここでは[Choose an existing role]を選択し、上記手順で作成したIAM Roleを選択します。
内容を確認、[Create function]を押下。
Lambda functionが出来ました。右上に表示されているARNについては後程使いますのでコピーして控えておきます。
Step 3:Retryフィールドのあるステートマシンの作成
Step Functionsにてステートマシンを作成します。管理コンソールメニューにて[Step Functions]をクリック。
ステートマシンの作成については下記エントリと同じ流れのため、割愛します。
設定するコードについては、下記の内容を使い、Resourceの部分を上記で控えておいたLambda関数のARNを貼り付けて設定します。
{ "Comment": "A Retry example of the Amazon States Language using an AWS Lambda Function", "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME", "Retry": [ { "ErrorEquals": [ "HandledError" ], "IntervalSeconds": 1, "MaxAttempts": 2, "BackoffRate": 2 }, { "ErrorEquals": [ "UnhandledError" ], "IntervalSeconds": 1, "MaxAttempts": 3, "BackoffRate": 2 }, { "ErrorEquals": [ "States.TaskFailed" ], "IntervalSeconds": 30, "MaxAttempts": 2, "BackoffRate": 2 }, { "ErrorEquals": [ "States.ALL" ], "IntervalSeconds": 5, "MaxAttempts": 5, "BackoffRate": 2 } ], "End": true } } }
Step 4:ステートマシンの実行
ステートマシン実行。実行の際に用いるパラメータとして、以下文字列を設定します。この内容がLambda関数に渡され、処理が実行される形となります。
{ "Comment": "Insert your JSON here" }
ステートマシン実行。程なくして結果が表示されました。
HelloWorld が赤くなっているため、失敗しているとわかります。
Output にはトレースバックが表示されいます。
Output の error: UnhandledError
からわかるように、今回は UnhandledError
が発生しました。ステートマシーンの
{ "ErrorEquals": ["UnhandledError"], "IntervalSeconds": 1, "MaxAttempts": 3, "BackoffRate": 2.0 },
の条件にマッチするため、エラーが発生後、3回ほどリトライを行い、その後、終了しています。
例外の種類について
"X": { "Type": "Task", "Resource": "arn:aws:states:us-east-1:123456789012:task:X", "Next": "Y", "Retry": [ { "ErrorEquals": [ "ErrorA", "ErrorB" ], "IntervalSeconds": 1, "BackoffRate": 2, "MaxRetries": 2 }, { "ErrorEquals": [ "ErrorC" ], "IntervalSeconds": 5 } ], "Catch": [ { "ErrorEquals": [ "States.ALL" ], "Next": "Z" } ] }
というように、細かい粒度で例外処理ができそうに読み取れます。
Step Functions Forums での 2016/12/19 時点での中の人の回答によると、実際には
- HandledError
- UnhandledError
の例外にしか対応していないそうです。Lambda でのエラーをランタイムによらずに統一的にコントロールするすべが用意されていないことも、その一因だそうです。
まとめ
という訳でAWS Step Functionsチュートリアル:Retryフィールドのエラーハンドリング編でした。Lambdaの実行だけでなく、エラー内容によってリトライ処理や遷移先を制御出来るのは非常に強力ですね。引き続きチュートリアルについては実践を進めて行こうと思います。こちらからは以上です。