AWS CDKでS3バケットに資材がPUTされたことをトリガーにECSの1つのコンテナを入れ替えるだけのシンプルなCI/CDパイプラインを作ってみた

AWS CDKでS3バケットに資材がPUTされたことをトリガーにECSの1つのコンテナを入れ替えるだけのシンプルなCI/CDパイプラインを作ってみた

単純な処理でもCI/CDパイプラインを作成しよう
2026.05.15

ECSのコンテナを入れ替えるだけのシンプルなCI/CDパイプラインを作りたい

こんにちは、のんピ(@non____97)です。

皆さんはECSのコンテナを入れ替えるだけのシンプルなCI/CDパイプラインを作りたいなと思ったことはありますか? 私はあります。

コンテンツを更新したあとに環境に反映させるまでには以下ステップを踏むことになります。

  • コンテナイメージをビルド
    • コンテナイメージビルドに必要なアセットがあるのであれば、それを手元に持ってくる作業も
  • ECRにコンテナイメージをPush
  • タスク定義を更新
  • ECSサービスの更新

中々手間です。CI/CDパイプラインを作りたいところです。

ということで、シンプルなCI/CDパイプラインをAWS CDKを作ってみます。

やってみた

検証環境

検証環境は以下のとおりです。

検証環境

1つのECSタスクには複数のコンテナが同居しています。今回はこの内webコンテナだけを入れ替えます。

CI/CDパイプラインで行っていることは以下のとおりです。

要するにHTMLファイルなどのコンテンツをアップロードしたことをトリガーに、DockerfileやNginxのコンフィグファイルなどを固めたzipファイルをダウンロードしてきてコンテナイメージをビルド、デプロイする形です。

今回はアプリケーションの開発環境の都合上、Gitを使用していない or できないことを想定しています。そのため、S3バケットにコンテンツがアップロードされたことをトリガーに動作するようにしています。

また、ECSサービス側ではECSネイティブのBlue/Green Deploymentを使用するようにしています。

こちらのCI/CDパイプラインおよびシェルスクリプトのコードは以下GitHubリポジトリに保存しています。

https://github.com/non-97/aws-cdk-ecs-native-blue-green-cicd-pipeline

Webアプリケーション自体の環境の説明やコードは以下記事、GitHubリポジトリをご覧ください。

https://dev.classmethod.jp/articles/ecs-native-blue-green-deployment-lifecycle-hooks-amazon-q-developer-slack/

https://github.com/non-97/ecs-native-blue-green/tree/v3.0.0

動作確認

動作確認をします。

現在、アクセスをすると以下のようにテキストを返してくれます。

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com/
index.txt v1.0

これをindex.txt v1.1に変更します。

index.htmlのファイルを変更します。

その後、指定したディレクトリをzipで固めて、CodePipelineのSourceステージで使用しているS3バケットに配置するシェルスクリプトを実行します。引数にはビルドしたイメージに付与するタグも指定します。

> bash ./scripts/upload-contents.sh 1.0.1 ./assets/html "" CicdPipelineStack
[1/3] html ディレクトリを zip に固めています: ./assets/html
      ステージングディレクトリを作成...
      staging_dir=/var/folders/4s/dby8gc1n2dj9n433fh6dsksr0000gn/T/tmp.jgtKZwncTU
      html をコピー: ./assets/html -> /var/folders/4s/dby8gc1n2dj9n433fh6dsksr0000gn/T/tmp.jgtKZwncTU/html
      zip 化: /var/folders/4s/dby8gc1n2dj9n433fh6dsksr0000gn/T/contents-XXXXXX.zip.sK55E8pazl
      zip 作成: /var/folders/4s/dby8gc1n2dj9n433fh6dsksr0000gn/T/contents-XXXXXX.zip.sK55E8pazl
[2/3] ContentsBucket を解決しています (引数 or Stack 'CicdPipelineStack' CfnOutput)
      ContentsBucket: cicdpipelinestack-contentsbucket571b0902-ecg8fnfbdlxv
[3/3] S3 にアップロードしています (version=1.0.1)
アップロード完了: contents.zip (version=1.0.1) -> s3://cicdpipelinestack-contentsbucket571b0902-ecg8fnfbdlxv/contents.zip

アップロード完了したようですね。

CodePipelineを確認すると、もうDeployステージまで進んでいますね。

1.パイプライン.png

ECSタスクの状態を確認すると、新旧2種類計4つのECSタスクが起動していました。

2.タスクの状態.png

私はライフサイクルフックの設定をしていたので、指定していたSlackチャンネルに通知が来ました。

3.通知.png

この状態で本番リスナーとテストリスナーにアクセスします。

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com/
index.txt v1.0

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com:10080/
index.txt v1.1

テストリスナーにアクセスした場合、テキストが変わっていることが分かりますね。

再ルーティングボタンを押下して、本番トラフィックの再ルーティングを行います。

すると、本番リスナーでもレスポンスの内容が変わりました。

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com/
index.txt v1.1

CodePipelineも正常に実行完了しています。

4.CodePipelineの実行結果.png

ロールバックした場合の挙動も確認しましょう。

index.htmlの内容をindex.txt v1.2に変更して、再度upload-contents.shでS3バケットにPUTします。

しばらくすると、指定したSlackチャンネルに再ルーティングするかロールバックするかの確認通知が来ました。

動作確認をします。

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com/
index.txt v1.1

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com:10080/
index.txt v1.2

テストリスナーのみレスポンスの内容が変わりましたね。

今回はロールバック時の挙動の確認なので、ロールバックボタンを押下します。

5.ロールバックの実行.png

ロールバックを行うと、CodePipelineのDeployアクションが失敗しました。

6.ロールバックした時のパイプライン.png

ロールバック後に再度アクセスをすると、以下のようにテストリスナーアクセス時のコンテンツが元に戻りました。

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com/
index.txt v1.1

> curl http://EcsNat-AlbCo-MVM2FDwH12Al-988247753.us-east-1.elb.amazonaws.com:10080/
index.txt v1.1

単純な処理でもCI/CDパイプラインを作成しよう

AWS CDKでS3バケットに資材がPUTされたことをトリガーにECSの1つのコンテナを入れ替えるだけのシンプルなCI/CDパイプラインを作ってみました。

単純な処理であっても何回も繰り返し行うのであれば、トータルではかなり時間を費やしてしまうことになります。自動化できるものは自動化してしまいましょう。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事