🥇

【AWS】Codeサービス群の設定項目を考察してみた

に公開

はじめに

今回は、AWS Codeサービス群について、基本的な概要と作成方法をおさらいしたうえで、各設定項目について深堀りを行っていきます。
また、Codeサービス群を利用中に発生した疑問を解決するため検証を行ったので、加えてその経緯と結果を共有します。

AWS Codeサービス群とは

AWSでは、継続的インテグレーション/継続的デプロイメント(CI/CD)構成を作成するためのサービスとして、AWS CodeCommitAWS CodeBuildAWS CodeDeployAWS CodePipelineが提供されています。
本記事では、上記4つのサービスをまとめて「Codeサービス群」と呼称します。

各サービスの解説は割愛しますが、一般的に、

  1. CodeCommitでソースコードを管理
  2. CodeCommitのブランチをCodeBuildで指定し、対象ソースコードをビルド
  3. CodeBuildにより生成されたソフトウェアパッケージをCodeDeployで実環境にデプロイ

という一連の流れをCodePipelineで自動化してCI/CDを実現する、という使われ方をすることが多いです。

CI/CDパイプラインを作成しながら設定項目を見ていく

それではさっそく、以下の手順でAWS Codeサービス群を利用したCI/CDパイプラインを作成しながら、各設定項目を詳しく見ていきます。

  1. CodeCommitでリポジトリを作成
  2. 1で作成したリポジトリにソースコードをCommit、Push
  3. CodeBuildでビルドプロジェクトを作成
  4. CodeDeployでアプリケーションを作成
  5. CodePipelineでパイプラインを作成

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cicd-2022-reg-event.html

1. CodeCommitでリポジトリを作成

まずはCodeCommitで、ソースコードを管理するリポジトリを作成します。

1-1. [Create repository]を押下

1-2. [Repository name]、[Description](任意)、[Tags](任意)を入力

1-3. [Additional configuration]はデフォルトのまま下にスクロール

  • AWS KMS Key
    暗号化キーの種別を選択する項目です。

    • Customer managed key(デフォルト)
      セキュリティ要件が高く、キーの高度な管理や細かな制御が必要な場合、また、利用環境でAWS利用ポリシーでカスタマーマネージドキーの利用が求められている場合は、カスタマーマネージドキーを利用することを検討してください。
    • AWS managed key
      特に上記の要件が無い場合は、基本的にAWSマネージドキーで問題ありません。今回も、AWSマネージドキーを選択して後続の作業を進めていきます。

    (参考)https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/concepts.html

1-4. [Create]を押下

  • Enable Amazon CodeGuru Reviewer for Java and Python
    リポジトリにAmazon CodeGuruを紐づけ、機械学習によってコードレビューをする機能です。
    (参考)https://aws.amazon.com/jp/blogs/devops/automate-code-reviews-with-amazon-codeguru-reviewer/
    今回は「CICDパイプラインの作成」にフォーカスを当てるため、デプロイするアプリケーションはHTMLのみで構成されるシンプルなWebサイトとします。なので、今回は本項目にチェックをせずに[Create]を押下します。

リポジトリ作成が完了しました。

2. 1で作成したリポジトリにソースコードをCommit、Push

次に、Webサイトの表示で利用するindex.htmlと、CodeBuildで利用するbuildspec.yml、CodeDeployで利用するappspec.ymlを作成し、1で作成したリポジトリにCommit、Pushをします。

index.html
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS World!!
</body>
</html>
buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - aws deploy push --application-name [アプリケーション名] --s3-location s3://[事前に作成したS3バケット名]/artifact.zip --source src
artifacts:
  files:
    - '**/*'
  base-directory: src
appspec.yml
version: 0.0
os: linux
files:
  - source: index.html
    destination: /var/www/html/

3. CodeBuildでビルドプロジェクトを作成

次に、CodeBuildでビルドプロジェクトを作成していきます。

3-1. [Create project]を押下

3-2. [Project configuration]設定

