はじめに
ECS Scheduled TaskはAmazon EventBridge ルールを使用し、スケジュールに基づいて、
または EventBridge イベントへの応答として、タスクを実行する機能です。
ECSで動作している環境でECS Scaduled Taskを使ったバッチ処理を導入する機会がありましたので実施する手順を紹介します。
前提
- すでにECSで動作している環境
- すでに動作している環境のコンテナにバッチ処理用のスクリプトが配置されている
- terraformで設定
ディレクトリ構造
terraform versionやバックエンド設定などはconfig.tfに定義。
container-overrides/schedule.jsonはcontainerOverridesの設定を定義してます。
ローカル変数はlocals.tfに定義。
今回説明するECS Scheduled Taskメインの処理はmain.tfに定義してます。
projectに合わせてよしなに分割ください。
.
├── config.tf
├── container-overrides
│ └── schedule.json
├── locals.tf
└── main.tf
terrafom設定
使用バージョンは下記の通り。
Name | Version |
---|---|
terraform | 1.2.0 |
hashicorp/aws | 4.15.1 |
terraform
IAM
ECS Scaduled TaskではEventBridgeが使用されるため信頼されたエンティティにevents.amazonaws.comを設定します。
作成したロールにAmazonEC2ContainerServiceEventsRoleのマネージドポリシーを設定。このポリシーはEventBridgeからECSを使用するためのポリシーです。
data "aws_iam_policy_document" "schedule" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
}
}
resource "aws_iam_role" "schedule" {
name = "schedule-${terraform.workspace}"
assume_role_policy = data.aws_iam_policy_document.schedule.json
}
resource "aws_iam_role_policy_attachment" "schedule" {
role = aws_iam_role.schedule.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole"
}
EventBridge Rule
ECS Scaduled TaskではEventBridgeを使用して定期実行を設定します。
EventBridgeではタイムゾーンがUTCになるのでお気をつけください。
JSTの月初00時00分で使用する場合、月末を表すワイルドカードL
を使用して00 15 L * ? *
のような形にする必要があります。
EventBridgeで使用するCron式の詳細についてはこちら
resource "aws_cloudwatch_event_rule" "schedule" {
name = "schedule-${terraform.workspace}"
description = "ECS Scaduled Task"
schedule_expression = "cron(00 15 L * ? *)"
}
EventBridge Target
EventBridge Targetを使用して、ルールに定義されたイベントパターンにイベントがマッチしたときに、イベントを送信する先のリソース(ECS Task)を定義します。
既存のECSのecs cluster arnの指定が必要です。
inputでECSに渡すjsonを定義します。
ここではoverridesを使用することで、コンテナのデフォルトコマンドを上書きし、入力をタスクに渡します。
overridesの詳細はこちら
ecs_targetの項目ではタスクを呼び出すときに使用するパラメータを設定します。
ここでは既存のECSの設定値を渡しております。
task_definition_arnで最新版を指定しておきたい場合、terraformではarn最後に記載されているリビジョンを除外して設定する必要があります。
resource "aws_cloudwatch_event_target" "schedule" {
target_id = "schedule-${terraform.workspace}"
arn = local.ecs_cluster_arn
input = file("container-overrides/schedule.json")
rule = aws_cloudwatch_event_rule.schedule.name
role_arn = aws_iam_role.schedule.arn
ecs_target {
launch_type = "FARGATE"
task_count = 1
task_definition_arn = local.ecs_task_definition_arn
platform_version = "1.4.0"
network_configuration {
subnets = local.subnets
security_groups = local.security_groups
assign_public_ip = false
}
}
}
上記inputとして渡しているcontainer-overrides/schedule.jsonには、containerOverrides(タスクの実行時に、タスク定義の一部を上書きする機能)を使って実行コマンドを定義してます。
nameでoverrides対象のコンテナを指定してます。
commandの項は","区切りでコマンドを渡すことができます。
{
"containerOverrides": [
{
"name": "app",
"command": [
"xxx",
"yyy"
]
}
]
}
おわりに
こちらでECS使ったバッチの定期実行が可能になりました。
containerOverridesを複数用意し別個に登録すれば同じコンテナイメージを複数のジョブで使用できます。
参考
こちら参考にさせていただいたサイトです。