ecscheduleにTaskDefinitionの存在チェックを追加した
最近はECS周りにecspressoを使うようになり、その流れで煩雑だったECS ScheduledTaskの管理もecscheduleを使い始めました。そして見事にオペミスをやらかしたので、冬休みの課題がてら防止策を実装してプルリク出してマージされました。
背景
先日Revisionを1個進めて適用していましたが、見事に別のTaskのRevisionを更新しており存在していないためTaskが実行されない状態に陥っていました。(NOT production環境)
意図せずこの状態に陥るとなかなか気づくことが難しいです。ECS上は何もエラーは表示されず、Taskのログを確認しようにも起動していないのでCloudWatchLogsなどには出てこない。唯一気付けるのがFailedInvocationsと言うCloudWatchMetricsなんですが、これ自体はイベントからの起動が失敗したかのメトリクスで、Scheduled Taskでパッと出てきません。さらにLambdaでもEventBridge経由していると同じメトリクスになるため、いまいち点が線にならない。
調べると出てこなくはないんですが、FailedInvocationsを知らないと引きにくいし、前述の通り頭の中ですぐつながらないのです。
対策
原因はわかったんですが、頑張ってもミスる時はミスるのと、FailedInvocationsを監視しても時すでに遅し*1なので根本の設定時にチェックすることにしました。ecscheduleはGoで書かれているので読めるし手も出せるのでちょうどよかったです。
内容は指定してあるTaskDefinitionとRevisionをECS DescribeTaskDefinitionに投げるだけです。これで存在していれば詳細が返ってきて、無ければエラーが返されます。Revisionの指定がなければ最新扱いになるのでそのケースも問題なし。ばばっとコード見て作ってプルリク投げました。*2
ほぼないと思うんですが、存在しないTaskDefinition/Revisionを指定しておいて、定義ができたら動き出すみたいなトリッキーな使い方をしてたら破壊的変更になるので、Opt-out/Opt-inでオプションプランの必要性も聞いてみましたが、それは必要ないかなと言うことでそのままマージしてもらいました。リリースもされてました。
最近はなかなかOSS関係にプライベートで時間割けなかったりしてましたが、いい課題があってサクッとできてよかったです。
補足: AWSマネジメントコンソールの機能とAPI
AWSマネジメントコンソールでScheduledTaskを作ろうとすると、作成済みのTaskDefinitionとRevisionから選ぶようになっており、存在しないものが指定できないようになっています。この手のものはいくつかAPIを組み合わせて実現してあり、ecscheduleはCloudWatchEventのAPIを呼ぶだけなので、TaskDefinitionとRevisionの存在チェックは入っていませんでした。そのため、存在しないTaskDefinitionとRevisionが指定してある状態で作れていました。
AWSマネジメントコンソールが実は裏でやっていることは表からは隠れてしまっているので、ecscheduleに限らずTerraformなどでも似たようなことをやると不足したりすることがよく*3あります。何で作られているかが理解できると、他のサービスを経由して作る場合に追加でチェックが作られています。今回のだとScheduledTaskの起動設定のcron書式などは間違ったものを入れるとCloudWatchEvent APIで弾かれます。これはそもそもCloudWatchEvent自体で使う設定はそのAPIでチェックしているからです。でも、ECSのTaskDefinitionはCloudWatchEventの動作自体には影響がないので、そのAPIではチェックされません(と言うか使われ方次第なのでできません)
APIが先にあり、それを使って画面を作っているのがよくわかります。時々表からは聞いたことない名前のAPIがあったり、途中で名前の変更があったものなどの残骸が見て取れるのでこれはこれで面白いんですが、もうちょっとAWSマネージメントコンソールの裏で何やってるかわかると助かります。