【AWS】Codeサービス群の「Source」の優先度ついて検証してみた
はじめに
今回は、AWS Codeサービス群の挙動について、業務上で発生した疑問を解決するため検証を行ったので、その経緯と結果を共有します。
AWS Codeサービス群とは
AWSでは、継続的インテグレーション/継続的デプロイメント(CI/CD)構成を作成するためのサービスとして、AWS CodeCommit、 AWS CodeBuild、 AWS CodeDeploy、 AWS CodePipelineが提供されています。
本記事では、上記4つのサービスをまとめて「Codeサービス群」と呼称します。
各サービスの解説は割愛しますが、一般的に、
- CodeCommitでソースコードを管理
- CodeCommitのブランチをCodeBuildで指定し、対象ソースコードをビルド
- CodeBuildにより生成されたソフトウェアパッケージをCodeDeployで実環境にデプロイ
という一連の流れをCodePipelineで自動化してCI/CDを実現する、という使われ方をすることが多いです。
Codeサービス群の「Source」とは
Codeサービス群に含まれるCodeBuildとCodePipelineでは、ビルドやパイプライン実行のインプットとなるソースコード群を「Source」と呼び、それぞれAmazon S3やCodeCommit、GitHub、GitLabのブランチ等を指定します。
CodeBuildでビルドを実行する際に作成する「ビルドプロジェクト」と、CodePipelineでパイプラインを実行する際に作成する「パイプライン」は、基本的に独立した別のリソースとなりますが、パイプライン作成画面内のウィザードで、同時にビルドプロジェクトを作成することも可能です。
その場合、ビルドプロジェクトのSourceとしてCodePipelineを指定することができ、CodePipelineのSourceで指定したソースコードを元に、ビルドを含めたパイプラインが実行されます。
一方で、ビルドプロジェクトを個別で作成し、後でパイプラインと紐づけた場合、ビルドプロジェクトのSourceにCodePipelineを指定することが出来ません。ビルドプロジェクト、パイプラインそれぞれで、Sourceを個別に指定する必要があります。
今回の検証内容
ビルドプロジェクト、パイプラインそれぞれで、実行対象とするSourceを個別に指定する、ということは、それぞれで異なるSourceを指定することが可能、ということです。
そこで今回は、ビルドプロジェクトとパイプラインのSourceに、それぞれ異なるソースコード(ブランチ)を指定してパイプラインを流した場合に、どちらのSource設定が優先されてリソースが作成されるのか、という点を調査・検証してみました。
公式ドキュメントを確認してみる
まず、公式ドキュメントを確認すると以下のような表記がありました。
Note The artifact configured in your CodeBuild project becomes the input artifact used by the CodeBuild action in your pipeline.
(日本語訳)CodeBuild プロジェクトで設定されたアーティファクトは、パイプライン内の CodeBuild アクションで使用される入力アーティファクトになります。
Source設定の優先度についての記述とも取れますが、読み方次第では
- ビルドプロジェクトで設定されたアーティファクト(Source)が、パイプラインの入力アーティファクトとして利用される
- ビルドプロジェクトで設定されたアーティファクト(Source)が、パイプラインの入力アーティファクトに上書きされる
のどちらにも受け取れるように感じ、「環境で試した方が早い!」ということで実際にリソースを作成して試してみることにしました。
検証の準備
まず、今回の検証に利用するリソースの作成を行いました。作成のステップは以下の通りです。
- ステップ1. CodeCommitでリポジトリを作成し、検証用ソースコードを格納する
- ステップ2. CodeBuildでビルドプロジェクトを作成する
- ステップ3. CodeDeployでアプリケーションを作成する
- ステップ4. CodePipelineでパイプラインを作成する
なお、各リソースの作成方法はAWS公式ハンズオンを参考にしています。
リソース作成の詳細な手順については本記事に記載していないので、下記ハンズオン(無料・要登録)で紹介されている手順を参照してください。
ステップ1. CodeCommitでリポジトリを作成し、検証用ソースコードを格納する
まずはじめに、CodeCommitに1つリポジトリを作成し、そのリポジトリに「codebuild」「codepipeline」という名前の2つのブランチを作成しました。それぞれのブランチには、表示が異なるHTMLファイルと、CodeBuildで利用するbuildspec.yml、CodeDeployで利用するappspec.ymlを格納しています。
CodebuildのSource設定用ブランチ(ブランチ名:codebuild)のindex.html
「for codebuild」と表示されます。
CodePipelineのSource設定用ブランチ(ブランチ名:codepipeline)のindex.html
「for codepipeline」と表示されます。
ステップ2. CodeBuildでビルドプロジェクトを作成する
次に、ソースコードをビルドするため、CodeBuildでビルドプロジェクトを作成します。
その際、Sourceを指定する欄があるので、ステップ1で作成したCodebuildのSource設定用ブランチ(ブランチ名:codebuild)を設定しました。
ステップ3. CodeDeployでアプリケーションを作成する
ビルドプロジェクトでビルドされたソフトウェアパッケージをEC2にデプロイするため、CodeDeployでアプリケーションを作成します。
CodeDeployのアプリケーションには、Sourceを指定する欄はないため、Application nameとCompute platform(今回はEC2)を設定してアプリケーションを作成した後、Deployment groupsとして事前に作成しておいたデプロイ先のEC2を指定しました。
ステップ4. CodePipelineでパイプラインを作成する
次に、CodePipelineでパイプラインを作成します。
パイプライン作成時にも、ビルドプロジェクト作成時と似たような画面でSourceを設定する欄があるので、こちらではステップ1で作成したCodePipelineのSource設定用ブランチ(ブランチ名:codepipeline)を設定しました。
パイプラインの設定を進めていくと、ビルドステージの設定画面に進みます。
ここで、Input Artifactsという設定項目があることに気が付きました。
今までパイプラインを新規で作成したことが無く、気が付かなかったのですが、このInput Artifactsという項目では、パイプラインを実行した際に「ビルドステージで何をインプットとするのか」を設定することができるようです。
このInput Artifactsの設定こそが、パイプライン実行時にビルド対象としてどのSource設定を優先するのか、を定義する重要な項目だったのです。
この段階で既に、本検証の目的である「ビルドプロジェクトとパイプラインのSourceに、それぞれ異なるソースコードを指定してパイプラインを流した場合に、どちらのSource設定が優先されるのか確認すること」についてほぼ結論が出てしまいましたが、実際にデプロイされたアプリケーションの画面を確認するまで作業を継続しました。
今回の検証時には、Input Artifactsの選択肢として、SourceArtifact(=パイプラインのSourceで設定したソースコード)のみが選択できる状態だったため、SourceArtifactを選択してパイプラインの設定を進めました。
条件次第では他の選択肢も表示されるかもしれませんが、本検証ではそこまで深追いはしていません。
次に、デプロイステージの設定画面に移ります。
デプロイステージの設定画面でも、Input Artifactsの設定項目がありました。
ビルドステージと異なり、SourceArtifactに加えてBuidArtifact(=前段のビルドステージでビルドされた結果、生成されるソフトウェアパッケージ)も選択できたので、両者を設定した場合にどちらが優先されるのか確認するため、SourceArtifactとBuidArtifactの両方を選択しました。
今回、SourceArtifactとして設定しているCodeCommitには、まだビルドされていないソースコードが格納されているため、もしSourceArtifactが優先された場合は、パイプラインのデプロイステージでエラーが発生するはずです。
一方で、BuidArtifactが優先された場合、ビルド済みのソフトウェアパッケージがデプロイのインプットになるため、パイプラインが正常に終了し、リソースが作成されることになります。
以上でパイプラインの設定は終わり、検証の準備が完了しました。
実際に検証してみる
ここからは、実際の検証に入ります。
今回は、当初予定していたSource設定の優先度確認に加えて、検証準備の過程で新たに発生した疑問である、デプロイステージのInput Artifactsの優先度確認を行います。そのため、以下の2つの軸で、パイプラインを通じて作成された環境の確認を行いました。
- 検証1. CodePipelineとCodeBuildのSource設定のどちらが優先されるか
- 検証2. デプロイステージのInput Artifactsとして、SourceArtifactとBuidArtifactどちらが優先されるか
検証1. CodePipelineとCodeBuildのSource設定のどちらが優先されるか確認してみる
まず、検証準備で作成したパイプラインを実行します。
数分後、パイプラインが正常に実行・終了したことが確認できました。
次に、デプロイされたアプリケーションを確認したところ、画面には「for codepipeline」と表示されました。したがって、今回のパイプラインでは、ビルドステージのInput Artifactsの設定どおり、パイプラインのSourceで設定したソースコードが優先されてビルド・デプロイされていることが分かります。
念のため、パイプラインの実行詳細画面にて、ビルドステージのインプット情報を見てみます。
こちらでも、SourceArtifactをインプットとしてビルドが実行されていることが確認できました。
検証2. デプロイステージのInput Artifactsとして、SourceArtifactとBuidArtifactどちらが優先されるか確認してみる
次に、パイプラインの実行詳細画面にて、デプロイステージのインプット情報を見てみます。
こちらでは、BuidArtifactをインプットとしてデプロイが実行されていることが確認できました。
デプロイステージでは、SourceArtifactとBuidArtifactの両方をInput Artifactsに設定しましたが、今回の検証ではBuidArtifactが優先して利用される結果となりました。
ちなみに、デプロイステージのInput ArtifactsをSourceArtifactのみにしてパイプラインを再実行したところ、やはりデプロイに失敗し、パイプラインがエラーとなることも確認できました。
検証結果
ビルドプロジェクトとパイプラインのSourceに、それぞれ異なるソースコード(ブランチ)を指定してパイプラインを流した場合、パイプライン作成時のビルドステージのInput Artifactsの設定に従い、パイプラインで指定したSourceが優先されることが分かりました。
そのため、パイプラインの一環でビルドプロジェクトを実行する場合、ビルドプロジェクトに指定したSource設定は、パイプラインのSource設定に上書きされることになります。
またデプロイについて、パイプラインのデプロイステージ設定時に、Input ArtifactsとしてSourceArtifactとBuidArtifactの両方を選択した場合、BuidArtifactが優先されることが分かりました。
さいごに
今回は、ビルドプロジェクトとパイプラインのSourceに異なるソースコードを指定した場合にどちらの設定が優先されるのか、また、デプロイステージのInput ArtifactsにSourceArtifactとBuidArtifactの両方を選択した場合にどちらが優先されるか、この2点の検証結果をご紹介しました。
本記事が、CodePipelineにおけるパイプライン作成の際の一助になれば幸いです。
Discussion