Railsのバッチ機能でgem wheneverを入れてschedule.rbファイルを管理する方法があるのですが、それをECS/Fargateで動かしたい場合は ECS Scheduled Tasks
を利用して実装が可能となります。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/scheduling_tasks.html
この中身はCloudWatchのイベントルールで管理されているので、「TerraformでECS Scheduled TasksのResorceから作ろう!」と思っていてもTerraform化されていないので注意してください。では、実際に作ってみましょう。
■Resource: aws_cloudwatch_event_target
https://www.terraform.io/docs/providers/aws/r/cloudwatch_event_target.html
今回必要となるのはECS Scheduled Tasksを実行するRole、実行コマンドが記載されているJSONファイル、各Resorceとそれに伴うevent targetを指定します。
■Terraform
- iam.tf
1 2 3 4 5 6 7 8 9 10 |
## ECS Scheduled Tasks resource "aws_iam_role" "ecsscheduledtasks_role" { name = "ecs-Scheduled-Tasks-Role" assume_role_policy = file("files/assume_role_policy/ecs-scheduled-tasks.json") } resource "aws_iam_role_policy_attachment" "ecsscheduledtasks_role_attach" { role = aws_iam_role.ecsscheduledtasks_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole" } |
- files/assume_role_policy/ecs-scheduled-tasks.json
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } |
- cloudwatch_event_target.tf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
resource "aws_cloudwatch_event_rule" "hoge_worker" { name = "HogeWorker" description = "HogeWorker" schedule_expression = "cron(0 9 ? * MON-FRI *)" is_enabled = "false" } resource "aws_cloudwatch_event_target" "hoge_worker" { target_id = "HogeWorker" arn = aws_ecs_cluster.hoge.arn rule = aws_cloudwatch_event_rule.hoge_worker.name role_arn = aws_iam_role.ecsscheduledtasks_role.arn input = file("files/container-overrides/HogeWorker.json") ecs_target { launch_type = "FARGATE" task_count = 1 task_definition_arn = aws_ecs_task_definition.hoge.arn platform_version = "LATEST" network_configuration { subnets = [aws_subnet.adachin-app-1a.id,aws_subnet.adachin-app-1c.id] security_groups = [aws_security_group.adachin-app.id] assign_public_ip = false } } } |
まずCloudwatchのcronの書き方が特殊なので以下を参考と、デフォルトがUTCなのでJSTに変換して書きましょう。(今回は月曜~金曜の18時/JST) 17行目のタスク定義で最新イメージを取得したい場合は直でリポジトリのリンクを指定しないといけないためハマりどころ。19行目の network_configuration
は launch_type
がFARGATEだとawsvpcモードが必須なので、各サブネットやセキュリティグループを指定してあげてください。
https://dev.classmethod.jp/articles/terraform-ecs-scheduled-task-latest-md/
- files/container-overrides/HogeWorker.json
1 2 3 4 5 6 7 8 |
{ "containerOverrides": [ { "name": "adachin-app", "command": ["bundle","exec","rails","runner","HogeWorker.new.execute"] } ] } |
nameはタスク定義名を指定しないと、いつまでたってもタスク定義で指定したコマンドが実行されてしまうので、他の名前をつけないようにしましょう。
あとはterraform apply!!
- Cloudwatch >イベント>ルール
- ECS/クラスタ/タスク
- Cloudwatch Logs
ログが出ていればOK!
■まとめ
このままバッチが増えるとTerraformで作業が発生してしまうので、共通部分はfor_eachとかで実装すれば良さそうですね。
0件のコメント