🤯

タスク定義が 100 個を超えたら ECS にデプロイできなくなった

2024/01/24に公開

ある日 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 回実行します。このため、クエリには各ページで最初に一致する要素が含まれており、予期しない余分な出力が発生する可能性があります。出力をさらにフィルタリングするには、headtail などの他のコマンドラインツールを使用できます。

ちなみに、--output text は、出力からダブルクォーテーションをなくすのに必要です。

ページングを考慮したコマンドに修正する

AWS CLI のページ分割オプションを使用するを参考に、ページングを考慮してアクティブなタスク定義の数に関係なく、最新のタスク定義を 1 つだけ取得できるようにしました。

bash
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  テックブログ

Discussion