AWS Step Functionsを利用してAWS BatchやFargateのタスクを起動する

この記事は、はてなエンジニア Advent Calendarの22日目の記事です。

qiita.com

最近は仕事で AWS Batch に触れることが多くなってきました。また、ちょっとしたスクリプトならFargate のほうが便利かもしれないということを同僚に教えてもらい、Fargateを利用してcronで実行している処理を置き換えられないか、ということを個人的に検討しています。今日はそこで得たちょっとした便利情報をご紹介しようと思います。

Step Functionsを試す

AWS BatchにしてもFargateにしても、成功/失敗のハンドリングが少し難しいという課題があると考えていました。AWS Batchは24時間後にはジョブの実行結果がコンソール上から消えてしまいます。Fargateも、タスク終了後短期間でタスク一覧から消えてしまい、どこかに通知していない限りは「ジョブ/タスクが成功したかどうか」すら分からなくなってしまいます。そんな折、AWS Step Functions(以下SFn) が最近AWS Batch/Fargate に対応したというのを見たのでそれを利用してみることにしました。それぞれのステートマシン定義は以下の通りです

AWS Batch

  {
    "Comment": "AWS Batchを起動する",
    "StartAt": "Submit Batch Job",
    "States": {
        "Submit Batch Job": {
            "Type": "Task",
            "Resource": "arn:aws:states:::batch:submitJob.sync",
            "Parameters": {
                "JobName": "sample-job",
                "JobDefinition": "<JOB_DEFINITION_ARN>",
                "JobQueue": "<JOB_QUEUE_ARN>"
            },
            "End": true
        }
    }
}

JobDefinitionに実行したいジョブのジョブ定義のARNを、JobQueueにジョブ定義を実行するジョブキューのARNを設定します。また、Resourceのリソースネームに.syncをつけることで、タスクが完了するまで待機するようになります

Fargate

{
    "Comment": "Run Fargate Task Statemacine",
    "StartAt": "Run Fargate Task",
    "TimeoutSeconds": 3600,
    "States": {
        "Run Fargate Task": {
            "Type": "Task",
            "Resource": "arn:aws:states:::ecs:runTask.sync",
            "Parameters": {
                "LaunchType": "FARGATE",
                "Cluster": "<CLUSTER_ARN>",
                "TaskDefinition": "<TASKDEFINITION_ARN>",
                "NetworkConfiguration": {
                    "AwsvpcConfiguration": {
                        "Subnets": [
                            "subnet-id"
                        ],
                        "AssignPublicIp": "ENABLED"
                    }
                }
            },
            "End": true
        }
    }
}

ClusterにECSクラスターのARNを、TaskDefinitionにタスク定義のARNを設定します。また、Fargateの場合実行時にAwsvpcConfigurationの設定が必須です。こちらもBatch同様、Resourceのリソースネームに.syncをつけることで、タスクが完了するまで待機するようになります。

気に入っているところ

  • バッチジョブやFargateタスクの成否のハンドリングがしやすくなった
  • バッチジョブやFargateタスクの実行についても、ステートマシンを起動するだけで実行できる
    • AWS BatchやFargateの実行」を「SFnの実行」に統一できる
  • SFnの実行履歴が1000件まで保存できる
  • BatchやFargateタスクの実行結果は割と短い期間で消えてしまうが、SFnを通すことで、実行結果だけあとで知りたいというようなときに実行履歴を見ることで事足りる場合もある

SFnのステートマシンはCloudWatch Eventsから時刻指定で起動することも可能なので、それを利用してcronのような使い方もできます(AWS Batchのジョブ/Fargateタスクともに CloudWatch Eventsから直接実行することも可能です)。実際に、一部バッチ処理をそのようにして定時実行するようにしています。実行の成否がコンソール上にまとまっているためとても便利です。SFnなので、タスクの実行後に成功通知をLambdaを使ってSlackに通知するということも当然可能です。

ということで、AWS BatchやFargateでバッチ処理を実行するような場合にちょっと便利になるようなTipsのご紹介でした。他にもいろいろ方法はあるかと思いますが、手軽に導入できるので気に入っています。タスクが少し扱いやすくなるので、AWS BatchやFargateでバッチ処理を実行しているような方は一度試してみてはいかがでしょうか?

世間のクリスマス感も高まってきましたね。はてなエンジニア Advent Calendar も残すところ3日となりましたが、引き続きよろしくおねがいします!