プロジェクトの基本設定をしていきます。
[Project name]を入力し、[Project type]と[Additional configuration]はデフォルトのまま進めます。

  • Project type
    ビルドステップを実行方法、および実行環境を設定する項目です。

    • Default project(デフォルト)
      buildspec.yamlに基づき、CodeBuild上でビルドステップを実行します。
      今回は前述のbuildspec.ymlを利用してビルドプロジェクトを作成するため、デフォルト設定であるDefault projectを選択します。
    • Runner project
      GitHubやGitLabで、セルフホステッドランナーを実行します。
  • Public build access(デフォルト:無効)
    ログやartifact等を含むビルドの結果にパブリックアクセスできる機能です。
    OSSのコントリビューター向けにビルド結果を公開するような場面で利用しますが、特段要件が無ければ無効にしておくことをお勧めします。

  • Build badge(デフォルト:無効)
    埋め込み可能な画像(=badge)が動的に生成され、最新ビルドのステータスを表示できます。認証が不要で、誰でもCodeBuildプロジェクトのステータスを確認できることがメリットです。

  • Enable concurrent build limit(デフォルト:無効)
    当該プロジェクトで許可される同時ビルドの数を制限することができます。

3-3. [Source]設定

ビルドのインプットとなるソースを定義します。
※Sourceの詳しい解説は後述します。
事前に作成したCodeCommitリポジトリのmasterブランチを指定し、[Additional configuration]はデフォルトのまま下にスクロールします。

  • Source provider
    ソース取得元サービスを選択する項目です。
    以下の通り7つの選択肢からソース取得元を選択することができます。
  • Git clone depth
    指定した数のコミット履歴だけに限定したデータを取得します。デフォルトは「1」です。

3-4. [Environment]設定

ビルドを実行する環境を定義します。
こちらは全てデフォルトのまま進めます。

  • Provisioning model
    リソースのプロビジョニングの方針を設定します。

    • On-demand(デフォルト)
      必要な時に必要なだけリソースをプロビジョニングする方法です。
    • Reserved capacity
      使用料金を前払いすることで大幅にコスト削減を実現できる方法です。事前にリソースを利用するボリュームや期間が決まっているようであれば、こちらを選択した方がコストが抑えられます。
  • Compute
    ビルドに利用するコンピューティング環境を設定する項目です。

    • EC2(デフォルト)
      柔軟性を重要視した選択肢です。
      Lambdaには様々な制限(後述)があるため、速度を求められる要件が無ければこちらで良いと思います。
    • Lambda
      速度を重要視し、ビルドの起動時間を最小限に抑えたい場合に選択します。ただし、次のユースケースはLambdaではサポートされていません:
      • Provisioning modelで「Reserved capacity」を利用する場合
      • ビルド間でキャッシュを利用したい場合
      • タイムアウトによる実行時間の制限を設けたい場合
      • ルートユーザー権限を必要とするツールを利用する場合
  • Operating system
    ビルドに利用するOSを設定する項目です。
    [Running mode]でContainerを選択した場合、以下の選択肢から選択が可能です。

  • Additional configuration
    より詳細な設定が可能ですが、本記事では解説を割愛します。

3-5. [Buildspec]設定

ビルドの実行内容を定義します。
事前に用意したbuildspec.ymlを利用するよう設定します。

  • Build specifications
    buildspecの指定方法を設定する項目です。
    • Insert build commands(デフォルト)
      本画面に直接buildspecを記述する場合に選択します。
    • Use a buildspec file
      別途用意したyamlファイルを利用する場合に選択します。

3-6. [Batch configuration]設定

今回、Batch configurationはデフォルトのオフのままにします。

  • Define batch configuration
    バッチビルドを使用して、複数のビルドタスクを並列に実行したり、順番に実行していくことが可能になります。

3-7. [Artifacts]設定

ビルド作業で生成された成果物(=Artifacts)の出力先を定義します。
[Type]にAmazon S3を選択しし、Bucket nameに事前に作成しておいたS3バケットを指定します。

3-8. [Logs]設定

CloudWatch logsの設定がデフォルトでオンになっているので、そのまま進めます

