Step Functionsのstate machine全体のタイムアウトはCatchで拾えない

  • AWS
  • Step Functions
  • EventBridge

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

何が起きたか

Step FunctionsのASLにはTimeoutSecondsが、Taskステートなど個々のstate単位だけでなく、state machine定義のトップレベルにも書ける。両方併用できる。

{
"Comment": "example",
"StartAt": "ExampleState",
"TimeoutSeconds": 3600,
"States": {
"ExampleState": {
"Type": "Task",
"Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:example",
"TimeoutSeconds": 300,
"End": true
}
}
}

ただ、state machine全体のTimeoutSecondsでタイムアウトした場合、これはステートマシン内のCatchでは拾えない。Catchで捕捉できるのはstate単位のエラー(States.Timeoutなど)で、machine全体の強制終了はステートマシンの実行そのものが止まる形になるので、ステートマシン内のエラーハンドリングの対象外になる。

検知方法

machine全体のタイムアウトを検知するには、Step Functionsの実行状態変化イベントをEventBridge経由で拾うしかない。

Step FunctionsはEventBridgeのデフォルトイベントバスにStep Functions Execution Status Changeイベントを自動で送っている。

flowchart LR
    A[Step Functions実行がTIMED_OUT] --> B[EventBridge: Execution Status Change]
    B --> C[EventBridge Rule<br/>stateMachineArn + statusで絞り込み]
    C --> D[SNS Topic]
    D --> E[メール通知]

イベントパターンはこんな感じ。

{
"source": ["aws.states"],
"detail-type": ["Step Functions Execution Status Change"],
"detail": {
"status": ["TIMED_OUT"],
"stateMachineArn": ["arn:aws:states:REGION:ACCOUNT_ID:stateMachine:example-state-machine"]
}
}

detail.stateMachineArnで対象のstate machineだけに絞り込める。複数のstate machineを一つのアカウントで運用していても、これで個別に通知先を分けられる。

ターゲットにSNSトピックを直接指定すれば、Lambdaを挟まずにメール通知まで持っていける。

補足

SNSトピックをEventBridgeルールのターゲットに直接指定する場合、SNS側のトピックポリシーでEventBridgeからのPublishを許可しておく必要があるらしい。ここは実機未確認。

結論

  • state machine全体のTimeoutSecondsはCatchでは拾えない
  • 検知はEventBridgeのStep Functions Execution Status Changeイベント経由
  • detail.stateMachineArnでstate machine単位のフィルタが可能
  • SNSを直接ターゲットにすればLambdaレスで通知まで組める