AWS CodeBuild を安全・高速・低コストに運用するための実践的なガイドラインをまとめたものです。


目次

  1. buildspec の設計
  2. セキュリティ
  3. パフォーマンス(ビルド高速化)
  4. コンピューティングの選択とコスト最適化
  5. ビルド環境(イメージ)の管理
  6. テストとレポート
  7. 監視・ログ・通知
  8. 信頼性とデバッグ
  9. ガバナンスと IaC
  10. チェックリスト

1. buildspec の設計

基本方針

  • buildspec.yml はリポジトリで管理する。コードと同じくレビュー・履歴管理の対象にする。
  • フェーズの役割を明確に分ける。
フェーズ役割
installランタイム指定、依存ツールのインストール
pre_build認証(ECR ログインなど)、依存パッケージ取得、静的解析
buildコンパイル、テスト、イメージビルド
post_build成果物のプッシュ、メタデータ出力
  • runtime-versions でランタイムを明示し、暗黙のデフォルトに依存しない。
  • on-failure: ABORT を指定して、失敗時に後続フェーズを無駄に実行しない。
  • 長いシェル処理は buildspec に直書きせず、scripts/ 配下のスクリプトに切り出してローカルでも実行可能にする。

推奨テンプレート

version: 0.2
 
env:
  shell: bash
  variables:
    APP_NAME: my-app
  parameter-store:
    DB_HOST: /my-app/prod/db-host
  secrets-manager:
    API_TOKEN: my-app/prod:api_token
  exported-variables:
    - IMAGE_TAG
 
phases:
  install:
    runtime-versions:
      nodejs: 20
    on-failure: ABORT
    commands:
      - npm ci
  pre_build:
    on-failure: ABORT
    commands:
      - export IMAGE_TAG=${CODEBUILD_RESOLVED_SOURCE_VERSION:0:7}
      - aws ecr get-login-password | docker login --username AWS --password-stdin "$ECR_REGISTRY"
  build:
    on-failure: ABORT
    commands:
      - npm run lint
      - npm test
      - docker build -t "$ECR_REGISTRY/$APP_NAME:$IMAGE_TAG" .
  post_build:
    commands:
      - |
        if [ "$CODEBUILD_BUILD_SUCCEEDING" = "1" ]; then
          docker push "$ECR_REGISTRY/$APP_NAME:$IMAGE_TAG"
        fi
 
reports:
  unit-tests:
    files: ["reports/junit.xml"]
    file-format: JUNITXML
  coverage:
    files: ["coverage/cobertura-coverage.xml"]
    file-format: COBERTURAXML
 
artifacts:
  files:
    - imagedefinitions.json
  discard-paths: yes
 
cache:
  paths:
    - "/root/.npm/**/*"

ポイント

  • post_build はビルド失敗時にも実行されるため、CODEBUILD_BUILD_SUCCEEDING で成否を判定してからデプロイ系処理を行う。
  • exported-variables を使うと CodePipeline の後続アクションへ値を渡せる。
  • イメージタグには latest ではなくコミットハッシュ(CODEBUILD_RESOLVED_SOURCE_VERSION)を使い、トレーサビリティを確保する。

2. セキュリティ

IAM(サービスロール)

  • プロジェクトごとに専用のサービスロールを作成し、最小権限にする。*FullAccess 系のマネージドポリシーは使わない。
  • リソース ARN を限定する(特定の S3 バケット、特定の ECR リポジトリ、特定のロググループなど)。
  • 他アカウントへのデプロイは、ロール引き受け(sts:AssumeRole)で行い、権限をデプロイ先側で制御する。
  • CodeBuild の条件キー(codebuild:*)を使った IAM ポリシーで、特権モードや VPC 設定などプロジェクト作成時の設定を組織として制限できる。

シークレット管理

  • 認証情報を 環境変数(plaintext)や buildspec に直書きしない。
  • env.secrets-manager / env.parameter-store(SecureString)を使って実行時に取得する。
  • ソースプロバイダ(GitHub 等)への接続は、個人アクセストークンより AWS CodeConnections(旧 CodeStar Connections) を優先する。トークンが必要な場合は Secrets Manager に格納する。
  • ログにシークレットが出力されないよう、set -x や env の全出力を避ける。

特権モード(Privileged mode)

  • Docker デーモンが必要な場合にのみ有効化する。特権モードのコンテナはホストに近い権限を持つため、信頼できないコードを実行するプロジェクトでは無効にする。
  • Docker イメージのビルドが主目的なら、後述の Docker サーバーモード の利用も検討する。