3-9. [Create build project]を押下

これで、ビルドプロジェクトの作成が完了しました。

4. CodeDeployでアプリケーションを作成

次に、CodeDeployでアプリケーションを作成していきます。

4-1. [Create project]を押下

4-2. [Application configuration]設定

アプリケーションの基本設定をしていきます。
[Application name]を入力し、[Compute platform]はEC2/On-premisesを選択します。

  • Compute platform
    デプロイに利用するプラットフォームを設定します。以下の選択肢から選択が可能です。

4-3. [Create application]を押下

アプリケーションの作成が完了しました。

4-4. [Create deployment group]を押下

次にdeployment groupを作成していきます。

4-4. [Deployment group name]、[Service role]設定

[Deployment group name]を入力し、CodeDeploy用のIAMロールを新規作成[Service role]に設定します。

4-5. [Deployment type]設定

次に、デプロイメントタイプを定義します。
今回は、あくまでサンプルアプリであり、デプロイ時の一時停止を許容できるため、In-placeを選択します。

  • Deployment type
    デプロイメントの実行方針を設定する項目です。
    • In-place(デフォルト)
      デプロイメントグループ内のインスタンスを最新のアプリケーションリビジョンで更新します。デプロイメント中、各インスタンスは更新のために一時的にオフラインになります。
    • Blue/green
      デプロイメントグループ内のインスタンスを新しいインスタンスに置き換え、最新のリビジョンを新しいインスタンスにデプロイします。置き換え環境のインスタンスがロード バランサーに登録された後、元の環境のインスタンスは登録解除されるため、デプロイ時の一時停止が発生しません。

4-6. [Environment configuration]設定

アプリケーションのデプロイ先を定義します。
今回は、事前に作成したデプロイ先EC2(Nameタグ=codedeploy-test-20250328)を指定します。

4-7. [Agent configuration with AWS Systems Manager]設定

AWS Systems Managerによる、CodeDeployエージェントのインストールと更新を設定します。今回は特に不要なのでNeverにしました。

4-8. [Deployment settings]設定

複数のデプロイ先(例:Auto Scalingを設定したAmazon EC2等)に対して、一度にどれだけ同時にデプロイを実行するか定義します。今回は、デプロイ先のEC2が1つしかないため、AllAtOnceにします。

他にも、デフォルトで以下の通り選択でき、自身でconfigurationを作成することも可能です。

4-9. [Load balancer]設定

デプロイ中に受信トラフィックを管理するロードバランサーを設定します。
ロードバランサーは、デプロイ中に各インスタンスからのトラフィックをブロックし、デプロイが成功した後に再度トラフィックを許可します。
今回は、ロードバランサーを要さないのでチェックを外します。

4-10. [Create deployment group]を押下

これで、deployment groupの作成が完了しました。

5. CodePipelineでパイプラインを作成

CodePipelineでCodeCommitのリポジトリ、CodeBuildのビルドプロジェクト、CodeDeployのアプリケーションを繋ぎ、パイプラインを作成します。

5-1. [Create pipeline]を押下

5-2. [Category]設定

Categoryとして、下図の4種から選ぶことができ、ユースケースごとにテンプレートが用意されています。今回はテンプレートを使わずにカスタムのパイプラインを作成したいため、[Build custom pipeline]を選択して[Next]を押下します。

(例1)Deployment

(例2)Continuous Integration

(例3)Automation

5-3. [Pipeline settings]設定

アプリケーションの基本設定をしていきます。
[Pipeline name]を入力し、他はデフォルトのままで[Next]を押下します。

  • Execution mode
    パイプラインの実行方法を設定する項目です。
    • Superseded
      新しい処理が古い処理を追い越すことができます。
    • Queued(デフォルト)
      処理はキューに入れられ、順に1つずつ処理されます。
    • Parallel
      複数の処理が並行して実行されます。

5-4. [Source]設定

パイプラインのインプットとなるソースを定義します。
事前に作成したCodeCommitリポジトリのmasterブランチを指定し、[Next]を押下します。

