AWS CodeBuildによるビルドとテストの自動化
AWS CodeBuildのビルド環境、buildspec.ymlの4フェーズ、環境変数、成果物とテストレポート、料金、Jenkinsとの違いを学びます。
AWS CodeBuildによるビルドとテストの自動化
アプリケーションを開発した後、ソースコードを実行可能なパッケージへ変換し、テストし、デプロイ可能な成果物として用意する必要があります。この一連の作業がビルドです。プログラムのコンパイルやパッケージングだけでなく、依存ライブラリの取得、単体テスト、レポート生成などもビルド工程に含められます。
AWS CodeBuildは、ソースコードをビルドし、テストを実行して、配布やデプロイに使う成果物を作成するフルマネージドサービスです。ビルドを実行するサーバーを利用者が常時用意して管理するのではなく、プロジェクトに設定した環境と手順に基づいてビルドを実行します。CodePipelineに接続してパイプラインの一工程として使うことも、単独で実行することもできます。
ビルドプロジェクトを構成する要素
CodeBuildのビルドプロジェクトでは、主に次の要素を定義します。
- ソース:ビルド対象のリポジトリや、CodePipelineから受け取る入力。
- ビルド環境:OS、ランタイム、ツールを含むコンテナイメージと、ビルドに割り当てる計算資源。AWS提供のイメージのほか、要件に合わせたカスタムイメージも選べます。
- ビルド仕様:どのコマンドをどの順番で実行し、何を成果物やテストレポートとして扱うかを記述する設定。
- サービスロール:ビルド中にCodeBuildがAWSリソースへアクセスするためのIAMロール。
- 出力先:成果物やテストレポートの保存先。成果物はAmazon S3バケットに保存したり、CodePipelineの後続アクションに渡したりできます。
これらを使って、ビルドのたびに同じ実行手順を適用できます。再現性を高めるには、使うランタイムや依存関係のバージョンを明示し、変化する外部要素も管理することが重要です。CodeBuildを使うだけで依存パッケージや外部イメージが自動的に固定されるわけではありません。
buildspec.ymlと4つのフェーズ
ビルド手順は通常、ソースリポジトリのbuildspec.ymlにYAML形式で記述します。CodeBuildはファイルのphasesにある各フェーズを、install、pre_build、build、post_buildの順で実行します。フェーズ名は定義済みであり、独自の名前には変更できません。
| フェーズ | 役割 | 実行内容の例 |
|---|---|---|
install |
ビルドに必要な言語ランタイムやツール、依存関係を準備する | コンパイラやテストライブラリを利用可能にする |
pre_build |
ビルド本体の前に必要な認証や設定を行う | コンテナレジストリへの認証、イメージ名やタグの決定 |
build |
ソースを実際にビルドし、テストする | コンパイル、パッケージ作成、単体テスト、コンテナイメージ作成 |
post_build |
ビルド完了後の処理を行う | 成果物の公開、後続処理用ファイルの作成、完了通知 |
フェーズの中では、commandsに実行したいコマンドを並べます。たとえばコンテナイメージを作ってAmazon ECRへ登録する場合、pre_buildで対象レジストリへの認証とリポジトリ名・タグの設定を行い、buildでイメージの作成と必要なテストを実行し、post_buildで検証済みイメージをECRへプッシュできます。
別の例として、図書館の蔵書検索APIをコンテナ化するビルドでは、installでGoのツールチェーンやテスト依存関係を準備し、pre_buildでECRへの認証とコミット識別子に基づくタグを決めます。buildでAPIのコンパイル、単体テスト、コンテナイメージ作成を行い、成功したイメージだけをpost_buildでECRへ登録します。アプリケーションのパッケージやテスト結果ファイルは、それぞれの形式に応じて別途出力対象に指定します。
buildspec.ymlにはフェーズ以外に、環境変数、成果物、テストレポート、キャッシュなども定義できます。CodeBuildプロジェクト側の設定でビルド仕様を与える方法もあり、リポジトリごとにバージョン管理したい場合はソースにファイルを含める方法が適しています。YAMLではインデントが構造を表すため、ずれがあると意図しない設定になったり、ビルド開始時に解析エラーになったりします。
環境変数で共通設定を渡す
環境変数を使うと、複数フェーズから参照する値を一か所で定義できます。たとえば、ECRのリポジトリ名、ビルド対象の環境名、成果物のバージョンなどを変数として設定すれば、コマンドに同じ値を何度も直接書かずに済みます。また、環境ごとに値を切り替えたり、コードを変更せずにプロジェクト設定から値を与えたりできます。
ただし、CodeBuildプロジェクトやビルド仕様に平文で設定した環境変数は、コンソールやAPIなどから参照可能な場合があります。パスワード、アクセストークン、秘密鍵などの機密値を通常の平文変数に含めないでください。AWS Systems Manager Parameter StoreまたはAWS Secrets Managerに値を保存し、ビルド時に環境変数として取得する方式を使います。その場合、CodeBuildのサービスロールには対象パラメータやシークレットを読む権限が必要です。
ログ上でシークレットがマスキングされる場合でも、加工した値は元のシークレット文字列と一致せず、ログに現れる可能性があります。機密値をエンコード・連結した内容をコマンド出力へ書かないようにし、ビルドコマンドが認証情報を不用意に表示しないことも確認します。
成果物とテストレポート
artifacts:次の工程へ渡すファイル
artifactsでは、ビルド環境内で作成されたファイルのうち、CodeBuildの出力として保存または引き渡す対象を指定します。アプリケーションのパッケージ、デプロイ用マニフェスト、ビルド後の設定ファイルなどが該当します。成果物として含めるファイルのパスやディレクトリを指定し、プロジェクトの設定に応じてS3やCodePipelineのアーティファクトとして扱います。
たとえば、テストを通過したAPIのデプロイパッケージをS3に保存し、CodePipelineの後続デプロイアクションへ渡せます。後続工程にはビルド後の成果物を入力として指定するため、テストに使ったものと同じ成果物を環境へ昇格させやすくなります。パスの指定が誤っていると成果物が出力されないため、ビルド環境内で生成されたファイルの場所と、artifactsに指定したパスを一致させます。
reports:テスト結果の記録
テストレポートは、ビルド成果物とは別の機能です。テストフレームワークが生成するJUnit XMLやCucumber JSONなどの結果ファイルをCodeBuildのレポートグループに登録し、ビルドごとの成功・失敗やテスト傾向を確認できます。テスト自体の実行コマンドはbuildなどのフェーズで指定し、reports設定では生成された結果ファイルの場所や形式を指定します。
CodeBuildのテストレポートは作成から30日で期限切れになります。より長期間保管したい場合は、レポートグループの設定を使って生のテスト結果ファイルをS3へエクスポートします。S3へ保存したファイルはレポート画面の保持期限とは別に扱われるため、必要な保存期間に応じてS3側のライフサイクルも設計します。
テストコマンドが失敗ステータスを返せば、そのビルドは失敗となり、CodePipelineの後続アクションも通常は成功した工程として進みません。一方、テスト結果ファイルの登録はテストコマンドの成否とは別の処理です。コマンドの終了コードを正しく扱うことと、結果ファイルの形式・場所を正しく設定することの両方が必要です。
コンテナイメージをECRへ登録する
CodeBuildでDockerイメージを作り、Amazon ECRへプッシュするときは、ビルド環境でDockerコマンドを実行できる状態にし、対象リポジトリへの認証を行います。CodeBuildのサービスロールには、認証トークンの取得やイメージレイヤーのアップロードなど、ECRへプッシュするための権限が必要です。
処理の流れは、認証、リポジトリとタグの決定、イメージのビルド、必要なテスト、ECRへの登録です。タグにはlatestだけを使うのではなく、コミットIDやリリース番号など、ビルド元を識別できる値を使うと、どのソースから作られたイメージかを追跡しやすくなります。ECRへのプッシュをpost_buildで行えば、通常は先行するbuildが成功した後に公開処理を進められます。
CodeBuildのビルド環境は、プロジェクトで選択したOS、CPUアーキテクチャ、ランタイム、計算資源に応じて用意されます。通常の非VPCビルドではDockerデーモンが既定で有効ですが、VPC内でDockerコンテナを使うビルドでは特権モードを有効にする必要があります。Windows環境では特権モードを利用できません。ネットワーク構成や環境の種類によって利用できる機能が異なるため、プロジェクトの要件に合うビルド環境を選択します。
CodeBuildとJenkinsの違い
Jenkinsは、ビルド、テストなどのCI工程を自動化するオープンソースのツールです。AWS CodeBuildがビルド実行基盤の管理をAWSへ任せられるマネージドサービスであるのに対し、JenkinsをAWS上で動かす場合は、EC2などの実行環境を利用者が用意して運用します。
| 比較項目 | AWS CodeBuild | Jenkins |
|---|---|---|
| 運用する実行基盤 | AWSがビルド環境を提供し、利用者はプロジェクトやビルド手順を設定する | 利用者がJenkinsサーバーや必要なエージェントの用意・更新・運用を行う |
| ビルド手順の拡張 | buildspec、カスタムイメージ、AWSサービスとの連携を使う | 多数のプラグインやエージェントを組み合わせて構成できる |
| 計算資源の準備 | オンデマンド環境はビルドの実行に応じて利用できる。予約済み環境も選べる | 利用者がサーバーやエージェントの容量、可用性、拡張方法を設計する |
| 適する状況 | ビルド基盤の管理を減らし、AWSのビルド・保管・パイプライン機能を組み合わせたい | 既存のJenkins資産、特定のプラグイン、独自のエージェント構成や接続要件を活用したい |
AWS内のリポジトリやデプロイ先を中心に、基盤の保守を抑えてビルドしたい場合はCodeBuildが候補です。多様なプラグインを使う必要がある場合や、既存のJenkinsを含む複数ベンダー・オンプレミス環境で共通のビルド手順を運用したい場合はJenkinsが適することがあります。ただし、Jenkinsでも外部サービスと連携するにはネットワークや認証を構成する必要があり、CodeBuildもカスタムイメージなどで柔軟なビルドを行えます。要件と既存運用を比べて選択します。
料金と計算資源の選び方
CodeBuildの料金は、ビルド環境の種類や選択した計算資源、ビルド時間などに応じて変わります。CPUやメモリの異なるコンピュートタイプがあり、必要な性能を満たすサイズを選びます。オンデマンドのEC2ビルドでは、ビルドの開始から終了までの実行時間をもとに課金され、時間は分単位に切り上げて計算されます。OSやアーキテクチャ、リージョンによって単価も異なるため、最新の料金表で条件を確認します。
CodeBuildには、オンデマンドのほかに予約済みキャパシティのビルド環境もあります。予約済みキャパシティでは、専用の計算資源をあらかじめ確保して待機させるため、ビルド開始時の待ち時間を短縮しやすい反面、ビルドが実行されていない時間も確保した環境の料金が発生します。ビルド頻度、起動待ち時間の要件、計算資源の利用率を踏まえて選びます。
ビルド時間が長くなるほど、実行料金も増えます。不要な依存関係のインストール、ビルドに不要なテストや処理、大きすぎる成果物の転送を減らすことは、実行時間とコストの両方の改善につながります。固定額を記憶するのではなく、実行するリージョン、OS、アーキテクチャ、コンピュートタイプ、課金方式に対応した最新価格を確認してください。
学習ポイント
- CodeBuildはビルドとテストを行うマネージドサービスであり、ビルド環境を実行するサーバーの通常運用を利用者から軽減します。
buildspec.ymlはビルド手順を定義するYAMLファイルです。install、pre_build、build、post_buildの4フェーズは決められた順序で実行されます。- 依存関係やツールの準備は
install、認証などの事前処理はpre_build、コンパイル・テスト・イメージ作成はbuild、公開などの後処理はpost_buildに配置します。 - 共有設定には環境変数を使えますが、パスワードやトークンを平文変数に入れず、Parameter StoreまたはSecrets Managerから読み込みます。
artifactsは後続デプロイなどに利用する成果物、reportsはテスト結果の記録です。レポートは標準で30日後に期限切れとなり、長期保管にはS3へのエクスポートを検討します。- ECRへイメージをプッシュするには、ビルド環境でイメージを作れることに加え、CodeBuildのサービスロールに必要なECR権限を与えます。
- Dockerを使うビルドでは環境設定も確認します。VPC内のDockerビルドには特権モードが必要で、Windows環境では特権モードを使えません。
- オンデマンドの料金は選んだビルド環境と実行時間で変わります。予約済みキャパシティは専用計算資源を確保するため、アイドル時間にも料金がかかります。
- Jenkinsは拡張性と構成自由度が高い一方、サーバーやエージェントの運用が必要です。CodeBuildはマネージドなビルド実行を提供し、AWS連携と運用負荷の軽減に向きます。
公式ドキュメント
重要ポイント
- ▸CodeBuildはビルド環境のサーバー管理をAWSに任せ、ソースコードのコンパイル、テスト、成果物作成を実行するフルマネージドサービス
- ▸buildspec.ymlのinstall、pre_build、build、post_buildは決められた順で実行され、それぞれ依存関係の準備、事前処理、ビルドとテスト、後処理を担う
- ▸環境変数はフェーズ間で共有する設定値に使い、認証情報などの機密値は平文で定義せずParameter StoreまたはSecrets Managerから取得する
- ▸artifactsは後続工程に渡すビルド成果物、reportsはテスト結果の記録であり、用途と保持の扱いが異なる
- ▸料金はビルド環境の計算資源と実行時間に応じて変わり、予約済みキャパシティではビルドがない時間も確保した計算資源に料金がかかる
- ▸Jenkinsはプラグインや実行ノードを細かく構成できる一方、基盤の準備・更新・運用を利用者が担う。CodeBuildはビルド基盤の管理を軽減する
このトピックの学習を完了しますか?
完了状態はいつでも切り替えられます
この試験ドメイン内で次の学習に進む
同じサービスの関連トピック
IaC / 環境自動化 / コンテナ に関連するトピックを続けて確認できます。