Step Functions を使用して ECS タスクを実行する際、タスク内でエラーが発生しても Step Functions はそれを適切に捕捉せずに次の処理を実行してしまうことがあります。これは、Step Functions がデフォルトでは ECS タスクの ExitCode が 0
以外である場合のみエラーと判断するためです。
本記事では、Python(Flask)で実装した ECS タスクのエラーを Step Functions に通知し、適切にエラーハンドリングを行う方法を解説します。
1. Step Functions が ECS タスクのエラーを捕捉しない理由
Step Functions は ECS タスクの ExitCode
をチェックし、0
以外の値である場合にエラーとして認識します。しかし、タスク内で発生したアプリケーションエラーが ExitCode=0
のままの場合、Step Functions はそれを正常終了とみなし、次のステップを実行してしまいます。
そのため、タスク内で適切にエラー処理を行い、Step Functions にエラーを通知する仕組みが必要になります。
2. Python(Flask)での実装例
2.1. ECS タスクの実装
ECS タスクとして実行される Flask アプリの例です。処理中にエラーが発生した場合、boto3 を使用して Step Functions にエラーを通知します。
from flask import Flask
import sys
import json
import os
import boto3
app = Flask(__name__)
sfn = boto3.client("stepfunctions", region_name="ap-northeast-1")
@app.route("/process")
def process():
try:
# ここでエラーが発生する処理
raise ValueError("処理中にエラーが発生しました!")
except Exception as e:
sfn = boto3.client('stepfunctions')
sfn.send_task_failure(
taskToken=os.getenv("TASKTOKEN"),
error = 'TaskFailed',
cause = 'Something wrong'
)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
2.2. Step Functions のエラーハンドリング設定
Step Functions の Retry
や Catch
を活用してエラーを適切に処理できます。
また、アプリに渡す環境変数でTASKTOKENを追加します。
{
"StartAt": "ECSタスクの実行",
"States": {
"ECSタスクの実行": {
"Type": "Task",
"Resource": "arn:aws:states:::ecs:runTask.sync",
"Parameters": {
"LaunchType": "FARGATE",
"Cluster": "{クラスターのARN}",
"TaskDefinition": "{タスク定義のARN}",
"NetworkConfiguration": {
"AwsvpcConfiguration": {
"AssignPublicIp": "DISENABLED",
"SecurityGroups": [
"{セキュリティグループ}"
],
"Subnets": [
"{サブネット}"
]
}
},
"Overrides": {
"ContainerOverrides": [
{
"Name": "{コンテナ名}",
"Environment": [
{
"Name": "TASKTOKEN",
"Value.$": "$$.Task.Token"
}
]
}
]
}
},
"Catch": [
{
"ErrorEquals": ["States.TaskFailed"],
"Next": "エラーハンドリング"
}
],
"End": true
},
"エラーハンドリング": {
"Type": "Fail",
"Cause": "ECS タスクでエラー発生"
}
}
}
3. ECS タスクの IAM ロール設定
StepFunctionsに通知をするには、適切な IAM ロールが必要です。 以下の IAM ポリシーをアタッチしてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"states:SendTaskSuccess",
"states:SendTaskFailure"
],
"Resource": "*"
}
]
}
4. 参考ドキュメント
この方法を使えば、ECS タスクのエラーを適切に捕捉し、Step Functions での処理を正しく制御できます。