Amazon ECS サービスを更新していないタスク定義のリビジョンは ECS 標準デプロイアクションでは無視される
2024.12.23
この記事は NHN テコラス Advent Calendar 2024 の 23 日目の記事です。
概要
ECS のタスク定義を更新した後、CodePipeline を実行するとタスク定義で変更した更新がロールバックされていました。
その動作と解決策について色々と検証した記録をまとめます。
結論
先に結論を述べます。
ECS 標準デプロイアクションの仕様として、ECS サービスを更新していないタスク定義のリビジョンは無視されるようです。
CodePipeline の Amazon ECS 標準デプロイアクションは、Amazon ECS サービスによって使用されるリビジョンに基づいて、タスク定義の独自のリビジョンを作成します。
Amazon ECS サービスを更新せずにタスク定義の新しいリビジョンを作成した場合、デプロイアクションはそれらのリビジョンを無視します。
Tutorial: Amazon ECS Standard Deployment with CodePipeline – AWS CodePipeline
そのため、今回の検証内容のように以下の両条件を満たす場合、タスク定義を更新する際は変更がロールバックされる可能性があるためご注意ください。
- タスク定義のリビジョンだけを更新した場合
- ECS サービスは更新していない
- CodePipeline の ECS 標準デプロイアクションを実行する場合
対策としては、タスク定義のリビジョンを更新した後、ECS サービスで最新のリビジョンを使用してタスクをデプロイしてください。
発生した事象
発生した事象の前提について、以下の内容に沿って簡単に記述します。
- 構成図
- 発生した事象
構成図
ポイントとしては、以下の通りです。
- CodePipeline のデプロイステージでは、「ECS 標準デプロイアクション」を使用している点
- ECS 標準デプロイアクションでは、タスク定義の独自のリビジョンを新規で作成する点
その他については、基本的な ECS 設定 と CI/CD の環境です。
チュートリアル: を使用した Amazon ECS 標準デプロイ CodePipeline – AWS CodePipeline
Amazon Elastic Container Service デプロイアクションリファレンス – AWS CodePipeline
発生した事象
実際の動作については、後述の検証で確認しますが以下の流れです。
ここでは、構成図をもとに机上で解説します。
1. 初期状態
リビジョン 1 のタスク定義を用いて、タスクが起動している状態です。
2. 手動でタスク定義を更新した状態
タスク定義を CPU とメモリのみを手動でコンソールから更新します。
3. CodePipeline で自動パイプライン実行された状態
CodePipeline を実行すると新しいタスク定義が作成されます。
作成された新しいタスク定義のリビジョン 3 にはリビジョン 2 の CPU とメモリが引き継がれておりません。
リビジョン 2 で手動で変更した内容をもとに、新しいリビジョン 3 のタスク定義がデプロイされることを期待しましたが、実際はリビジョン 1 の内容がデプロイされています。
回避する方法
ECS 標準デプロイアクションは、現在デプロイされているタスク定義をもとに更新を行う仕様のようです。
そのため、タスク定義を更新した場合は、そのタスク定義でタスクをデプロイするようにすれば、設定がロールバックされることはありません。
この動作は、CodePipeline の仕様のようなので、運用面で見直していくしか方法はなさそうです。
動作検証
では、続いては上述した動作を実際に検証してみます。
この動作検証では、以下の 2 つのケースを確認します。
- 手動でタスク定義のリビジョンを更新しただけの場合
- 実際の挙動の事実確認
- 手動でタスク定義のリビジョンを更新したあと ECS サービスをアップデートした場合
- 事象を回避するための方法
手動でタスク定義のリビジョンを更新しただけの場合
手順
- タスク定義を手動で更新
- CPU とメモリを変更
- CodePipeline でパイプラインを実行
- 新しいリビジョンでタスク定義を更新
- ECS サービスが更新される
- 新しいリビジョンのタスク定義でタスク作成
まずは、リビジョン 1 でデプロイしている状態です。
リビジョン 1 のタスク定義の CPU とメモリは以下の通り定義しています。
- CPU : 2 vCPU
- メモリ : 4 GB
1. タスク定義を手動で更新
では、タスク定義をコンソールから手動で更新します。
リビジョン 2 のタスク定義の CPU とメモリは以下の通り更新しています。
- CPU : 2 vCPU → 1 vCPU
- メモリ : 4 GB → 3 GB
この状態で、 ECS サービスのタスク定義は更新しません。
2. CodePipeline でパイプラインを実行
では、続いては、パイプラインを実行します。
デプロイまで完了しました。
3. ECS サービスが更新される
まず、タスク定義の状態から確認します。
リビジョン 3 に更新されていました。
リビジョン 3 の内容は、リビジョン 1 の CPU とメモリが引き継がれています。
次に、ECS サービスを確認します。
パイプラインで更新されたリビジョン 3 が指定されています。
当初、発生した事象が確認できました。
次は、これを回避する方法を試します。
手動でタスク定義のリビジョンを更新したあと ECS サービスをアップデートした場合
先ほどと違い、パイプラインを実行する前に、ECS サービスの更新手順を追加しています。
手順
- タスク定義を手動で更新
- CPU とメモリを変更
- 更新したリビジョンで ECS サービスを更新
- CodePipeline でパイプラインを実行
- 新しいリビジョンでタスク定義を更新
- ECS サービスが更新される
- 新しいリビジョンのタスク定義でタスク作成
先ほど使用したタスク定義をそのまま使うので、リビジョン 3 を初期状態とします。
リビジョン 3 のタスク定義の CPU とメモリは以下の通り定義しています。
- CPU : 2 vCPU
- メモリ : 4 GB
1. タスク定義を手動で更新
では、先ほどと同じ様にタスク定義を更新します。
リビジョン 4 のタスク定義の CPU とメモリは以下の通り更新しています。
- CPU : 2 vCPU → 1 vCPU
- メモリ : 4 GB → 3 GB
2. 更新したリビジョンで ECS サービスを更新
次は、先程はなかった手順で ECS サービスを先程のリビジョン 4 に更新します。
3. CodePipeline でパイプラインを実行
ここからは同じ様に、パイプラインを実行し、デプロイまで完了しました。
4. ECS サービスが更新される
まず、タスク定義から確認しますが、リビジョンが 5 に更新されています。
内容は以下の通りです。
CPU とメモリは、リビジョン 4 を引き継いでいます。
意図した通りの挙動になっています。
タスクを見ると、リビジョン 5 がデプロイされています。
まとめ
CodePipeline の仕様によって、設定がロールバックすることがあるため、運用の際はご注意ください。
参考情報
Tutorial: Amazon ECS Standard Deployment with CodePipeline – AWS CodePipeline
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitter2021年新卒入社。インフラエンジニアです。RDBが三度の飯より好きです。 主にデータベースやAWSのサーバレスについて書く予定です。あと寒いのは苦手です。
Recommends
こちらもおすすめ
-
『生成 AI』における『ガードレール』とは?
2024.12.14
-
Amazon ECSコンテナ #SaaS化 :クラスター生成、タスク定義
2023.11.8
-
OWASP Top10 脆弱性とは?
2024.12.2
-
Auto Scalingで起動テンプレートに更新をかけずにAMIを更新する方法
2024.12.20
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16