はじめに
Step Functions 内の処理でエラーが発生したときに、特定の処理を行わせたいことがあると思います。
その際の取りうるパターンを整理します。
対象者
この記事は下記のような人を対象にしています。
- Step Functions 内の処理でエラーが発生した時に、特定の処理を行わせたい人
- ステートマシンでタスクフローを作成したい人
StepFunctions 内で完結させるパターン
タスクごとに Catch する
各タスクごとに Catch フィールドを使用することで、エラーをキャッチすることができます。
以下の図からも分かるように、冗長になっていて複雑なステートマシンになると、どういうフローかが視覚的に分かりにくくなります。
ASL はこちらです。
{
"Comment": "A description of my state machine",
"StartAt": "タスク1",
"States": {
"タスク1": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName1"
},
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "エラー時の処理"
}
],
"Next": "タスク2"
},
"タスク2": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName2"
},
"Next": "タスク3",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "エラー時の処理"
}
]
},
"タスク3": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName3"
},
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "エラー時の処理"
}
],
"End": true
},
"エラー時の処理": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myErrorJob"
},
"End": true
}
}
}
Parallel ステートでまとめる
Parallel ステートを利用することで、Catch フィールドを一つにまとめることができます。
フロー図を見ても、先ほどと比べてすっきりしていて分かりやすい印象を受けます。
ASL はこちらです。
{
"Comment": "A description of my state machine",
"StartAt": "Parallel",
"States": {
"Parallel": {
"Type": "Parallel",
"Branches": [
{
"StartAt": "タスク1",
"States": {
"タスク1": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName"
},
"Next": "タスク2"
},
"タスク2": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName"
},
"Next": "タスク3"
},
"タスク3": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName"
},
"End": true
}
}
}
],
"End": true,
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "エラー時の処理"
}
]
},
"エラー時の処理": {
"Type": "Task",
"Resource": "arn:aws:states:::glue:startJobRun",
"Parameters": {
"JobName": "myJobName"
},
"End": true
}
}
}
注意点
こちらのパターンには、すべてのエラーを捕捉できないという大きな注意点があります。
Catch 対象のエラーに”States.ALL”を指定しても States.Runtime エラーは捕捉することができません。そのため、States.Runtime エラーが発生する可能性がある場合は、別の方法を取る必要があります。
tates.ALL での再試行またはキャッチでは States.Runtime エラーは検出されません。
Step Functions のエラー処理 – AWS Step Functions
EventBridge を利用するパターン
2021年5月に、Step FunctionsとEventBridgeとのサービス統合がサポートされました。
これにより柔軟なエラー処理を行うことが可能になりました。例えばステートマシンのステータスの変化を検知して Lambda を呼び出すことなどが可能です。
以下は EventBrdige をトリガーととする Lambda 関数を SAM デプロイする際の YAML ファイルです。
参考:EventBridgeRule – AWS Serverless Application Model
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
Globals:
Function:
Timeout: 3
Parameters:
stateMachineArn:
Type: String
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world_function/
Handler: hello_world/app.lambda_handler
Runtime: python3.7
Architectures:
- x86_64
Events:
HelloWorld:
Type: CloudWatchEvent
Properties:
Pattern:
source:
- aws.status
detail-type:
- Step Functions Execution Status Change
detail:
status:
- FAILED
stateMachineArn:
- !Ref stateMachineArn
Outputs:
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
SAM デプロイに使用した TOML ファイルのサンプルです。
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-app"
s3_bucket = "{SAMアーティファクト用のS3バケット}"
s3_prefix = "sam-app"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
parameter_overrides = [
"stateMachineArn={ステートマシンARN}}"
]
おわりに
本記事では、Step Functions 内の処理でエラーが発生したときに、特定の処理を行わせるアーキテクチャ案を紹介しました。この記事がどなたかの参考になれば幸いです。
コメント