Step Functions で ECS タスクのエラーを適切に捕捉する方法

ECS

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 の RetryCatch を活用してエラーを適切に処理できます。

また、アプリに渡す環境変数で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 での処理を正しく制御できます。

タイトルとURLをコピーしました