Webhook とプルリクエスト

  • フォークからのプルリクエストで任意のコードが実行されるリスクに注意する。
    • Webhook フィルタで イベント種別・ブランチ・アクター(ACTOR_ACCOUNT_ID) を制限する。
    • PR ビルド用プロジェクトには本番環境へのアクセス権限やシークレットを持たせない。
  • 本番デプロイ用プロジェクトは、保護ブランチへのマージ(push)のみをトリガーにする。

ネットワーク

  • プライベートリソース(RDS、内部 API など)にアクセスする場合は VPC 内で実行する。
  • VPC 内で実行する場合は、プライベートサブネット + NAT Gateway、または VPC エンドポイント(S3、ECR、Secrets Manager、CloudWatch Logs など)を用意する。
  • セキュリティグループのアウトバウンドも必要最小限にする。

暗号化

  • アーティファクト・キャッシュ・ログを KMS(カスタマーマネージドキー)で暗号化する。
  • 成果物を置く S3 バケットはパブリックアクセスをブロックし、バケットポリシーで TLS 必須にする。

承認・監査

  • AWS Config の CodeBuild 向けセキュリティベストプラクティス適合パック(plaintext 認証情報の検出、ログ設定の確認など)を有効化する。
  • CloudTrail でプロジェクト設定の変更・ビルド開始を監査する。
  • セキュリティスキャン(SCA、SAST、コンテナイメージスキャン)は、開発者が編集する buildspec とは 別の CodeBuild アクション として、プラットフォーム/セキュリティチームが管理する形にすると統制しやすい。

3. パフォーマンス(ビルド高速化)

キャッシュ

種類特徴向いているケース
S3 キャッシュビルドホストをまたいで共有可能依存パッケージ(npm、Maven、pip など)
ローカルキャッシュ(Source / Docker layer / Custom)同一ホスト上でのみ有効、高速高頻度ビルド、Docker レイヤー再利用
  • 依存パッケージのキャッシュディレクトリを cache.paths に指定する。
  • ロックファイル(package-lock.json など)のハッシュをキャッシュキーに使い、無効化を制御する。
  • キャッシュが巨大化すると転送時間が逆に増えるため、不要なファイルは含めない。

Docker ビルドの高速化

  • Docker サーバーモード:永続ストレージを持つ専用 Docker サーバーをプロジェクトに用意でき、レイヤーキャッシュが効きやすくなる。
  • Dockerfile はキャッシュが効く順序(変更頻度の低いレイヤーを先)で書く。
  • マルチステージビルドで最終イメージを小さくする。
  • ベースイメージは ECR(または ECR のプルスルーキャッシュ)から取得し、Docker Hub のレート制限を回避する。

並列化

  • バッチビルド(build list / build matrix / build graph)で、マルチプラットフォームビルドや依存関係のあるビルドを並列実行する。
  • テスト分割と並列実行:codebuild-tests-run を使ってテストを複数環境に分散し、レポートをマージする。
  • 独立したジョブは別プロジェクトに分け、CodePipeline 上で並列アクションにする。

その他

  • git-clone-depth を浅くして(例: 1)クローン時間を短縮する(タグやフル履歴が必要なツールでは注意)。
  • 不要なサブモジュールの取得を無効化する。
  • 大きなバイナリは S3 などから必要時に取得する。

4. コンピューティングの選択とコスト最適化

コンピューティングモードの使い分け

モード特徴向いているケース
オンデマンド(EC2)使った分だけ課金、柔軟一般的なビルド
Lambda コンピューティング起動が高速、秒単位課金軽量・短時間のビルド(Docker 不要なもの)
リザーブドキャパシティ(フリート)常時待機でキュー待ちなし、インスタンスタイプ・ストレージを指定可能高頻度ビルド、起動待ちを避けたい場合、特殊なインスタンスが必要な場合

コスト削減のポイント

  • コンピューティングタイプを 実測に基づいて選ぶ。大きすぎるインスタンスは無駄、小さすぎるとビルド時間増で逆に高くつく。
  • ARM(Graviton)イメージが使えるワークロードは ARM を検討する。
  • timeoutInMinutes と queuedTimeoutInMinutes を適切に設定し、ハングしたビルドで課金が続かないようにする。
  • Webhook フィルタやファイルパスフィルタで 不要なビルドを起動しない(ドキュメントのみの変更など)。
  • 古いアーティファクト・キャッシュは S3 ライフサイクルルールで削除する。
  • CloudWatch Logs の保持期間を設定する(デフォルトは無期限)。

