本記事は
【コンテナウィーク】
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へデプロイするまでの流れとして、
- リポジトリへの反映
- ソースステージ
- ビルドステージ
- デプロイステージ
の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、タスク定義書の元が必要になります。
必要なファイルの違いは以下を参照ください。
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