スパイスな人生

素敵な人生をおくるためのスパイスを届けていきたい、そんな想いで仕事をするspice lifeメンバーブログ

AWS CloudWatch Eventsをcronとして使う powered by maekawa

f:id:yu_suke1994:20170308012920p:plain

おはようございます。cronは「クーロン」と読むうなすけです。

実は2月頭からTMIX開発チームを離れ、インフラチームに所属しています。そして、インフラチームとしての初仕事として、AWS CloudWatch Eventsを用いたバッチ処理行基盤の構築を行いました。

バッチ処理基盤の要件

Webサービスがある程度の規模に成長すると、一定の期間で定期的に実行するバッチ処理が必要になるでしょう。もちろんTMIXでもバッチ処理は必要で、それはアプリケーションサーバーのひとつにcronjobの実行を任せることで行っていました。

しかし、TMIXを将来Dockerで動かすことを考えると、いつ破棄されるか不明なコンテナでcronを実行させる訳にはいかず、この方法はいずれ使えなくなります。なにかしら別の方法を考える必要があります。

そして、次のような要件を定義しました。

処理自体は ECS Task で行う (MUST)

処理に関わる環境の構築について考えることを減らせるので、これは必須要件です。

実行ログ (MUST)

言わずもがな、これも必須要件です。

コードベースでの管理 (SHOULD)

Pull Requestを経由して、レビューを行ってからジョブの登録をしたいので、javan/whenever のようなDSLでも、もしくはcrontabそのものでも、とにかくジョブがコードで管理されている状態にしたいです。

マネージドサービスであること (SHOULD)

運用コストを削減したいからDocker化するのであって、ここで新たに管理対象が増えるのは避けたいところです。

ただ、ECSで運用できるのであればマネージドでなくてもよいことにしました。

実行時エラーを検知したい (SHOULD)

エラーが発生したことは何らかの方法で知る必要があります。

ワークフロー管理 (MAY)

cronサーバの代替なので、ワークフロー管理は必須ではありませんが、あれば言うことはないでしょう。

その他にもいくつかの要件がありましたが、大きなものは以上です。これらの要件を満たすかどうか、いくつかのジョブスケジューラーを比較・検討してみました。

検討したもの

kuroko2

cookpad/kuroko2 は、cookpadで開発されたジョブスケジューラ、ワークフローエンジンです。

techlife.cookpad.com

kuroko2はよくできたジョブスケジューラですが、ジョブのコード管理ができず、ECS上で動かすことが困難であった(ように見えた)ので採用はしませんでした。

rundeck

rundeckは、オープンソースで開発されているジョブスケジューラで、有料のマネージドサービスもあります。

rundeck.org

rundeckは公式なDockerfileが見当らず、マネージドサービスは高価すぎるので採用はしませんでした。

AWS Batch

AWS BatchはAWSが用意しているフルマネージドのバッチ処理基盤です。

aws.amazon.com

AWS Batchはスケジュールに従って実行する機能がないこと、また僕が評価のために試用したときにいくら待ってもジョブが実行されずに評価不可能だったので採用しませんでした。

AWS CloudWatch Events

AWS ClowdWatch EventsはAWSが用意している、AWSのリソースの変化をトリガーとして様々な機能を呼び出すことのできるサービスです。

docs.aws.amazon.com

ClowdWatch Eventsは定期的、もしくはcron書式によるイベントを定義することができ、そこからAWS lambdaを経由してECS RunTaskを実行することができます。

しかし、コードによる管理は、それを行うツールが調べた限りでは存在しませんでした。

maekawaというCLI toolの開発

どのようなジョブが登録されているのか、どのようなジョブを登録しようとしているのかをPull Requestベースで管理したいので、 定義ファイルに従って状態を変更する、 codenize-tools/miamcodenize-tools/roadworker のようなべき等性を持つCLI toolが必要でした。

そこで、べき等性を持つ、CloudWatch Eventsを管理するCLI tool、maekawaを作成しました。

github.com

maekawaによって……

  • CloudWatch EventsのRuleとTargetの組み合わせをYamlによって管理
  • Yamlの定義に従ったRuleとTargetの登録もしくは削除

が可能になり、Pull Requestをベースとした、CIによるジョブスケジュールの定義が可能になりました。

maekawaは単なる社内ツールとしてではなく、OSSとして公開することにしました。また。個人的にチャレンジしたかったので、Golangで書いています。Golangで書いたことによって、CI環境へのセットアップが容易にできるようになったのは、予期しない利点でした。

全体的な処理の流れ

まず、cron書式などによって定義された時刻に、CloudWatch Eventsによってlambda functionが実行されます。lambda functionは、それ自体はECS RunTaskを実行するだけの薄い層として存在するだけです。lambdaを通じて実行されたECS Taskによって、目的のバッチ処理が実行される、という流れになっています。

なにに使用しているのか

こうして新しくなったバッチ処理基盤ですが、これで何を実行しているのかというと、現状は

などです。

今後、様々なジョブが登録されていくと思います。

以上、僕のインフラチーム移籍後の初仕事でした。今後ともTMIXならびにSTEERSをよろしくお願いします。