NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    改めてCI/CDパイプラインを使ったECS自動デプロイの流れを整理する

    本記事は  【コンテナウィーク】  1日目の記事です。
    💻  告知記事  ▶▶ 本記事 ▶▶  2日目  📱

    こんにちは。梅原です。

    皆さんはCI/CDパイプラインやってますか。昨今はパイプラインファーストという考え方もあり、ソースコードの変更反映をトリガーにテストやビルド、デプロイまで自動でやることは多いのではないでしょうか。

    今回はAWSでCI/CDパイプラインを実現するためのサービスであるCodeシリーズ(CodeCommit、CodeBuild、CodeDeploy、CodePipeline)を使ってECSへ自動デプロイする流れを見ていきます。

    AWSでCI/CDパイプラインを実現するために

    そもそもCI/CDパイプラインは、継続的インテグレーション/継続的デリバリーの略で、これまで手動でしていたテストやビルド、デプロイ作業を自動化・高速化するために使われるものです。 CI/CDパイプラインを使うことで、開発効率やリリース効率を向上できるようになります。

    AWSでCI/CDパイプラインを実現するためには、以下4つのサービスを使います。

    • AWS CodeCommit (ソースコード管理)

    • AWS CodeBuild (ソースコードのテストやビルド)

    • AWS CodeDeploy (ビルドされたものからデプロイを行う)

    • AWS CodePipeline (上記3サービスを統括)

    CodePipelineでCodeCommit、CodeBuild、CodeDeployを繋げることで、ソースコードの変更反映をトリガーにデプロイまで自動で実施することができます。
    リポジトリの反映からCodePipelineでECSへデプロイするまでの流れとして、

    1. リポジトリへの反映
    2. ソースステージ
    3. ビルドステージ
    4. デプロイステージ

    の4ステージあります。

    リポジトリへの反映は文字通り、ソースリポジトリへソースコードのpushやマージリクエストの取り込みといったCodeCommitへの変更反映を実施します。

    ソースステージでは、リポジトリの反映をトリガーに、後続のビルドステージに必要なソースコードをリポジトリから取得します。 トリガー元のソースリポジトリはGitHubやBitBucket、S3、ECRなどがあり、最近ではSaaS版のGitLabも対応しました。

    ビルドステージでは、buildspec.yamlに記述された命令を元にソースコードのテストやビルド、dockerイメージのビルド、dockerイメージをレジストリにpushします。 JenkinsといったOSSを使用する場合は別途サーバーが必要となりますが、Codebuildではサーバーを意識する必要がありません。
    また、ビルド上で出力される成果物のことをビルドアーティファクトと呼び、後続のデプロイステージで利用されます。 ソースコードはソースアーティファクトと呼ばれ、CodeBuildの処理される前にも使用されています。

    最後のデプロイステージでは、ソースアーティファクトやビルドアーティファクトを元に、ECSなどにデプロイを実施します。 デプロイ対象はECSだけでなく、EC2はもちろんS3やCloudFormationなどへも可能です。
    ECSにデプロイする方法として、ローリングアップデートとBlue/Greenデプロイがあります。 2つのデプロイ方法の比較は以下ブログを参照ください。 tech.nri-net.com

    ローリングアップデートとBlue/Greenデプロイで必要なファイルが異なります。今回はBlue/Greenデプロイを説明します。
    Blue/GreenデプロイはCodeDeployと統合されており、CodeDeployのデプロイ情報を記載したappspec.yamlとイメージの場所を示すimageDetail.json、タスク定義書の元が必要になります。
    必要なファイルの違いは以下を参照ください。

    docs.aws.amazon.com

    ECSサービスにデプロイするときは、新しいコンテナイメージを向いたタスク定義書を作成し、そのタスク定義書を元にECSサービスを更新する必要があります。 新しいタスク定義書の作成やECSサービスのアップデートといった部分は、CodePipelineないしCodeDeployでよしなにやってくれます。 ビルドステージで新しいコンテナイメージのURIの情報をビルドアーティファクトとしてimageDetail.jsonで出力します。 CodeDeployでソースコードに含めておいたappspec.yamlとtaskdef.jsonのプレースホルダーをビルドアーティファクトから設定し、CodeBuildでpushした新しいコンテナイメージをデプロイしてくれます。

    これらを図にまとめると以下になります。 CodeCommitに変更を反映した後、CodePipelineが実行され、CodeBuild上でソースコードのテストやdockerイメージのビルドされ、CodeDeployソースアーティファクトとビルドアーティファクトを元にデプロイされます。

    詳細の流れを見ていく

    ただ、この図だけでは各サービスが単独で動作しており、まだ処理のつなぎの流れは見えないと思います。 ソースコードへのpushからデプロイまで各ステージの詳細の流れを初めから見ていこうと思います。

    1. ソースコードの変更反映

    開発者はデプロイを開始したいときは、CodeCommitへソースコードの変更をpushします。 CodeCommitの変更がイベントとしてEventBridgeへ渡されて、EventBridgeがパイプラインを実行し後続のステージへ繋がります。(CodePipelineの検出方法としてCloudWatch Eventsを設定した場合)
    図ではmainブランチに直でpushしていますが、通常はマージリクエストを出して特定のブランチに取り込むと思います。そのようなマージリクエストの変更をトリガーに設定できます。

    2. ソースステージ

    実行されたCodePipelineはソースステージへと入り、CodeCommitからソースコードの取得がなされます。 CodePipelineに指定したサービスロールでCodeCommitのリポジトリを取得し、ソースアーティファクトとしてS3に保存します。

    3. ビルドステージ

    S3内のソースアーティファクトのbuildspec.yamlに記述した命令を元にテストやビルド、ECRへのpush、imageDetail.jsonの作成を実施します。 imageDetail.jsonはビルドアーティファクトとしてS3に保存されます。

    4. デプロイステージ

    ソースアーティファクトのappspec.yamlとtaskdef.json、ビルドアーティファクトのimageDetail.jsonを元にCodeDeployがデプロイをしてくれます。その後はCodeDeploy内でBlue/Greenデプロイを開始してくれます。 先述の通り、タスク定義書の作成やECSサービスの更新等のコマンドは不要でサービス側でよしなにやってくれます。

    最後に

    この通り、CI/CDパイプラインはただ各サービスが単独で動作しているわけではなく、ファイルの受け渡しとしてS3や変更反映イベント発行でEventBridgeといったサービスが使用されています。
    このブログで記載したCI/CDパイプラインが基本の形だと思います。要件によっては承認フローを挟んだり、Lambdaで処理を挟んだりといろいろなことが必要になると思います。CodePipelineではそのようなことも可能です。

    また、最近のアップデートでCodePipeline v2が出て動的なパラメーターを設定できたり、CodeBuildはコンピュートタイプとしてLambdaを選択できるようになっています。より便利により柔軟なパイプラインが組めるようになっています。

    執筆者 梅原航

    クラウドエンジニア
    2024 Japan AWS Jr. Champions
    2025 Japan All AWS Certifications Engineers