🧪

ECSのデプロイ運用でLatest運用せずCDKと実際のECRバージョンを乖離させない方法

2023/08/06に公開

概要

ECSを本番運用してアプリの更新がある場合、ECRのバージョン管理があると思います。
Latest運用はおすすめされていないため、バージョンをあげつつイミュータブルな設定をしている方が対象読者となります。(参考:[ECR.2] ECR プライベートリポジトリでは、タグのイミュータビリティが設定されている必要があります

バージョンを上げつつ、デプロイの継続はどのように行っていますか?
アプリケーションのデプロイとなるとCDK以外を使うというケースは多いと思います。
初期構築をCDKで行っていた場合、CDKとECRのバージョンが乖離していませんか?

問題:CDKとバージョンが乖離するってどうゆうこと?

以下のケースでトラブルが発生します。

  1. CDKデプロイ:Version1(CDKにVersion1でGit管理されている)
  2. 別手段でデプロイ:Version2に変更された
  3. CDKでECSのタスク以外の箇所を修正:ここで意図せずタスク定義のデプロイが動作する
  4. CDKのVersion1に戻る
  5. デグレ発生!!!

デグレ問題が起こってしまうのです。CDKはdeploy時に裏でCfnを作成し差分を見ています。管理外でバージョンを上げるとCDKもバージョンを合わせることを忘れずに行う必要が発生し、これはとてもうっかりミスが起きやすい作業です。

この解決策としては何通りかあります。
一番思い切ったものはタスク定義をCDKの管理から外して別手段で作成するものです。
マネコンやCLIで初期セットし、ecspressoというOSSツールなどを使ってしまう方法です。

ただ、手のこんだことをせずに、もっと簡単に済ませてしまおう。
というのが今回の記事の本題になります。

解決策:ECRのバージョン「のみ」CDKの管理から外す

この記事で提案する解決策はECRのバージョンはパラメータストアで扱うということです。
・デプロイ時にはパラメータストアを更新する
・CDKでもパラメータストア参照することで常に同じバージョンとなる。デグレが起きない

以下で手順サンプルを記載します。

手順1:パラメータストアは手動で作成しておく

CDKのREADME.mdに作成方法を記載しておきましょう。

$ aws ssm put-parameter --name "ecr名-tag" --value "init" --type String

手順2:ECS管理するCDKスタックにてパラメータストア取得

CDK外でデプロイが行われたとしても常に最新のバージョンが取得されます。

cdkスタック
// コンテナタグ
const ecrTag = StringParameter.valueForStringParameter(
  this,
  "ecr名-tag"
);

手順3:ECSのタスク定義にて参照

ecrTagを参照しているのが最大のポイント

cdkスタック
// ECS コンテナ定義
const containerName = `${prefix}-api-container`;
const container = taskDefinition.addContainer(containerName, {
  image: ContainerImage.fromEcrRepository(apiEcr, ecrTag),
  containerName,
  cpu: 256,
  memoryLimitMiB: 512,
  portMappings: [{ containerPort: 80 }],
  logging: LogDriver.awsLogs({ streamPrefix: containerName, logGroup }),
});

さいごに

パラメータストアを正にする運用さえできれば絶対にデグレは起こりません。可能な限りパラメータストアの更新は自動化するとよいでしょう。
GitHub ActionsなどCI/CDツールによってGitのコミットハッシュを値に入れると、あとから振り返りやすくなり便利かと思います。
バージョン以外の部分(CPUやメモリなど)に手を加えたいときにCDK管理されていることはとても他の選択肢と違って強みになると思います。1箇所に情報が集中するので、見通しがよいところも気に入っています。
Latest運用せずにCDKの乖離を回避する選択肢の1つとして検討してみてはいかがでしょうか。

Discussion