5-5. [Build]設定

パイプラインのビルドフェーズを定義します。
Build providerとしてCodeBuildを設定し、事前に作成したビルドプロジェクトを指定します。他はデフォルトのままで[Next]を押下します。

5-5. [Build]設定

パイプラインのビルドフェーズを定義します。
Build providerとしてCodeBuildを設定し、事前に作成したビルドプロジェクトを指定します。他はデフォルトのままで[Next]を押下します。

5-6. [Test]設定

今回テストはパイプライン内で実行しないため、[Skip test stage]を押下します。

5-7. [Deploy]設定

パイプラインのデプロイフェーズを定義します。
Deploy providerとしてCodeDeployを設定し、事前に作成したアプリケーションとDeployment groupを指定します。他はデフォルトのままで[Next]を押下します。

5-6. [Create pipeline]を押下

Review画面で設定内容を確認し、 [Create pipeline]を押下します。

これで、CodeCommitのリポジトリ、CodeBuildのビルドプロジェクト、CodeDeployのアプリケーションをつないだパイプラインの作成が完了しました。

以上が、CI/CDパイプラインの作成方法と、設定項目の解説でした。

Codeサービス群の「Source」を検証してみる

次に、CI/CDパイプラインを作成する中で1つの疑問が発生したので、その疑問について検証してみます。

前提

Codeサービス群の「Source」とは

既出ではありますが、Codeサービス群に含まれるCodeBuildとCodePipelineでは、ビルドやパイプライン実行のインプットとなるソースコード群を「Source」と呼び、それぞれAmazon S3やCodeCommit、GitHub、GitLabのブランチ等を指定します。

CodeBuildでビルドを実行する際に作成する「ビルドプロジェクト」と、CodePipelineでパイプラインを実行する際に作成する「パイプライン」は、基本的に独立した別のリソースとなりますが、パイプライン作成画面内のウィザードで、同時にビルドプロジェクトを作成することも可能です。
その場合、ビルドプロジェクトのSourceとしてCodePipelineを指定することができ、CodePipelineのSourceで指定したソースコードを元に、ビルドを含めたパイプラインが実行されます。
https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodeBuild.html

一方で、ビルドプロジェクトを個別で作成し、後でパイプラインと紐づけた場合、ビルドプロジェクトの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 アクションで使用される入力アーティファクトになります。

https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodeBuild.html#action-reference-CodeBuild-input

Source設定の優先度についての記述とも取れますが、読み方次第では

  • ビルドプロジェクトで設定されたアーティファクト(Source)が、パイプラインの入力アーティファクトとして利用される
  • ビルドプロジェクトで設定されたアーティファクト(Source)が、パイプラインの入力アーティファクトに上書きされる

のどちらにも受け取れるように感じ、「環境で試した方が早い!」ということで実際にリソースを作成して試してみることにしました。

準備

まず、今回の検証に利用するリソースの作成を行いました。作成のステップは以下の通りです。

  • ステップ1. CodeCommitでリポジトリを作成し、検証用ソースコードを格納する
  • ステップ2. CodeBuildでビルドプロジェクトを作成する
  • ステップ3. CodeDeployでアプリケーションを作成する
  • ステップ4. CodePipelineでパイプラインを作成する

ステップ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が優先されることが分かりました。

さいごに

今回は、Codeサービス群を利用したパイプラインの作成方法、及び各設定項目の解説をするとともに、ビルドプロジェクトとパイプラインのSourceに異なるソースコードを指定した場合にどちらの設定が優先されるのか、また、デプロイステージのInput ArtifactsにSourceArtifactとBuidArtifactの両方を選択した場合にどちらが優先されるか、この2点の検証結果をご紹介しました。

本記事が、CodePipelineにおけるパイプライン作成の際の一助になれば幸いです。


Accenture Japan - ICE (有志) により固定
 Cloudのキャリア・採用情報 | アクセンチュア
 女性が活躍する職場|採用情報 | アクセンチュア

Accenture Japan (有志)

Discussion