タスク定義が 100 個を超えたら ECS にデプロイできなくなった
ある日 ECS にデプロイできなくなった
いつも通り、ECS (AWS Fargate) にデプロイしようとすると、以下のコマンドでエラーになりました。
デプロイは GitHub Actions から行っています。
// ①最新のタスク定義を取得する
$ ecs_app_task_definition_arn=$(aws ecs list-task-definitions \
--family-prefix <タスク定義名> \
--query "reverse(taskDefinitionArns)[0]" \
--output text)
// ②最新のタスク定義でサービスを更新する
$ aws ecs update-service \
--task-definition $ecs_app_task_definition_arn \
--cluster <クラスター名> \
--service <サービス名> \
--desired-count 1 \
--force-new-deployment
エラー内容は以下です。
Unknown options: <タスク定義名>:<バージョン>
Error: Process completed with exit code 252.
エラーコード 252 は「コマンド構文が無効、不明なパラメータが指定されている、またはパラメータの値が正しくないため、コマンドを実行できませんでした。」というエラーです。
直近でコマンドの修正はしていません。みなさんは何が原因かわかるでしょうか?
ちなみに、以下のコマンドを CloudShell から実行してみるとエラーになりません。
$ aws ecs update-service \
--task-definition <最新のタスク定義> \
--cluster <クラスター名> \
--service <サービス名> \
--desired-count 1 \
--force-new-deployment
原因
調査を進める中でタスク定義が 100 個を超えると、①最新のタスク定義を取得するコマンドで 2 件のタスク定義が返ってくることがわかりました。
これはページングを考慮できていないためです。
ドキュメントに記載はないですが、タスク定義取得時のページサイズはデフォルトでおそらく 100 になっていて、101 個のタスク定義があると、1 ページ目(1 ~ 100 個目)で --query
にマッチするタスク定義と、2 ページ目(101 個目)で --query
にマッチするタスク定義の 2 つが取得できるようです。
その結果、2 個のタスク定義が ②最新のタスク定義でサービスを更新するコマンドに渡されて、Unknown options
エラーになったというわけです。
ページングについて
ページングについては AWS CLI のドキュメントに記載がありました。
指定する出力タイプによって、--query
オプションの動作が変更されます。
•
--output text
を指定する場合、出力は--query
フィルターが適用される前にページ分割され、AWS CLI は出力の各ページでクエリを 1 回実行します。このため、クエリには各ページで最初に一致する要素が含まれており、予期しない余分な出力が発生する可能性があります。出力をさらにフィルタリングするには、head
やtail
などの他のコマンドラインツールを使用できます。
ちなみに、--output text
は、出力からダブルクォーテーションをなくすのに必要です。
ページングを考慮したコマンドに修正する
AWS CLI のページ分割オプションを使用するを参考に、ページングを考慮してアクティブなタスク定義の数に関係なく、最新のタスク定義を 1 つだけ取得できるようにしました。
ecs_app_task_definition_arn=$(aws ecs list-task-definitions \
--family-prefix <タスク定義名> \
- --query "reverse(taskDefinitionArns)[0]" \
- --output text)
+ --sort DESC
+ --max-items 1
+ --query "taskDefinitionArns[0]" \
+ --output text | head -n 1)
おわりに
特定の条件でのみエラーが起こるので、初めは何が問題かわからずハマってしまいましたが、デプロイに失敗したタスク定義を登録解除してみたり、エラーになるケースとならないケースを比べることで、アクティブなタスク定義の数が 100 個を超えるとエラーになることに気づけました。
試行錯誤する前に、エラー内容と該当のコマンドから、①最新のタスク定義を取得するコマンドを実行してみるべきでした😅
今後は AWS CLI で --query
オプションを使う時は、ページングに注意していこうと思います。
私たち BABY JOB は、子育てを取り巻く社会のあり方を変え、「すべての人が子育てを楽しいと思える社会」の実現を目指すスタートアップ企業です。圧倒的なぬくもりと当事者意識をもって、こどもと向き合う時間、そして心のゆとりが生まれるサービスを創出します。baby-job.co.jp/
Discussion