5. ビルド環境(イメージ)の管理

  • AWS 管理の標準イメージ(aws/codebuild/standard:x.0、amazonlinux 系)を基本とし、サポートされているバージョンを使う。
  • 必要なツールが多い場合は カスタムイメージを ECR に用意し、install フェーズの時間を短縮する。
    • カスタムイメージは定期的に再ビルドし、脆弱性スキャン(ECR の拡張スキャン / Amazon Inspector)を実施する。
    • イメージは digest またはバージョンタグで固定し、再現性を確保する。
  • イメージのプルには serviceRole 認証情報を使う設定(imagePullCredentialsType: SERVICE_ROLE)にする。

6. テストとレポート

  • reports セクションでテスト結果(JUnit XML、Cucumber JSON、TestNG など)とカバレッジ(Cobertura、JaCoCo、Clover など)を出力し、コンソール上で推移を可視化する。
  • テスト失敗時はビルドを失敗させる(終了コードを握りつぶさない)。
  • 単体テストは早い段階、時間のかかる E2E テストは別プロジェクトや並列実行に分ける。
  • 静的解析・リンタ・セキュリティスキャンも CI の必須ステップとして組み込む。

7. 監視・ログ・通知

  • CloudWatch Logs と S3 へのログ出力を設定し、ロググループの保持期間を決める。
  • ビルドの成功率・所要時間・キュー待ち時間を CloudWatch メトリクスで監視し、劣化に気づけるようにする。
  • EventBridge / AWS CodeStar Notifications でビルド失敗を Slack や Amazon SNS に通知する。
  • 失敗が続くプロジェクトやビルド時間の急増には CloudWatch アラームを設定する。

8. 信頼性とデバッグ

  • 自動リトライ(Webhook ビルドの auto-retry)を設定し、一時的な失敗(ネットワークエラーなど)による手動再実行を減らす。ただし、本質的な失敗をリトライで隠さないよう回数は少なめに。
  • 外部依存(パッケージレジストリなど)は可能な限り CodeArtifact やミラーを経由させ、外部障害の影響を抑える。
  • ビルドの冪等性を保つ(何度実行しても同じ結果になるようにする)。
  • デバッグ時は以下を活用する。
    • CodeBuild サンドボックス:ビルド環境を再現した状態で対話的にデバッグ。
    • Session Manager 接続:buildspec に codebuild-breakpoint を入れて実行中のビルドに接続。
    • ローカルエージェント(CodeBuild local):ローカルで buildspec を検証。

9. ガバナンスと IaC

  • CodeBuild プロジェクトは CloudFormation / CDK / Terraform で管理し、コンソールでの手作業変更を避ける。
  • プロジェクト命名規則とタグ(Project、Environment、Owner、CostCenter)を統一し、コスト配分に活用する。
  • 共通処理(ECR ログイン、通知、スキャンなど)は共有スクリプトやカスタムイメージ、CDK コンストラクトとして再利用する。
  • 開発者が自由に編集できる部分(buildspec in repo)と、プラットフォームチームが統制する部分(インライン buildspec のセキュリティアクション、IAM、VPC 設定)を分離する。
  • GitHub Actions を使っている場合は、CodeBuild をセルフホストランナーとして使う構成も選択肢になる(ワークフローは GitHub Actions、実行環境は AWS 内)。

10. チェックリスト

セキュリティ

  • サービスロールはプロジェクト専用かつ最小権限
  • シークレットは Secrets Manager / Parameter Store から取得している
  • plaintext の認証情報が環境変数にない
  • 特権モードは必要なプロジェクトのみ有効
  • Webhook フィルタでフォーク PR やアクターを制限している
  • アーティファクト・ログ・キャッシュが KMS で暗号化されている
  • AWS Config / CloudTrail で設定変更を監査している

パフォーマンス・コスト

  • 依存パッケージのキャッシュを設定している
  • Docker ビルドでレイヤーキャッシュが効いている
  • コンピューティングタイプを実測に基づき選定している
  • タイムアウトとキュータイムアウトを設定している
  • 不要なビルドをフィルタで抑止している
  • ログ保持期間・S3 ライフサイクルを設定している

運用

  • buildspec はリポジトリでバージョン管理されている
  • テストレポート・カバレッジを出力している
  • 失敗時の通知が設定されている
  • プロジェクトは IaC で管理されている
  • イメージタグにコミットハッシュを使用している

参考リンク

0件のページ