CodeArtifact×CodeGuru実践|パッケージ管理とコードレビュー自動化

目次

1. この記事について

fig01: aws-code-family シリーズ完結 全体像

aws-code-family シリーズ完結ナビゲーション (全4巻)

【QG-1】aws-code-family シリーズ完結アーキテクチャ (Vol1-4 統合・各レイヤーと責任分界)

aws-code-family 全4巻が担う補完レイヤーと責任分界を以下に整理する。

  • Vol1 (サービス選定レイヤー): AWS Code* / GHA / ecspresso の選定基準を確立。ゼロからパイプライン設計を始める際の「どれを使うか」判断軸。GHA/ecspresso との共存パターンもここで決定。
  • Vol2 (ビルドレイヤー): CodeBuild がソースコードをコンパイル・テスト・コンテナイメージ化。VPC プライベートビルド・ARM64/AMD64 マルチアーキテクチャ・キャッシュ最適化まで実装。
  • Vol3 (デプロイレイヤー): CodePipeline V2 がフルパイプラインのオーケストレーション。CodeDeploy が Blue/Green・Canary の安全なデプロイと本番ロールバック自動化を担う。
  • Vol4 (品質・パッケージ補完レイヤー / 本記事): CodeArtifact が社内パッケージの中央レジストリとして upstream proxy・脆弱性遮断を担当。CodeGuru Reviewer が PR 自動静的解析、Profiler が本番フレームグラフ解析で継続的品質改善を実現。
  • 外部 AI 統合軸: Bedrock Agents は §7 で比較詳述。「定型ルール適用 → CodeGuru Reviewer」「カスタム AI ロジック → Bedrock Agents」の選定フローで共存できる。

この4層により「設計 → ビルド → デプロイ → 品質保証・パッケージ管理」というエンタープライズ CI/CD の全ライフサイクルが Terraform 一本で完結する。

1-1. 本記事のゴール

本記事は aws-code-family シリーズ完結弾として、Vol1-3 で構築した CI/CD パイプラインに欠けていた 2 つの補完運用を追加する。

第一に CodeArtifact による社内パッケージレジストリの構築だ。npm/pip/maven/nuget のパッケージを組織内で一元管理し、upstream proxy 経由で外部レジストリを安全にキャッシュする実装を Terraform + AWS CLI + コンソールの 3 形式で完走する。upstream 設定・IAM Token 12時間期限への対処・CodeBuild 自動認証統合まで踏み込んだ実務レベルの実装を示す。

第二に CodeGuru Reviewer/Profiler による継続的な品質改善だ。Reviewer は PR ごとに CWE/OWASP ベースの静的解析を自動実行し、Profiler は本番 Lambda/ECS のフレームグラフで CPU ホットスポットを可視化する。2サービスの棲み分けと料金設計まで解説する。

さらに Bedrock Agents との使い分け軸を §7 で提示し、「定型ルール適用は CodeGuru / カスタム AI ロジックは Bedrock」という選定指針を確立する。Action Group 統合パターンと CodeGuru の CWE ルール体系の比較で、現場の選択判断を明確にする。

本記事を読み終えたとき、読者は Vol1-4 チートシートを片手に、設計 → ビルド → デプロイ → 品質保証 → パッケージ管理という本番運用パイプラインを Terraform で完全実装できる状態になっている。各章で Terraform HCL / AWS CLI / コンソール 3形式の実装例を提供するため、既存環境への段階的な組み込みにも対応できる。

本記事で扱う主要 Terraform リソースは以下の通りだ。

  • aws_codeartifact_domain / aws_codeartifact_repository / aws_codeartifact_repository_permissions_policy
  • aws_codegurureviewer_repository_association
  • aws_codeguruprofiler_profiling_group
  • IAM 関連: aws_iam_role / aws_iam_role_policy_attachment (CodeArtifact / CodeGuru 両対応)

シリーズ全4巻のコードは一貫した変数設計 (var.project / var.environment / var.region) を共有しているため、Vol2-3 の Terraform モジュールとそのまま組み合わせて使用できる。

1-2. 読者像

想定読者: aws-code-family Vol1-3 を読了し、CodeBuild・CodePipeline・CodeDeploy の基本実装を習得済みのエンジニア。加えて、「チーム内でパッケージを共有管理したい」「PR のコードレビューを自動化したい」「本番 API の遅延原因をボトルネック分析したい」という課題を抱える中級レベル以上の実務者を対象とする。

必須前提知識チェックリスト: 以下の項目を確認してから読み進めてほしい。

  • Terraform の基本構文 (resource / variable / output / data) が読み書きできる
  • IAM Role の信頼関係設計と sts:AssumeRole の仕組みを理解している
  • CodeBuild の buildspec.yml 記述経験がある (Vol2 修了レベル)
  • GitHub または CodeCommit でのブランチ運用・PR フロー経験がある
  • aws CLI の基本コマンドが使える (プロファイル切り替え・--query オプション等)

上記チェックリストの大半が未確認であれば、Vol1-3 から順に読むことを推奨する。

本記事で身につくこと:

  • CodeArtifact の Domain/Repository/Package 3層設計と upstream proxy 構成
  • IAM Token 認証 (12時間期限) の自動更新と CodeBuild 統合パターン
  • CodeGuru Reviewer の PR 自動統合とコスト試算 (月あたり PR数による料金計算)
  • CodeGuru Profiler のエージェント組み込みとフレームグラフの読み方
  • Terraform でこれら全サービスの完全 IaC 実装
  • Bedrock Agents との棲み分け判断軸 (定型 vs カスタム AI ロジック)
  • Vol1-4 全体を俯瞰したチートシートと落とし穴10選

1-3. なぜ今これを書くか

AWS CodeArtifact は 2019年にリリースされ、GitHub Packages や JFrog Artifactory の AWS ネイティブ代替として普及しつつあるが、日本語技術記事では「公式ドキュメントの紹介レベル」にとどまるものが多く、upstream proxy 設定・IAM Token 12時間期限への実務対処・CodeBuild との統合パターンまで踏み込んだ記事は稀少だ。CodeGuru も同様で、Reviewer と Profiler の棲み分けを解説した国内記事はほとんど存在しない。

さらに 2023年以降、Bedrock の普及により「AI でコードレビューしたい」という要件が急増し、「CodeGuru Reviewer か Bedrock Agents か」という選定判断が現場で求められている。本記事はこの比較軸を §7 で正面から扱い、実務判断に直結する選定フローを提供する。

aws-code-family シリーズとして、本記事は Vol1-3 で構築したパイプラインの「最後のピース」を担う。シリーズ全4巻を通読するだけで、設計から品質保証まで本番レディな CI/CD 環境を一から構築できる。この完走価値を最大化することが本記事の執筆動機である。

特にパッケージガバナンスの観点から、2024年以降は Log4Shell・XZ Utils のようなサプライチェーン攻撃事例が増加しており、外部レジストリへの直接依存を遮断して内部承認済みパッケージのみを使用する組織的ポリシーの重要性が増している。CodeArtifact の upstream proxy + Package Origin Control はこのニーズに直接応えるアーキテクチャだ。本記事はそのセキュリティ観点も含めて実装を解説する。

本番運用クオリティのゴールラインとしては、以下の状態を目標とする。

  • CodeArtifact Domain が KMS 暗号化で保護され、社内パッケージが upstream proxy 経由でキャッシュされている
  • CodeBuild の buildspec.yml で IAM Token が自動更新され、12時間制限を意識せずに CI が回る
  • CodeGuru Reviewer が全 PR に静的解析を自動実行し、CRITICAL 指摘が即日対応される運用が確立されている
  • CodeGuru Profiler が本番 ECS/Lambda に組み込まれ、フレームグラフで CPU ホットスポットが継続的に可視化されている

1-4. 本記事の構成

本記事は §1〜§8 で構成される。通し読みでも、目的の章から読み始めても理解できるよう各章は独立性を保っている。

タイトル主な内容
§1この記事についてシリーズ完結宣言・読者像・QG-1 全体アーキ
§2CodeArtifact 全体像Domain/Repository/Package 3層・upstream proxy・GitHub Packages 比較
§3CodeArtifact 実装リポジトリ作成・IAM Token 認証・CodeBuild 統合 (Terraform/CLI/コンソール)
§4CodeGuru ReviewerPR 統合・CWE/OWASP 静的解析・コスト管理
§5CodeGuru Profilerエージェント組み込み・フレームグラフ解釈・Profiling Group 設計
§6Terraform 完全実装CodeArtifact + CodeGuru 全 HCL・変数設計・モジュール分割
§7Bedrock Agents との比較選定フロー・Action Group vs CWE ルール・共存パターン
§8シリーズ完結まとめVol1-4 チートシート・落とし穴10選・シリーズ完結宣言

読み方の指針:
– CodeArtifact の概念から始めたい → §2 → §3 の順で読む
– CodeGuru Reviewer の PR 統合だけ知りたい → §4 から読む
– Bedrock との選定で迷っている → §7 から読む
– シリーズ全体を振り返りたい → §8 のチートシートを参照する

aws-code-family シリーズ完結への道のり:

本記事は4巻構成シリーズの完結弾だ。各 Volume が担うレイヤーと依存関係を理解することで、パイプライン全体像が見えやすくなる。

[Vol1 選定] ← サービス選定・GHA/ecspresso 使い分け
  ↓
[Vol2 ビルド] ← CodeBuild VPC 統合・マルチアーキテクチャ
  ↓
[Vol3 デプロイ] ← CodePipeline V2・CodeDeploy Blue/Green
  ↓
[Vol4 品質・パッケージ] ← CodeArtifact・CodeGuru・Bedrock 比較 (本記事)

シリーズを Vol1 から順に読むことで、AWS 上の本番 CI/CD パイプラインを一から設計・実装・運用できる完全なロードマップが得られる。本記事を最後まで読んだとき、「設計から品質保証まで、Terraform 一本で全部書ける」という確かな手応えを届けることが目標だ。

Vol3: CodePipeline V2 + CodeDeploy 本番運用


2. CodeArtifact 全体像 (npm/pip/maven/nuget・upstream proxy・GitHub Packages比較)

fig02: CodeArtifact Domain/Repository/upstream 構造図

【QG-2】CodeArtifact vs GitHub Packages — 5軸比較マトリクス

比較軸AWS CodeArtifactGitHub Packages
コスト$0.05/GB ストレージ + $0.09/GB データ転送 (AWS外向け)。同一 VPC 内転送は無料。月100GBまでは数ドル程度。Freeプランは500MB/2GBまで無料。超過は $0.25/GB ストレージ + $0.50/GB 転送。GitHub Actions と同一 Org 内は無料転送。
権限管理IAM Role + resource-based policy で AWS 標準の細粒度アクセス制御。クロスアカウント共有も IAM 委任で実現。GitHub の組織/リポジトリ権限と連動。PAT または GitHub Apps トークンで認証。クロスオーガニゼーション共有はサポート外。
upstream proxynpmjs/PyPI/Maven Central/NuGet.org/crates.io 等 public registry を upstream に設定してキャッシュ可能。脆弱性遮断・承認フロー組込が可能。upstream proxy 機能なし。public registry への直接アクセスを代替できない。
対応言語npm/pip/maven/gradle/nuget/swift/cargo/generic (8形式)。Ruby gems は2024年時点で非対応。npm/maven/gradle/nuget/rubygems/docker の6形式。pip (Python) は非対応。
CI統合CodeBuild: IAM Role で Token 自動取得 (12時間期限に注意)。GHA: OIDC + aws-actions/configure-aws-credentials で統合可能。GitHub Actions とシームレス統合。GITHUB_TOKEN で認証不要。非 GitHub CI との統合は PAT/Apps 必要。

選定指針:

  • CodeArtifact を選ぶ場合: AWS 環境に閉じたパイプライン (CodeBuild/CodePipeline)・クロスアカウントパッケージ共有・upstream proxy でセキュリティポリシー統制が必要・Python (pip) パッケージを含む多言語環境。
  • GitHub Packages を選ぶ場合: GitHub Actions 主体の CI/CD・外部公開パッケージが主・Ruby gems を含む環境・GitHub Organization でアクセス管理を一元化している場合。
  • 共存パターン: 社内 npm/pip は CodeArtifact、公開 Docker イメージは GitHub Packages という切り分けも有効。

2-1. CodeArtifact 基本概念

CodeArtifact のリソースモデルは Domain → Repository → Package の3層で構成される。この階層を理解することが設計の出発点となる。

Domain (ドメイン)

Domain は CodeArtifact の最上位リソースで、組織またはビジネスユニット単位でパッケージ管理の境界を定義する。

  • 1つの AWS アカウントに複数の Domain を作成できる (通常は組織全体で1つが推奨)
  • Domain レベルで KMS カスタムキーによる暗号化を設定する
  • クロスアカウント共有: resource-based policy で他アカウントの IAM Role に Domain 内リポジトリへのアクセスを委任できる
  • Domain 名はリージョン内で一意。一度作成したら変更不可
resource "aws_codeartifact_domain" "main" {
  domain= "my-org"
  encryption_key = aws_kms_key.codeartifact.arn

  tags = {
 Project  = var.project
 Environment = var.environment
  }
}

resource "aws_kms_key" "codeartifact" {
  description = "CodeArtifact domain encryption key"
  deletion_window_in_days = 7
}
# Domain 作成 (CLI)
aws codeartifact create-domain \
  --domain my-org \
  --encryption-key arn:aws:kms:ap-northeast-1:123456789012:key/xxx

# コンソール: CodeArtifact → Domains → Create domain

Repository (リポジトリ)

Repository は Domain 内に作成するパッケージの集合体で、プロジェクト・チーム・用途単位で分割する。

  • 1つの Domain に複数の Repository を作成できる
  • Repository には upstream (上流リポジトリ) を設定でき、キャッシュ・代理取得が可能
  • 代表的なパターン:
  • internal-npm: チーム内共有パッケージのみを格納する
  • npm-store: npmjs.org の upstream proxy キャッシュ専用
  • shared-libs: 複数チームが利用する共通ライブラリ
# 内部パッケージ用リポジトリ
resource "aws_codeartifact_repository" "internal_npm" {
  repository= "internal-npm"
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  upstream {
 repository_name = aws_codeartifact_repository.public_npmjs.repository
  }
}

# public npmjs.org proxy 用リポジトリ (upstream 専用)
resource "aws_codeartifact_repository" "public_npmjs" {
  repository= "public-npmjs-com"
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  external_connections {
 external_connection_name = "public:npmjs"
  }
}
# リポジトリ作成 (CLI)
aws codeartifact create-repository \
  --domain my-org \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --repository internal-npm \
  --description "Internal npm packages"

# upstream 設定
aws codeartifact update-repository \
  --domain my-org \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --repository internal-npm \
  --upstreams upstreamRepositoryName=public-npmjs-com

# コンソール: CodeArtifact → Repositories → Create repository → Upstream repositories に追加

Package (パッケージ)

Package は Repository 内に格納される個別のパッケージで、format/namespace/name/version の4要素で一意に識別される。

  • format: npm / pypi / maven / nuget / swift / cargo / generic のいずれか
  • namespace: npm では @scope、maven では groupId に相当
  • version: semver 形式 (npm/pip/nuget) または maven 形式
  • パッケージのメタデータ (description/license/tags) はコンソールや API で確認可能
# パッケージ一覧 (CLI)
aws codeartifact list-packages \
  --domain my-org \
  --repository internal-npm \
  --format npm \
  --query 'packages[*].{Name:name,Namespace:namespace}' \
  --output table

# コンソール: CodeArtifact → Repositories → internal-npm → Packages

2-2. 対応パッケージ形式

CodeArtifact が対応するパッケージ形式は 2024年時点で以下の通りだ。形式によって external_connection (public registry への接続) の有無と GA リリース時期が異なる。

形式対象言語external_connection 名GA リリース備考
npmJavaScript / TypeScript / Node.jspublic:npmjs2020/06最も利用実績が多い
pypiPythonpublic:pypi2020/06pip/Poetry/pipenv 全対応
mavenJava / Kotlin / Scalapublic:maven-central / public:maven-googleandroid2020/06gradle も同形式を使用
nugetC# / .NET / F#public:nuget-org2020/06.NET 5+ 対応
swiftSwift / iOS / macOS‒ (external_connection 未対応)2022/12社内配布のみ・upstream proxy 不可
cargoRustpublic:crates-io2023/06Rust プロジェクトで採用増
generic任意バイナリ2021/06zip/tar/jar 等・CI アーティファクト管理に使用
rubyRuby未対応RubyGems は非サポート (2024年時点)

実務上の注意点:

  • Ruby (RubyGems) は 2024年時点で非対応。Ruby プロジェクトでは GitHub Packages または Gemfury を検討。
  • swiftexternal_connections ブロック指定不可 (社内パッケージの配布のみ)。
  • generic 形式は CI のビルド成果物 (zip/jar/wheel) を管理するのに便利。バージョン管理付き S3 の代替として使える。
  • maven / gradle は同じ maven 形式を共用。external_connection_name = "public:maven-central" で Maven Central をプロキシできる。
# pypi リポジトリ設定例
resource "aws_codeartifact_repository" "public_pypi" {
  repository= "public-pypi"
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  external_connections {
 external_connection_name = "public:pypi"
  }
}

resource "aws_codeartifact_repository" "internal_pip" {
  repository= "internal-pip"
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  upstream {
 repository_name = aws_codeartifact_repository.public_pypi.repository
  }
}
# 形式ごとのパッケージ publish 例
# npm
aws codeartifact login --tool npm --domain my-org \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --repository internal-npm
npm publish

# pip (twine 経由)
aws codeartifact login --tool pip --domain my-org \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --repository internal-pip
pip install twine
twine upload --repository codeartifact dist/*

# maven (settings.xml に認証情報を設定後)
mvn deploy

2-3. upstream proxy 機能

upstream proxy は CodeArtifact 最大の差別化機能だ。internal-npm → public-npmjs-com → npmjs.org というチェーンを組むことで、開発者は npm install を変更せず、透過的に public registry のパッケージを内部リポジトリ経由で取得できる。キャッシュにより再ダウンロードを回避し、upstream の障害時にも既存バージョンは取得可能になる。

upstream チェーンの構成

CodeArtifact の upstream チェーンは以下の3段構成が実務上の標準だ。

[開発者 npm install]
  ↓
[internal-npm] ← 社内プライベートパッケージ + キャッシュ取得
  ↓ (upstream)
[public-npmjs-com] ← npmjs.org の proxy/キャッシュ専用
  ↓ (external_connection)
[npmjs.org] ← 実際の public registry

Terraform での実装例を示す。

# upstream 設定付き内部リポジトリ
resource "aws_codeartifact_repository" "internal_npm" {
  repository= "internal-npm"
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  upstream {
 repository_name = aws_codeartifact_repository.public_npmjs.repository
  }
}

# npmjs.org proxy 専用 (external_connection で public registry に接続)
resource "aws_codeartifact_repository" "public_npmjs" {
  repository= "public-npmjs-com"
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  external_connections {
 external_connection_name = "public:npmjs"
  }
}
# upstream 設定確認 (CLI)
aws codeartifact list-repositories-in-domain \
  --domain my-org \
  --region ap-northeast-1 \
  --query 'repositories[*].{Name:name,Upstreams:upstreams}'

# upstream リポジトリ越しのパッケージ取得テスト
aws codeartifact login --tool npm \
  --domain my-org \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --repository internal-npm
npm install lodash  # npmjs.org から upstream 経由で自動取得・キャッシュ

コンソール: CodeArtifact → Repositories → internal-npm → 「Upstream repositories」タブで upstream チェーンのグラフを確認できる。

脆弱性遮断 (Package Origin Control)

Package Origin Control (POC) は、パッケージがどの origin から取得されたかを制御する機能だ。BLOCK を設定することで、internal リポジトリに存在しないパッケージが upstream (public registry) から直接流入するのを防ぎ、承認されていない新バージョンのインストールを組織ポリシーで強制できる。

# Package Origin Control の設定 (CLI)
aws codeartifact put-package-origin-configuration \
  --domain my-org \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --repository internal-npm \
  --format npm \
  --package lodash \
  --restrictions publish=ALLOW,upstream=BLOCK
  # ALLOW: 既存の承認済みバージョンのみ upstream から取得可
  # BLOCK: この repository への upstream 経由の自動追加を完全遮断

upstream=BLOCK に設定したパッケージは、internal リポジトリに明示的に publish されたバージョンのみ取得可能になる。Log4j のような脆弱性発覚時には BLOCK で即座に新バージョン流入を遮断し、セキュリティチームが承認したバージョンのみを ALLOW に戻す運用が可能だ。

社内承認フロー (バージョンライフサイクル管理)

# バージョン状態の確認 (Unlisted/Published/Archived/Disposed)
aws codeartifact list-package-versions \
  --domain my-org \
  --repository internal-npm \
  --format npm \
  --package lodash \
  --query 'versions[*].{Version:version,Status:status}'

# バージョンを Unlisted (非表示) に設定 (承認待ち扱い)
aws codeartifact update-package-versions-status \
  --domain my-org \
  --repository internal-npm \
  --format npm \
  --package lodash \
  --versions '["4.17.21"]' \
  --target-status Published  # Unlisted → Published で承認完了

# 廃止バージョンを Archived に変更 (ダウンロード不可・メタデータ残存)
aws codeartifact update-package-versions-status \
  --domain my-org \
  --repository internal-npm \
  --format npm \
  --package lodash \
  --versions '["4.17.10","4.17.11"]' \
  --target-status Archived

コンソール: CodeArtifact → Repositories → internal-npm → Packages → lodash → バージョン一覧でステータスをドロップダウンで変更できる。

2-4. GitHub Packages との比較選定

冒頭の QG-2 で5軸の定量比較を示した。ここでは実務での選定フローと移行パターンを補足する。

選定フロー (簡易チェック):

CI は GitHub Actions 主体か?
├─ Yes → GitHub Packages が統合コスト最小 (GITHUB_TOKEN で認証不要)
│ただし pip/Python パッケージが必要なら CodeArtifact へ
└─ No (CodeBuild/Jenkins/etc.) → CodeArtifact が IAM 統合で自然
│
├─ クロスアカウント共有が必要 → CodeArtifact (IAM 委任)
├─ upstream proxy でセキュリティ統制が必要 → CodeArtifact
└─ 外部公開パッケージが主 → GitHub Packages (公開は無料)

GitHub Packages から CodeArtifact への移行ステップ:

  1. CodeArtifact Domain + Repository を Terraform で作成
  2. aws codeartifact login --tool npm で認証設定
  3. 既存パッケージを npm publish で CodeArtifact へ再 publish
  4. ~/.npmrc の registry を CodeArtifact エンドポイントに切り替え
  5. CI の認証を PAT → IAM Role + Token 取得に変更
  6. Package Origin Control で外部パッケージの流入ポリシーを設定

実務上の注意点:

  • Ruby (RubyGems) を主力に使うチームは GitHub Packages が現実解 (CodeArtifact 非対応)
  • コスト面: 月数 GB 程度の社内パッケージなら両者ともに数ドル以下。転送量が多い場合は同一 VPC 内転送無料の CodeArtifact が有利
  • 既存 GitHub Organization が統制単位の場合: GitHub Packages の Org 権限管理がそのまま使えるメリットを活かす
  • AWS 環境に完全クローズしたい場合 (インターネット断絶 VPC): CodeArtifact + VPC Endpoint の組み合わせで外部通信を完全遮断できる

3. CodeArtifact 実装 (リポジトリ作成/upstream/IAM Token認証/CodeBuild統合)

fig03: CodeArtifact IAM Token認証フロー

CodeArtifact を本番運用に投入するには Domain (組織単位) と Repository (パッケージ集合) を正しく設計し、IAM Token による認証を CI パイプラインに自動組込する必要がある。本章では AWS CLI / Terraform / コンソールの 3 形式で実装手順を示す。

3-1. Domain 作成

Domain は組織単位の管理境界で、KMS カスタムキーによる暗号化が推奨される。1 AWS アカウントに複数 Domain を作成できるが、アカウント分離設計では 1 Domain / 1 環境が原則となる。Domain 名は英小文字・数字・ハイフンのみ使用可能で、作成後の変更はできない点に注意する。

AWS CLI

# KMS キー作成
aws kms create-key \
  --description "CodeArtifact Domain encryption key" \
  --key-usage ENCRYPT_DECRYPT \
  --region ap-northeast-1 \
  --query 'KeyMetadata.KeyId' \
  --output text

# Domain 作成 (KMS 暗号化指定)
aws codeartifact create-domain \
  --domain mycompany \
  --encryption-key arn:aws:kms:ap-northeast-1:123456789012:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  --region ap-northeast-1

# Domain 一覧確認
aws codeartifact list-domains --region ap-northeast-1

Terraform (aws_codeartifact_domain)

resource "aws_kms_key" "codeartifact" {
  description = "CodeArtifact Domain encryption key"
  deletion_window_in_days = 10
  enable_key_rotation  = true
}

resource "aws_kms_alias" "codeartifact" {
  name = "alias/codeartifact-domain"
  target_key_id = aws_kms_key.codeartifact.key_id
}

resource "aws_codeartifact_domain" "main" {
  domain= "mycompany"
  encryption_key = aws_kms_key.codeartifact.arn

  tags = {
 Environment = var.environment
 ManagedBy= "terraform"
  }
}

コンソール操作

  1. CodeArtifact コンソール → 「ドメインを作成」をクリック
  2. ドメイン名を入力 (例: mycompany)
  3. 暗号化キー → 「カスタム AWS KMS キーを使用」→ 事前作成済みキー ARN を指定
  4. 「ドメインを作成」をクリックして完了

3-2. Repository 作成 (upstream 設定込み)

Repository は対応パッケージ形式 (npm / pip / maven / nuget 等) ごとに作成する。upstream に public registry を設定することで公式パッケージへの透過的なプロキシ機能を利用できる。

設計パターン: 内部パッケージ用リポジトリ (internal-npm) と public proxy リポジトリ (upstream-npm) を分離し、internal-npmupstream-npm の upstream 接続を設定するのが定番構成。社内承認済みパッケージのみキャッシュすることで脆弱性のある外部パッケージの直接流入を防止できる。

AWS CLI

DOMAIN=mycompany
ACCOUNT=123456789012
REGION=ap-northeast-1

# public:npmjs upstream リポジトリ作成
aws codeartifact create-repository \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository upstream-npm \
  --description "npm public registry proxy" \
  --region $REGION

# upstream-npm に public:npmjs 外部接続を設定
aws codeartifact associate-external-connection \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository upstream-npm \
  --external-connection public:npmjs \
  --region $REGION

# 社内 npm リポジトリ (upstream に upstream-npm を接続)
aws codeartifact create-repository \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository internal-npm \
  --description "Internal npm packages with public proxy" \
  --upstreams repositoryName=upstream-npm \
  --region $REGION

# 社内 Python リポジトリ (pip)
aws codeartifact create-repository \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository internal-pypi \
  --description "Internal Python packages with public proxy" \
  --upstreams repositoryName=upstream-pypi \
  --region $REGION

Terraform (aws_codeartifact_repository)

# npm upstream (public:npmjs proxy)
resource "aws_codeartifact_repository" "upstream_npm" {
  repository = "upstream-npm"
  domain  = aws_codeartifact_domain.main.domain

  external_connections {
 external_connection_name = "public:npmjs"
  }
}

# PyPI upstream (public:pypi proxy)
resource "aws_codeartifact_repository" "upstream_pypi" {
  repository = "upstream-pypi"
  domain  = aws_codeartifact_domain.main.domain

  external_connections {
 external_connection_name = "public:pypi"
  }
}

# 内部 npm リポジトリ (upstream-npm に接続)
resource "aws_codeartifact_repository" "internal_npm" {
  repository  = "internal-npm"
  domain= aws_codeartifact_domain.main.domain
  description = "Internal npm packages with public proxy"

  upstreams {
 repository_name = aws_codeartifact_repository.upstream_npm.repository
  }

  tags = {
 Environment = var.environment
 ManagedBy= "terraform"
  }
}

# 内部 Python リポジトリ
resource "aws_codeartifact_repository" "internal_pypi" {
  repository  = "internal-pypi"
  domain= aws_codeartifact_domain.main.domain
  description = "Internal Python packages with public proxy"

  upstreams {
 repository_name = aws_codeartifact_repository.upstream_pypi.repository
  }

  tags = {
 Environment = var.environment
 ManagedBy= "terraform"
  }
}

# Repository permissions policy (CodeBuild IAM Role に read/publish 権限)
resource "aws_codeartifact_repository_permissions_policy" "internal_npm" {
  repository= aws_codeartifact_repository.internal_npm.repository
  domain = aws_codeartifact_domain.main.domain
  domain_owner = data.aws_caller_identity.current.account_id

  policy_document = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Sid = "AllowCodeBuildReadWrite"
  Effect = "Allow"
  Principal = {
 AWS = aws_iam_role.codebuild.arn
  }
  Action = [
 "codeartifact:GetAuthorizationToken",
 "codeartifact:GetRepositoryEndpoint",
 "codeartifact:ReadFromRepository",
 "codeartifact:PublishPackageVersion",
 "codeartifact:PutPackageMetadata"
  ]
  Resource = "*"
}
 ]
  })
}

コンソール操作

  1. CodeArtifact コンソール → 対象 Domain を選択 → 「リポジトリを作成」
  2. リポジトリ名 (例: internal-npm) とパッケージ形式 (npm) を選択
  3. 「パブリックアップストリームリポジトリ」→ npm-store (public:npmjs) を選択
  4. 「リポジトリを作成」をクリック
  5. 作成後、リポジトリ詳細 →「接続の手順」で認証設定コマンドを確認

3-3. IAM Token 認証 (12時間有効・⚠️期限切れ注意)

CodeArtifact は AWS STS ベースの一時トークンで認証する。aws codeartifact get-authorization-token で取得したトークンは 最大 12 時間有効 で、期限切れ後は再取得が必要になる。CI パイプラインでは pre_build フェーズで毎回再取得するのが定番パターン。

AWS CLI: トークン取得とエンドポイント確認

DOMAIN=mycompany
ACCOUNT=123456789012
REGION=ap-northeast-1

# 認証トークン取得 (最大 12時間有効)
export CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --query authorizationToken \
  --output text \
  --region $REGION)

# リポジトリエンドポイント取得
export NPM_ENDPOINT=$(aws codeartifact get-repository-endpoint \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository internal-npm \
  --format npm \
  --query repositoryEndpoint \
  --output text \
  --region $REGION)

echo "Token acquired. Endpoint: $NPM_ENDPOINT"

npm 認証設定 (~/.npmrc への自動書き込み)

# aws codeartifact login コマンドで ~/.npmrc を自動更新
aws codeartifact login \
  --tool npm \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository internal-npm \
  --region $REGION

# 生成される ~/.npmrc の内容例:
# //mycompany-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/npm/internal-npm/:_authToken=TOKEN
# @mycompany:registry=https://mycompany-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/npm/internal-npm/

pip 認証設定 (pip.conf への自動書き込み)

# aws codeartifact login コマンドで pip.conf を自動更新
aws codeartifact login \
  --tool pip \
  --domain $DOMAIN \
  --domain-owner $ACCOUNT \
  --repository internal-pypi \
  --region $REGION

# ~/.config/pip/pip.conf に書き込まれる内容例:
# [global]
# index-url=https://aws:TOKEN@mycompany-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/pypi/internal-pypi/simple/

maven 認証設定 (settings.xml)

<!-- ~/.m2/settings.xml への設定例 -->
<settings>
  <servers>
 <server>
<id>mycompany--internal-maven</id>
<username>aws</username>
<!-- CODEARTIFACT_TOKEN を環境変数として export した上で参照 -->
<password>${env.CODEARTIFACT_TOKEN}</password>
 </server>
  </servers>
  <profiles>
 <profile>
<id>codeartifact</id>
<repositories>
  <repository>
 <id>mycompany--internal-maven</id>
 <url>https://mycompany-123456789012.d.codeartifact.ap-northeast-1.amazonaws.com/maven/internal-maven/</url>
  </repository>
</repositories>
 </profile>
  </profiles>
  <activeProfiles>
 <activeProfile>codeartifact</activeProfile>
  </activeProfiles>
</settings>

コンソール操作 (接続の手順)

コンソールから直接トークンを発行する機能はないが、リポジトリ詳細画面 →「接続の手順」に npm / pip / maven / nuget 別の認証設定コマンドが表示される。ローカル開発環境での初回設定時はこのガイドをコピーして実行するとよい。

3-4. CodeBuild 統合 (buildspec.yml でトークン自動取得)

Vol2 CodeBuild 完全活用 で構築した buildspec ベースに CodeArtifact トークン取得フェーズを追加する。pre_build フェーズで毎回トークンを再取得することで 12 時間期限切れ問題を回避する。

buildspec.yml (npm プロジェクト例)

version: 0.2

env:
  variables:
 DOMAIN: mycompany
 REGION: ap-northeast-1
  parameter-store:
 ACCOUNT_ID: /codebuild/account-id

phases:
  install:
 runtime-versions:
nodejs: 18
 commands:
- echo "Installing Node.js runtime..."

  pre_build:
 commands:
- echo "Configuring CodeArtifact authentication..."
- aws codeartifact login --tool npm --domain $DOMAIN --domain-owner $ACCOUNT_ID --repository internal-npm --region $REGION
- echo "CodeArtifact npm login successful"

  build:
 commands:
- npm ci
- npm run build
- npm test

  post_build:
 commands:
- |
  if [ "$PUBLISH_PACKAGE" = "true" ]; then
 echo "Publishing package to CodeArtifact..."
 npm publish
  fi

artifacts:
  files:
 - "dist/**/*"

buildspec.yml (Python プロジェクト例)

version: 0.2

env:
  variables:
 DOMAIN: mycompany
 REGION: ap-northeast-1
  parameter-store:
 ACCOUNT_ID: /codebuild/account-id

phases:
  install:
 runtime-versions:
python: "3.11"
 commands:
- pip install --upgrade pip setuptools wheel

  pre_build:
 commands:
- echo "Configuring CodeArtifact pip authentication..."
- aws codeartifact login --tool pip --domain $DOMAIN --domain-owner $ACCOUNT_ID --repository internal-pypi --region $REGION
- echo "CodeArtifact pip login successful"

  build:
 commands:
- pip install -r requirements.txt
- python -m pytest tests/ -v --tb=short

  post_build:
 commands:
- python -m build
- |
  if [ "$PUBLISH_PACKAGE" = "true" ]; then
 REPO_URL=$(aws codeartifact get-repository-endpoint --domain $DOMAIN --domain-owner $ACCOUNT_ID --repository internal-pypi --format pypi --query repositoryEndpoint --output text)
 python -m twine upload --repository-url $REPO_URL dist/*
  fi

artifacts:
  files:
 - "dist/**/*"

Terraform: CodeBuild IAM Role への CodeArtifact 権限付与

Vol2 の CodeBuild モジュールで作成した IAM Role に以下のインラインポリシーを追加する。sts:GetServiceBearerTokenResource: "*" + Condition での付与が必須。

resource "aws_iam_role_policy" "codebuild_codeartifact" {
  name = "codebuild-codeartifact"
  role = aws_iam_role.codebuild.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Sid = "CodeArtifactDomainAccess"
  Effect = "Allow"
  Action = [
 "codeartifact:GetAuthorizationToken",
 "codeartifact:GetRepositoryEndpoint",
 "codeartifact:ReadFromRepository",
 "codeartifact:PublishPackageVersion",
 "codeartifact:PutPackageMetadata"
  ]
  Resource = [
 aws_codeartifact_domain.main.arn,
 "${aws_codeartifact_domain.main.arn}/*"
  ]
},
{
  Sid= "STSGetBearerToken"
  Effect= "Allow"
  Action= ["sts:GetServiceBearerToken"]
  Resource = "*"
  Condition = {
 StringEquals = {
"sts:AWSServiceName" = "codeartifact.amazonaws.com"
 }
  }
}
 ]
  })
}

コンソール操作: CodeBuild プロジェクトとの接続確認

  1. CodeBuild コンソール → 対象プロジェクト →「環境」タブ → サービスロール ARN を確認
  2. IAM コンソール → 対象ロール → codeartifact:GetAuthorizationToken / sts:GetServiceBearerToken が含まれることを確認
  3. ビルドログ → pre_build フェーズで CodeArtifact npm login successful が出力されることを確認
  4. 成功後、CodeArtifact コンソール → リポジトリ →「パッケージ」タブでキャッシュ済みパッケージを確認

3-5. 落とし穴 (本番で踏みやすいポイント)

CodeArtifact 実装で踏みやすい落とし穴

  • Token 12時間期限切れ: 長時間ビルドや夜間バッチでトークンが期限切れになり CI が失敗する。pre_build フェーズで毎回 aws codeartifact login を実行することで回避できる。
  • upstream 設定漏れ: upstream を設定しないと public npm / PyPI から直接パッケージを取得できず npm installpip install が失敗する。Repository 作成時に external_connections または upstreams ブロックを忘れずに設定する。
  • permissions policy 漏れ (sts:GetServiceBearerToken): CodeBuild の IAM Role に sts:GetServiceBearerToken がないとトークン取得が AccessDenied になる。この権限は Resource: "*" + Condition: {StringEquals: {sts:AWSServiceName: codeartifact.amazonaws.com}} で付与する必要がある。
  • KMS 暗号化漏れ: Domain 作成時に KMS キーを指定しないと AWS マネージドキー (aws/codeartifact) が自動適用される。コンプライアンス要件がある場合は必ずカスタムキーを指定する。
  • Repository permissions policy の Resource 指定: Repository ポリシーで個別 ARN を指定しようとすると権限が期待通りに効かないケースがある。Resource: "*" が推奨パターン。

4. CodeGuru Reviewer (PRレビュー自動化)

fig04: CodeGuru Reviewer PRレビュー自動化フロー

AWS CodeGuru Reviewer は機械学習を活用した静的コードレビューサービスだ。GitHub・CodeCommit・Bitbucket リポジトリと連携し、PR (Pull Request) が作成・更新されるたびに自動でコードを解析してインラインコメントを投稿する。開発者は CI/CD パイプラインを止めずに、セキュリティ脆弱性・コードスメル・パフォーマンス問題を PR 単位で継続的に検出できる。

Vol1-3 で構築した CodePipeline/CodeBuild パイプラインに CodeGuru Reviewer を組み込むことで、「ビルド成功 = 品質保証済み」の基準を引き上げられる。特に Java/Python の大規模プロダクトで効果が高く、CWE (Common Weakness Enumeration) ベースのセキュリティ検出は SonarQube 有償版に匹敵するレベルだ。Amazon 社内で 10 億行以上のコードを学習データとして構築された ML モデルが、一般的な静的解析ツールでは検出しにくいパターンを拾い上げる。

4-1. 対応言語と検出カテゴリ

対応言語 (11言語)

言語対応バージョン検出精度
Java8 / 11 / 17 / 21最高 (ML学習量最大)
Python3.6〜3.12最高
JavaScriptES5+
TypeScript4.x+
C#.NET 6+
Ruby2.7+
Go1.18+
Kotlin1.5+
Scala2.13+
Swift5.x
PHP7.4 / 8.x

⚠️ 重要: 上記以外の言語 (C/C++/Rust/Elixir 等) はレビューが実行されても検出件数ゼロになる。多言語モノレポで非対応言語のみの変更 PR に対してもコストは発生するため、リポジトリ構成と対応言語を事前に照合することが必須だ。

検出カテゴリ

CodeGuru Reviewer が検出する問題は 4 カテゴリに分類される。

カテゴリ説明主な検出例
セキュリティCWE / AWS セキュリティ best practices 違反SQLインジェクション・ハードコードシークレット・暗号化漏れ
コードスメル保守性・可読性の低下パターンデッドコード・過度な複雑度・冗長な条件分岐
パフォーマンス非効率な処理パターンN+1クエリ・不必要なオブジェクト生成・ループ内 I/O
AWS best practicesAWS SDK/API の非推奨使用非推奨 API 呼び出し・バーストリクエスト

4-2. 連携設定 (Terraform / AWS CLI / コンソール)

リポジトリを CodeGuru Reviewer と関連付ける方法は 3 通りある。

Terraform (推奨)

aws_codegurureviewer_repository_association リソースで GitHub/CodeCommit/Bitbucket を関連付ける。GitHub 連携には CodeStar Connection が必要だ。

# CodeStar Connection (GitHub OAuth 認証の実体)
resource "aws_codestarconnections_connection" "github" {
  name = "github-connection"
  provider_type = "GitHub"
}

# CodeGuru Reviewer リポジトリ関連付け (GitHub)
resource "aws_codegurureviewer_repository_association" "github_main" {
  repository {
 github_enterprise_server {
connection_arn = aws_codestarconnections_connection.github.arn
name  = "my-app-repo"
owner = "myorg"
 }
  }
  tags = {
 Env  = var.env
 Service = "CodeGuruReviewer"
  }
}

# CodeCommit リポジトリ連携 (OAuth 不要・シンプル)
resource "aws_codegurureviewer_repository_association" "codecommit_main" {
  repository {
 codecommit {
name = aws_codecommit_repository.app.repository_name
 }
  }
}

# CodeGuru Reviewer 用 IAM Role
resource "aws_iam_role" "codeguru_reviewer" {
  name = "codeguru-reviewer-role-${var.env}"
  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "codeguru-reviewer.amazonaws.com" }
Action = "sts:AssumeRole"
 }]
  })
}

resource "aws_iam_role_policy_attachment" "codeguru_reviewer" {
  role = aws_iam_role.codeguru_reviewer.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonCodeGuruReviewerFullAccess"
}

GitHub の場合は Terraform Apply だけでは有効化されない。Apply 後にマネジメントコンソールで CodeStar Connection の OAuth 認証ハンドシェイクを手動実施する必要がある。この手順を踏まないと Association が Pending のまま進まない。

AWS CLI

# GitHub リポジトリ連携 (CodeStar Connection ARN が必要)
aws codeguru-reviewer associate-repository \
  --repository '{
 "GitHubEnterpriseServer": {
"ConnectionArn": "arn:aws:codestar-connections:ap-northeast-1:123456789012:connection/xxxxxxxx",
"Name": "my-app-repo",
"Owner": "myorg"
 }
  }'

# CodeCommit リポジトリ連携 (OAuth 不要)
aws codeguru-reviewer associate-repository \
  --repository '{"CodeCommit": {"Name": "my-codecommit-repo"}}'

# 関連付け一覧確認 (State で有効化状態を確認)
aws codeguru-reviewer list-repository-associations \
  --query 'RepositoryAssociationSummaries[*].{Name:Name,State:State,Arn:AssociationArn}' \
  --output table

コンソール

  1. マネジメントコンソール → CodeGuruReviewerAssociated repositories
  2. Associate repository をクリック
  3. リポジトリプロバイダを選択 (GitHub / GitHub Enterprise / CodeCommit / Bitbucket)
  4. GitHub の場合: Connect to GitHub → OAuth 認証 → リポジトリを選択
  5. CodeCommit の場合: リージョン内のリポジトリ一覧から選択してそのまま確定
  6. Associate をクリック → State が Associated になれば完了
QG-3: CodeGuru Reviewer vs Profiler — 用途・対応言語・料金 比較

項目ReviewerProfiler
用途PR レビュー・静的コード解析 (開発時品質ゲート)本番環境パフォーマンス分析 (実行時ボトルネック特定)
解析タイミングPR 作成・更新時 (オンデマンド)本番稼働中 (常時サンプリング)
対応言語11言語 (Java/Python/JS/TS/C#/Ruby/Go/Kotlin/Scala/Swift/PHP)2言語 (Java/Python)
対応環境GitHub / CodeCommit / BitbucketEC2 / ECS / EKS / Fargate / Lambda
料金体系分析行数ベース (Standard $0.50/100行・Enterprise $0.10/100行)稼働時間ベース ($0.005/Profiling Group/時間・最低5分課金)
月額目安50,000行リポジトリ × 月 30PR = $7,500 (Standard)常時稼働 1 Group = $3.6/月
主な検出内容セキュリティ脆弱性・コードスメル・AWS best practices 違反CPU/Memory ホットスポット・latency bottleneck・heap allocation
CI/CD 統合PR 自動インラインコメント・SARIF 形式レポートフレームグラフ・CloudWatch Metrics 連携
ML 特化領域コードパターン学習 (Amazon 社内 10億行以上)プロファイルデータ統計分析・異常検知

選定指針: 「PR 段階で品質を担保したい」→ Reviewer / 「本番で遅い箇所を特定したい」→ Profiler。コスト制約があれば Reviewer 優先 (PR 単位で効果が可視化されやすく、セキュリティ検出の ROI が高い)。

4-3. PR コメント自動投稿

Association 完了後、リポジトリに PR を作成すると CodeGuru Reviewer が自動で解析を開始し、問題箇所にインラインコメントを投稿する。

recommendation severity (5段階)

Severity対応方針代表的な検出例
Critical即時修正必須 (PR マージ禁止推奨)ハードコードシークレット・SQLインジェクション
High修正必須 (次スプリントまで)暗号化漏れ・認証バイパス可能なコード
Medium計画的修正非効率なアルゴリズム・過度な複雑度
Low改善検討冗長コード・命名規則違反
Info参考情報AWS SDK 推奨パターン案内

検出コメント例 (Python — ハードコードシークレット)

# 検出されるコード (Critical 対象)
db_password = "MySecretPass123!"

# CodeGuru Reviewer が PR コメントとして投稿する内容:
# [Critical] hardcoded-credentials (CWE-798)
# Severity: Critical
# Recommendation: Store credentials in AWS Secrets Manager
#or use environment variables.

AWS CLI で Recommendation 一覧を取得する

# 最新の Code Review ARN を取得
REVIEW_ARN=$(aws codeguru-reviewer list-code-reviews \
  --type PullRequest \
  --query 'CodeReviewSummaries[0].CodeReviewArn' \
  --output text)

# Recommendation 一覧 (Severity・ファイル・説明)
aws codeguru-reviewer list-recommendations \
  --code-review-arn "$REVIEW_ARN" \
  --query 'RecommendationSummaries[*].{File:FilePath,Sev:Severity,Desc:Description}' \
  --output table

# Code Review の状態と分析行数を確認
aws codeguru-reviewer describe-code-review \
  --code-review-arn "$REVIEW_ARN" \
  --query 'CodeReview.{State:State,Lines:MetricsSummary.MeteredLinesOfCodeCount}' \
  --output json

GitHub Actions との統合 (SARIF 自動アップロード)

jobs:
  codeguru-review:
 runs-on: ubuntu-latest
 permissions:
security-events: write
id-token: write
contents: read
 steps:
- uses: actions/checkout@v4
  with:
 fetch-depth: 0
- uses: aws-actions/configure-aws-credentials@v4
  with:
 role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
 aws-region: ap-northeast-1
- uses: aws-actions/codeguru-reviewer@v1.1
  with:
 s3_bucket: codeguru-reviewer-${{ secrets.AWS_ACCOUNT_ID }}
- uses: github/codeql-action/upload-sarif@v3
  with:
 sarif_file: codeguru-results.sarif.gz

4-4. 料金と大量 PR 時のコスト爆発対策

料金体系

CodeGuru Reviewer の料金は「分析した行数」ベースだ。PR の差分行数ではなくリポジトリ全体の対象行数で計算される点に注意が必要だ。

プラン料金対象
Standard$0.50 / 100行すべてのリポジトリ
Enterprise$0.10 / 100行GitHub Enterprise + AWS Enterprise 契約

月額コスト試算 (Standard)

シナリオ A: 小規模チーム
  リポジトリ 10,000行 × 月 20 PR = $1,000/月

シナリオ B: 中規模チーム
  リポジトリ 50,000行 × 月 30 PR = $7,500/月

シナリオ C: 大規模チーム (危険水域)
  リポジトリ 200,000行 × 月 100 PR = $100,000/月

大規模リポジトリ × 高頻度 PR の組み合わせで月額数万〜数十万ドルに達する事例がある。導入前に必ずコスト試算を行うこと。

⚠️ コスト爆発対策

# AWS Budgets でアラート設定 (月 $500 上限の例)
aws budgets create-budget \
  --account-id "$AWS_ACCOUNT_ID" \
  --budget '{
 "BudgetName": "CodeGuruReviewerMonthlyBudget",
 "BudgetLimit": {"Amount": "500", "Unit": "USD"},
 "TimeUnit": "MONTHLY",
 "BudgetType": "COST",
 "CostFilters": {
"Service": ["AWS CodeGuru Reviewer"]
 }
  }' \
  --notifications-with-subscribers '[{
 "Notification": {
"ComparisonOperator": "GREATER_THAN",
"NotificationType": "ACTUAL",
"Threshold": 80,
"ThresholdType": "PERCENTAGE"
 },
 "Subscribers": [{
"Address": "ops-team@example.com",
"SubscriptionType": "EMAIL"
 }]
  }]'

コンソールでのコスト確認手順

  1. CodeGuru コンソール → ReviewerAssociated repositories
  2. 対象リポジトリを選択 → Code reviews タブ
  3. 各 Code Review の Lines of code analyzed 列で分析行数を確認
  4. AWS Cost Explorer → サービスフィルタ: CodeGuru Reviewer で月次推移監視

月次上限の設定は CodeGuru コンソール単体ではできない。AWS Budgets + Cost Anomaly Detection の組み合わせで異常コストを早期検知する運用が必須だ。

4-5. 落とし穴と対処法

落とし穴 1: 対応言語外・低精度言語で結果がゼロ件

Go や Kotlin は対応言語一覧に含まれているが、検出精度は Java/Python より大幅に低い。特に Go は「レビューは実行されたが 0 件」というケースが頻発する。非対応言語または精度が低い言語は SonarQube・Semgrep・Snyk 等の専用ツールと組み合わせること。CodeGuru Reviewer は Java/Python メインのリポジトリで最大の効果を発揮する。

落とし穴 2: GitHub Association が Pending のまま解消されない

GitHub の CodeStar Connection は Terraform Apply だけでは有効化されない。コンソールで OAuth 認証ハンドシェイクを手動実施しないと Pending 状態が続く。

# Association の State を確認する
aws codeguru-reviewer list-repository-associations \
  --query 'RepositoryAssociationSummaries[*].{Name:Name,State:State}' \
  --output table

# State: Pending → コンソールで OAuth 認証が必要
# State: Failed  → Connection ARN の誤りまたは権限不足を確認
# State: Associated → 正常 (PR 作成時にレビューが走る)

落とし穴 3: 大量 PR による意図せぬコスト増大

Feature Branch 戦略でブランチが乱立するプロジェクトでは、1日数十 PR が飛び交い月額が数万ドルに跳ね上がる。Association を解除しても既に分析済み PR の料金は取り消しできない。導入初月は必ず AWS Budgets + Cost Anomaly Detection を設定し、PR 規模の上限 (例: 500行/PR) をチームルール化することを推奨する。

落とし穴 4: 誤検知への過剰対応でレビュー文化が崩壊

CodeGuru Reviewer は機械学習ベースのため誤検知が発生する。特に社内独自フレームワークやカスタムライブラリのパターンは「コードスメル」として誤判定されやすい。PR コメントに @aws-codeguru-reviewer suppress と返信すると以降の同一パターンを抑制できる。チーム内で「Info/Low は参考情報・Critical/High のみ必須修正」のガイドラインを定め、適切な粒度でレビュー文化を維持することを推奨する。


5. CodeGuru Profiler (本番パフォーマンス分析)

fig05: CodeGuru Profiler フレームグラフ生成パイプライン

CodeGuru Profiler は本番環境で稼働中のアプリケーションの CPU/メモリ/レイテンシを継続的にサンプリングし、フレームグラフとして可視化するプロファイリングサービスです。アプリケーションコードを一切変更せずに軽量エージェントを追加するだけで、ホットスポット特定から最適化サイクルまでを自動化します。Vol3 (CodePipeline) でデプロイしたアプリケーションの本番品質を担保する補完レイヤーとして機能します。

5-1. Profiler 概要

対応ランタイムとプラットフォーム

ランタイムEC2ECS/EKSFargateLambda
Java (JVM 8+)
Python 3.6+

Lambda の場合は compute_platform = "AWSLambda" を明示しないとデータが正しく集計されません。EC2/ECS/EKS/Fargate には Default を使用します。

フレームグラフ種別

種別内容活用シーン
CPUメソッド別 CPU 使用時間の積み上げホットスポット特定・GC チューニング
Heap Summaryヒープ使用量の推移+オブジェクト分布メモリリーク検出
LatencyP50/P90/P99 レイテンシのメソッド別分布API 遅延原因の特定
CostAWS Compute コストに変換した CPU 時間コスト最適化の費用対効果算出

初回は CPU + Heap Summary から開始し、Latency は X-Ray 連携後に Cost と組み合わせて分析すると ROI が明確になります。

5-2. Profiling Group 設計

Profiling Group はプロファイルデータを集約する論理ユニットです。環境 (dev/stg/prd) × サービス単位で作成し、cross-environment 汚染を防止します。

Terraform

resource "aws_codeguruprofiler_profiling_group" "app_prd" {
  name = "${var.project_name}-${var.environment}-app"
  compute_platform = "Default"  # EC2/ECS/EKS/Fargate の場合

  agent_orchestration_config {
 profiling_enabled = true
  }

  tags = {
 Environment = var.environment
 ManagedBy= "Terraform"
  }
}

resource "aws_codeguruprofiler_profiling_group" "lambda_prd" {
  name = "${var.project_name}-${var.environment}-lambda"
  compute_platform = "AWSLambda"  # Lambda の場合は必須

  agent_orchestration_config {
 profiling_enabled = true
  }

  tags = {
 Environment = var.environment
 ManagedBy= "Terraform"
  }
}

compute_platform は作成後に変更できません。誤設定の場合はリソースを destroy して再作成してください。

AWS CLI

# EC2/ECS/Fargate 用 Profiling Group 作成
aws codeguru-profiler create-profiling-group \
  --profiling-group-name "myapp-prd-app" \
  --compute-platform Default \
  --agent-orchestration-config profilingEnabled=true \
  --tags Environment=prd

# Lambda 用 Profiling Group 作成
aws codeguru-profiler create-profiling-group \
  --profiling-group-name "myapp-prd-lambda" \
  --compute-platform AWSLambda \
  --agent-orchestration-config profilingEnabled=true

# Profiling Group 一覧確認
aws codeguru-profiler list-profiling-groups --output table

# Profiling Group の詳細確認
aws codeguru-profiler describe-profiling-group \
  --profiling-group-name "myapp-prd-app"

コンソール操作

  1. CodeGuru コンソール → 左メニュー「Profiler」→「Profiling groups」
  2. 「Create profiling group」をクリック
  3. Name: myapp-prd-app、Compute platform: Standard (= Default) を選択
  4. Agent orchestration: Profiling enabled をオン
  5. Tags: Environment=prd を追加して「Create」

5-3. エージェント設定

エージェントはアプリケーションプロセス内に埋め込まれ、デフォルトで 5 分ごとにサンプリングデータを CodeGuru Profiler へ送信します。

Java エージェント

Maven (pom.xml):

<dependency>
  <groupId>software.amazon.codeguruprofiler</groupId>
  <artifactId>codeguru-profiler-java-agent</artifactId>
  <version>2.5.2</version>
</dependency>

Gradle (build.gradle):

dependencies {
  implementation 'software.amazon.codeguruprofiler:codeguru-profiler-java-agent:2.5.2'
}

JVM 起動オプション (ECS タスク定義・EC2 起動スクリプト共通):

java \
  -javaagent:/opt/codeguru-profiler-java-agent.jar \
  -Dcom.amazonaws.codeguruprofiler.profilingGroupName=myapp-prd-app \
  -Dcom.amazonaws.codeguruprofiler.region=ap-northeast-1 \
  -jar app.jar

Python エージェント

# インストール
pip install codeguru-profiler-agent

# Lambda Layer としてパッケージ化する場合
pip install codeguru-profiler-agent -t python/lib/python3.11/site-packages/
zip -r codeguru-profiler-layer.zip python/

Lambda ハンドラへの組み込み (lambda_function.py):

from codeguru_profiler_agent import with_lambda_profiler

@with_lambda_profiler(profiling_group_name="myapp-prd-lambda")
def handler(event, context):
 return process(event)

EC2/ECS での起動 (app.py):

import codeguru_profiler_agent

profiler = codeguru_profiler_agent.Profiler(
 profiling_group_name="myapp-prd-app",
 region_name="ap-northeast-1"
)
profiler.start()
run_application()

IAM ロール設定

エージェントが CodeGuru Profiler にデータを送信するには AmazonCodeGuruProfilerAgentAccess マネージドポリシーが必要です。EC2 インスタンスプロファイル、ECS タスクロール、Lambda 実行ロールのいずれにもアタッチ可能です。

resource "aws_iam_role_policy_attachment" "codeguru_profiler_agent" {
  role = aws_iam_role.app_task.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonCodeGuruProfilerAgentAccess"
}

5-4. フレームグラフ読み方

フレームグラフは横軸が「全体 CPU 時間に占める割合」、縦軸が「コールスタックの深さ」を表します。横幅が広いフレームがホットスポットです。

Heap Summary の活用

  • Live objects count: GC 後も残存するオブジェクト数の推移 → メモリリーク検出指標
  • Allocated heap: ピーク時の割当量とその後の解放パターン → GC 頻度の評価
  • Recommendation Engine: 自動検出した最適化提案 (例: ArrayList の初期容量拡大でリサイズコストを削減)

ホットスポット特定→最適化サイクル

① CPU フレームグラフで横幅 > 5% のフレームを特定
  ↓
② Recommendation Engine の提案を確認
  ↓
③ コード修正 + Vol3 CodePipeline で自動デプロイ
  ↓
④ 「Compare profiles」で before/after スナップショット比較
  ↓
⑤ Cost フレームグラフで CPU 削減率を ROI 換算

CodeGuru Profiler はスナップショット比較機能 (「Compare profiles」) を内蔵しており、デプロイ前後の差分を視覚的に確認できます。

5-5. X-Ray 連携

X-Ray の分散トレーシングと Profiler を組み合わせることで、「どのリクエストが遅いか (X-Ray)」と「なぜ遅いか (Profiler)」を同一の観点で分析できます。X-Ray トレース ID が Profiler サンプリングデータに付与され、特定リクエストのコールスタックを遡ることができます。

# ECS タスク定義: X-Ray デーモンを sidecar として追加
aws ecs register-task-definition \
  --container-definitions '[
 {
"name": "xray-daemon",
"image": "amazon/aws-xray-daemon",
"essential": false,
"portMappings": [{"containerPort": 2000, "protocol": "udp"}]
 },
 {
"name": "app",
"environment": [
  {"name": "AWS_XRAY_DAEMON_ADDRESS", "value": "xray-daemon:2000"},
  {"name": "CODEGURU_PROFILER_GROUP_NAME", "value": "myapp-prd-app"}
]
 }
  ]'

X-Ray と Profiler を同時に有効化すると、CodeGuru コンソールの「Profiler」タブに「View in X-Ray」リンクが表示され、遅延リクエストのトレースから直接コールスタックへ遷移できます。

5-6. 落とし穴

Profiler 運用でハマる落とし穴 3 選

  • agent overhead が本番で顕在化するケース: デフォルトのサンプリングによる CPU overhead は通常 < 5% ですが、1秒以下のリクエスト処理が主体のサービスでは相対的な overhead が増大します。sampling_interval_millis を 600000 (10分) に変更するか、本番ピーク時間帯はエージェントを無効化するスケジューリングを検討してください。
  • Profiling Group 命名衝突 (環境間汚染): dev/stg/prd で同一名を使うと複数環境のプロファイルデータが混在します。必ず環境サフィックスを付加 (例: myapp-dev-app / myapp-prd-app) し、Terraform の name = "${var.project_name}-${var.environment}-app" パターンで統一してください。
  • Lambda コールドスタート影響: コールドスタート直後はエージェントの初期化で約 200ms のオーバーヘッドが発生します。Provisioned Concurrency と組み合わせる場合はウォームアップ期間のプロファイルデータを除外してください。また、compute_platform = "AWSLambda" を忘れるとデータが送信されません。

6. Terraform完全実装 (CodeArtifact Domain/Repository + CodeGuru 全HCL)

QG-4 Terraform 完全実装ハイライト (CodeArtifact + CodeGuru 統合 HCL)

  • CodeArtifact: aws_codeartifact_domain (KMS暗号化) + aws_codeartifact_repository (upstream設定) + aws_codeartifact_repository_permissions_policy
  • CodeGuru: aws_codegurureviewer_repository_association (PR自動レビュー) + aws_codeguruprofiler_profiling_group (本番プロファイリング)
  • IAM 信頼関係: codeartifact.amazonaws.com / codeguru-reviewer.amazonaws.com / codeguru-profiler.amazonaws.com の 3 サービス分を iam.tf で一元管理

6-1. ディレクトリ構成

modular 構成でサービスごとにファイルを分割し、変更影響範囲を最小化します。

terraform/
├── variables.tf # プロジェクト名/環境/リージョン/KMS Key ARN
├── codeartifact.tf # Domain / Repository / permissions_policy
├── codeguru.tf  # Reviewer association + Profiler profiling_group
├── iam.tf # 各サービス信頼関係 + マネージドポリシーアタッチ
└── outputs.tf# domain ARN / repository URL / profiling group ARN

6-2. variables.tf

variable "project_name" {
  description = "プロジェクト識別名 (リソース命名に使用)"
  type  = string
  default  = "myapp"
}

variable "environment" {
  description = "デプロイ環境 (dev / stg / prd)"
  type  = string
  default  = "prd"
}

variable "aws_region" {
  description = "AWS リージョン"
  type  = string
  default  = "ap-northeast-1"
}

variable "kms_key_arn" {
  description = "CodeArtifact Domain 暗号化用 KMS Key ARN"
  type  = string
  sensitive= true
}

variable "codestar_connection_arn" {
  description = "GitHub 連携用 AWS CodeStar Connection ARN"
  type  = string
}

variable "aws_account_id" {
  description = "AWS アカウント ID (permissions_policy で使用)"
  type  = string
}

6-3. codeartifact.tf

# Domain: 組織単位のパッケージ管理ルート
resource "aws_codeartifact_domain" "main" {
  domain= "${var.project_name}-${var.environment}"
  encryption_key = var.kms_key_arn  # KMS 暗号化必須 (省略すると AWS マネージドキー)

  tags = {
 Environment = var.environment
 ManagedBy= "Terraform"
  }
}

# npmjs.com の upstream proxy リポジトリ
resource "aws_codeartifact_repository" "npm_upstream" {
  repository = "${var.project_name}-npm-upstream"
  domain  = aws_codeartifact_domain.main.domain

  external_connections {
 external_connection_name = "public:npmjs"
  }
}

# 社内 npm レジストリ (npmjs upstream proxy 付き)
resource "aws_codeartifact_repository" "npm" {
  repository = "${var.project_name}-npm"
  domain  = aws_codeartifact_domain.main.domain

  upstream {
 repository_name = aws_codeartifact_repository.npm_upstream.repository
  }

  tags = {
 PackageFormat = "npm"
 Environment= var.environment
  }
}

# pypi.org の upstream proxy リポジトリ
resource "aws_codeartifact_repository" "pypi_upstream" {
  repository = "${var.project_name}-pypi-upstream"
  domain  = aws_codeartifact_domain.main.domain

  external_connections {
 external_connection_name = "public:pypi"
  }
}

# 社内 PyPI レジストリ (pypi upstream proxy 付き)
resource "aws_codeartifact_repository" "pypi" {
  repository = "${var.project_name}-pypi"
  domain  = aws_codeartifact_domain.main.domain

  upstream {
 repository_name = aws_codeartifact_repository.pypi_upstream.repository
  }

  tags = {
 PackageFormat = "pypi"
 Environment= var.environment
  }
}

# Repository レベルの permissions policy (CodeBuild からの publish 許可)
resource "aws_codeartifact_repository_permissions_policy" "npm" {
  repository= aws_codeartifact_repository.npm.repository
  domain = aws_codeartifact_domain.main.domain

  policy_document = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Sid = "AllowCodeBuildRead"
  Effect = "Allow"
  Principal = {
 AWS = aws_iam_role.codebuild_role.arn
  }
  Action = [
 "codeartifact:GetAuthorizationToken",
 "codeartifact:ReadFromRepository",
 "codeartifact:GetRepositoryEndpoint"
  ]
  Resource = "*"
},
{
  Sid = "AllowPublish"
  Effect = "Allow"
  Principal = {
 AWS = "arn:aws:iam::${var.aws_account_id}:root"
  }
  Action= ["codeartifact:PublishPackageVersion", "codeartifact:PutPackageMetadata"]
  Resource = "*"
}
 ]
  })
}

6-4. codeguru.tf

# CodeGuru Reviewer: CodeCommit リポジトリ連携
# GitHub/Bitbucket の場合は var.codestar_connection_arn を使用する
resource "aws_codegurureviewer_repository_association" "main" {
  repository {
 codecommit {
name = "${var.project_name}-${var.environment}"
 }
  }

  tags = {
 Environment = var.environment
 ManagedBy= "Terraform"
  }
}

# CodeGuru Profiler: EC2/ECS/Fargate 用
resource "aws_codeguruprofiler_profiling_group" "app" {
  name = "${var.project_name}-${var.environment}-app"
  compute_platform = "Default"

  agent_orchestration_config {
 profiling_enabled = true
  }

  tags = {
 Environment = var.environment
 ManagedBy= "Terraform"
  }
}

# CodeGuru Profiler: Lambda 用
resource "aws_codeguruprofiler_profiling_group" "lambda" {
  name = "${var.project_name}-${var.environment}-lambda"
  compute_platform = "AWSLambda"

  agent_orchestration_config {
 profiling_enabled = true
  }

  tags = {
 Environment = var.environment
 ManagedBy= "Terraform"
  }
}

6-5. iam.tf

# CodeBuild 用 IAM ロール (CodeArtifact Token 取得権限)
resource "aws_iam_role" "codebuild_role" {
  name = "${var.project_name}-${var.environment}-codebuild"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "codebuild.amazonaws.com" }
Action = "sts:AssumeRole"
 }]
  })
}

resource "aws_iam_role_policy" "codeartifact_read" {
  name = "CodeArtifactRead"
  role = aws_iam_role.codebuild_role.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Effect = "Allow"
  Action = [
 "codeartifact:GetAuthorizationToken",
 "codeartifact:GetRepositoryEndpoint",
 "codeartifact:ReadFromRepository"
  ]
  Resource = "*"
},
{
  Effect= "Allow"
  Action= "sts:GetServiceBearerToken"
  Resource = "*"
  Condition = {
 StringEquals = {
"sts:AWSServiceName" = "codeartifact.amazonaws.com"
 }
  }
}
 ]
  })
}

# CodeGuru Reviewer 用 IAM ロール
resource "aws_iam_role" "codeguru_reviewer" {
  name = "${var.project_name}-${var.environment}-codeguru-reviewer"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "codeguru-reviewer.amazonaws.com" }
Action = "sts:AssumeRole"
 }]
  })
}

resource "aws_iam_role_policy_attachment" "codeguru_reviewer_full" {
  role = aws_iam_role.codeguru_reviewer.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonCodeGuruReviewerFullAccess"
}

# ECS タスクロール (CodeGuru Profiler エージェント用)
resource "aws_iam_role" "app_task" {
  name = "${var.project_name}-${var.environment}-app-task"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "ecs-tasks.amazonaws.com" }
Action = "sts:AssumeRole"
 }]
  })
}

resource "aws_iam_role_policy_attachment" "codeguru_profiler_agent" {
  role = aws_iam_role.app_task.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonCodeGuruProfilerAgentAccess"
}

6-6. outputs.tf

output "codeartifact_domain_arn" {
  description = "CodeArtifact Domain ARN"
  value = aws_codeartifact_domain.main.arn
}

output "npm_repository_url" {
  description = "npm リポジトリエンドポイント URL"
  value = aws_codeartifact_repository.npm.repository_endpoint
}

output "pypi_repository_url" {
  description = "PyPI リポジトリエンドポイント URL"
  value = aws_codeartifact_repository.pypi.repository_endpoint
}

output "app_profiling_group_arn" {
  description = "アプリケーション用 Profiling Group ARN"
  value = aws_codeguruprofiler_profiling_group.app.arn
}

output "lambda_profiling_group_arn" {
  description = "Lambda 用 Profiling Group ARN"
  value = aws_codeguruprofiler_profiling_group.lambda.arn
}

output "codeguru_reviewer_association_id" {
  description = "CodeGuru Reviewer リポジトリ関連付け ID"
  value = aws_codegurureviewer_repository_association.main.id
}

6-7. Terraform/CLI/コンソール 3点セット まとめ

操作TerraformAWS CLIコンソール
Domain 作成aws_codeartifact_domainaws codeartifact create-domainCodeArtifact → Domains → Create
Repository 作成aws_codeartifact_repositoryaws codeartifact create-repositoryDomains → Repositories → Create
Permissions Policy 設定aws_codeartifact_repository_permissions_policyaws codeartifact put-repository-permissions-policyRepository → Edit Policy
Reviewer 連携aws_codegurureviewer_repository_associationaws codeguru-reviewer associate-repositoryCodeGuru → Reviewer → Associate
Profiling Group 作成aws_codeguruprofiler_profiling_groupaws codeguru-profiler create-profiling-groupCodeGuru → Profiler → Create
Token 取得aws codeartifact get-authorization-token— (CLI のみ)
# Terraform デプロイ手順
cd terraform/
terraform init
terraform plan -var-file=prd.tfvars
terraform apply -var-file=prd.tfvars

# デプロイ後: npm 認証設定 (CI/CD パイプラインの buildspec に組込)
DOMAIN_NAME=$(terraform output -raw codeartifact_domain_arn | awk -F'/' '{print $NF}')
OWNER=$(aws sts get-caller-identity --query Account --output text)
TOKEN=$(aws codeartifact get-authorization-token \
  --domain "${DOMAIN_NAME}" \
  --domain-owner "${OWNER}" \
  --query authorizationToken \
  --output text)
NPM_URL=$(terraform output -raw npm_repository_url)

npm config set registry "${NPM_URL}"
npm config set //${NPM_URL#https://}:_authToken "${TOKEN}"

コンソール確認手順:

  1. CodeArtifact コンソール → Domains → myapp-prd → Repositories → myapp-npm → 「View connection instructions」でパッケージマネージャ別の認証コマンドを自動生成
  2. CodeGuru コンソール → Profiler → myapp-prd-app → 「Profiling data」タブでフレームグラフを確認
  3. IAM コンソール → Roles → myapp-prd-app-taskAmazonCodeGuruProfilerAgentAccess のアタッチ状況を確認

7. Bedrock Agents との比較・使い分け

fig06: CodeGuru vs Bedrock Agents 使い分けフロー

7-1. CodeGuru Reviewer vs Bedrock Agents — 根本的な違い

AWS の AI サービスには「静的解析特化の CodeGuru」と「汎用 LLM の Bedrock Agents」という 2 つのアプローチが存在する。同じ「コード品質改善」という文脈でも、両者は設計思想から根本的に異なる。

CodeGuru Reviewer: ルールベースの静的解析 AI

  • 事前学習済みのセキュリティ/品質ルール (CWE/OWASP/Best Practices) を適用
  • 同じコードに対して常に同じ結果を返す決定論的 (Deterministic) 動作
  • PR 単位でトリガー・開発者へのコメント自動投稿に特化
  • 対応言語: Java/Python/JavaScript/TypeScript/C#/Ruby/Go/Kotlin/Scala/Swift/PHP の 11言語
  • 料金: Standard $0.50/100行・Enterprise $0.10/100行

Bedrock Agents: 汎用 LLM ベースの AI エージェント

  • Claude/Titan 等の Foundation Model をベースとした生成 AI
  • コンテキストに応じた柔軟な応答・コード生成・複数ツール連携が可能
  • 非決定論的 (Non-Deterministic): 同じ入力でも確率的に結果が変わり得る
  • 対応言語: Foundation Model が理解できる任意の言語 (事実上制限なし)
  • 料金: invoke 単位 (入出力トークン × モデル単価)
比較軸CodeGuru ReviewerBedrock Agents
設計思想ルールベース静的解析汎用 LLM エージェント
動作特性決定論的・確定的非決定論的・確率的
主な用途PR コードレビュー自動化任意タスク自動化/対話型
コード生成不可 (指摘のみ)可 (任意コード生成)
多言語対応11言語固定事実上無制限
トリガーPR イベントAPI call / イベント
即時性PR 受付後数分以内invoke 遅延あり (LLM 推論)
セットアップリポジトリ関連付けのみAction Group + Lambda 設計必要
運用コスト低 (ルール更新不要)中 (プロンプト/Agent 設計要管理)

CodeGuru Reviewer は 「何を検出するかが明確に定義されている」 領域で圧倒的な安定性を発揮する。一方で Bedrock Agents は 「何をすべきかを柔軟に決定できる」 領域で真価を発揮する。

7-2. 料金比較と月次コスト試算

CodeGuru Reviewer 料金体系

CodeGuru Reviewer は分析したコード行数に基づく課金モデルを採用している。

プラン単価月 200 PR・平均 300行/PR の場合
Standard$0.50 / 100行$300/月
Enterprise$0.10 / 100行$60/月
# 月次コスト試算 (Standard プラン)
pr_per_month = 200 # PR 数
avg_lines_per_pr = 300# 平均変更行数
unit_cost_per_100_lines = 0.50  # Standard 料金

monthly_cost = pr_per_month * avg_lines_per_pr / 100 * unit_cost_per_100_lines
# = 200 * 300 / 100 * 0.50 = $300/月

# Enterprise プランなら
monthly_cost_enterprise = 200 * 300 / 100 * 0.10  # = $60/月

注意: PR 1件あたりの課金対象は「変更されたコード行数」ではなく「リポジトリ内の全コード行数」となる場合がある (最新料金は AWS 公式ページを要確認)。大規模リポジトリでは Enterprise プランの検討が必須。

Bedrock Agents 料金体系

Bedrock Agents の料金は使用する Foundation Model のトークン単価に依存する。

Foundation Model入力トークン単価出力トークン単価
Claude 3 Haiku$0.25 / 1M トークン$1.25 / 1M トークン
Claude 3 Sonnet$3.00 / 1M トークン$15.00 / 1M トークン
Claude 3 Opus$15.00 / 1M トークン$75.00 / 1M トークン
# コードレビュー 1回あたりの試算 (Claude 3 Haiku 使用)
# 入力: システムプロンプト(1,000) + コード(2,000) = 3,000 トークン
# 出力: レビュー結果(1,500 トークン)

input_cost  = 3000 / 1_000_000 * 0.25# $0.00075
output_cost = 1500 / 1_000_000 * 1.25# $0.001875
total_per_call = input_cost + output_cost  # $0.002625/回

# 月 200 回呼び出しなら
monthly_cost = 200 * 0.002625  # $0.525/月

少量呼び出しであれば Bedrock Agents の方が大幅に安価になる。ただし、Bedrock Agents はセットアップ・プロンプト設計・運用保守コストを含めたトータル TCO での比較が重要。

7-3. 統合パターン: Bedrock Agents から CodeGuru API を呼び出す

Bedrock Agents と CodeGuru は「競合」ではなく「相互補完」として活用できる。Bedrock Agents の Action Group に CodeGuru Reviewer API を組み込むことで、AI が「まず静的解析 (CodeGuru) を実行 → 結果をコンテキストとして LLM で高度な分析・説明文生成」という高度なワークフローを実現できる。

参照: Bedrock Agents 本番運用ガイド

アーキテクチャ概要

[開発者] → PR 作成
 ↓
[CodeGuru Reviewer] → 静的解析・CWE/OWASP 検出
 ↓ 検出結果 (JSON)
[Bedrock Agent Action Group]
 ↓ Lambda で CodeGuru API → 解析結果取得
[Foundation Model (Claude)]
 ↓ 人間が読みやすいレビューコメント生成
 ↓ 修正案コード生成
[PR コメント] ← 自動投稿

Terraform 実装 (Bedrock Agent + CodeGuru 統合 Lambda)

resource "aws_lambda_function" "codeguru_action" {
  function_name = "${var.project}-codeguru-action"
  runtime = "python3.12"
  handler = "handler.lambda_handler"
  role = aws_iam_role.codeguru_action_role.arn
  filename= data.archive_file.codeguru_action.output_path

  environment {
 variables = {
REGION = var.aws_region
 }
  }
}

resource "aws_iam_role_policy" "codeguru_action_policy" {
  name = "${var.project}-codeguru-action-policy"
  role = aws_iam_role.codeguru_action_role.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Action = [
  "codeguru-reviewer:ListCodeReviews",
  "codeguru-reviewer:DescribeCodeReview",
  "codeguru-reviewer:ListRecommendations"
]
Resource = "*"
 }]
  })
}

Lambda ハンドラ (Python)

import boto3
import json

def lambda_handler(event, context):
 """Bedrock Agent Action Group: CodeGuru 検出結果取得"""
 action  = event.get("actionGroup")
 function= event.get("function")
 parameters = {p["name"]: p["value"] for p in event.get("parameters", [])}

 if function == "get_code_review_results":
  pull_request_id = parameters.get("pull_request_id")

  reviewer_client = boto3.client("codeguru-reviewer")
  reviews = reviewer_client.list_code_reviews(
Type="PullRequest",
States=["Completed"]
  )

  results = []
  for review in reviews["CodeReviewSummaries"]:
if pull_request_id in review.get("PullRequestId", ""):
 recs = reviewer_client.list_recommendations(
  CodeReviewArn=review["CodeReviewArn"]
 )
 results.extend(recs["RecommendationSummaries"])

  response_body = {"TEXT": {"body": json.dumps(results, ensure_ascii=False)}}
  return {
"actionGroup": action,
"function": function,
"functionResponse": {"responseBody": response_body}
  }

このパターンにより、Bedrock Agent は CodeGuru の機械的な検出結果を「開発者が理解しやすい説明文」や「具体的な修正コード提案」に変換できる。両者の強みを組み合わせた次世代レビューパイプラインとして機能する。

AWS CLI での動作確認

# Bedrock Agent を呼び出して CodeGuru 統合レビューを実行
aws bedrock-agent-runtime invoke-agent \
  --agent-id "${BEDROCK_AGENT_ID}" \
  --agent-alias-id "${BEDROCK_AGENT_ALIAS_ID}" \
  --session-id "pr-review-$(date +%s)" \
  --input-text "PR #42 のコードレビュー結果を取得して改善提案を日本語でまとめて" \
  --output json \
  | jq -r '.completion'

# CodeGuru Reviewer のレビュー状況を直接確認
aws codeguru-reviewer list-code-reviews \
  --type PullRequest \
  --states Completed \
  --query 'CodeReviewSummaries[*].{Name:Name,State:State,PRId:PullRequestId}' \
  --output table

7-4. 選定フロー — どちらを使うべきか

以下のフローで技術選定を行うことを推奨する。

新たな「コード品質改善」ニーズが発生
 ↓
Q1: 要件は「決まったルールでの静的チェック」か?
 │
 ├─ Yes → CodeGuru Reviewer が第一候補
 ││
 │├─ 対応 11言語内? → Yes → CodeGuru Reviewer 採用
 │└─ 11言語外? → Bedrock Agents (LLM でルール適用)
 │
 └─ No (カスタム/対話型ニーズ)
  ↓
 Q2: 「コードの説明・任意変換・自然言語での質問応答」が必要か?
  │
  ├─ Yes → Bedrock Agents
  └─ No → 要件を再整理

本番パフォーマンス最適化ニーズ
 → CodeGuru Profiler (フレームグラフ・Java/Python・実行時プロファイリング)

3サービス使い分けサマリ

ニーズ推奨サービス理由
PR の脆弱性・コードスメル自動検出CodeGuru Reviewerルールベース・確定的・PR統合
本番 Lambda/ECS の CPU ホットスポット解析CodeGuru Profilerフレームグラフ・エージェント型
カスタム質問応答・コード生成・説明文生成Bedrock Agents汎用LLM・柔軟な応答
CodeGuru 結果を人間向けに要約・説明Bedrock Agents + CodeGuru 統合両者の強みを組み合わせ
11言語外のコードレビュー自動化Bedrock Agents言語制限なし
コスト最小化 (大量PR・大規模リポジトリ)CodeGuru Reviewer Enterprise$0.10/100行

8. シリーズ完結まとめ + Vol1-4 チートシート + よくある落とし穴10選

【QG-5】aws-code-family シリーズ完結 — Vol1-4 通読で得られる本番運用パイプラインの完成像

  • Vol1 (サービス選定): AWS Code* vs GHA vs ecspresso の選定軸を習得 → 適材適所の基準を確立
  • Vol2 (CodeBuild): ビルド環境の Terraform 完全実装・VPC 統合・マルチアーキテクチャ対応
  • Vol3 (CodePipeline V2 + CodeDeploy): Blue/Green デプロイ・Canary デプロイ・本番ロールバック
  • Vol4 (本記事・完結): 社内パッケージ管理 (CodeArtifact) + コード品質/パフォーマンス (CodeGuru) を補完運用として統合
  • AI×CI/CD 選定軸: 定型レビュー → CodeGuru Reviewer / カスタムロジック → Bedrock Agents / 本番プロファイリング → CodeGuru Profiler
  • シリーズ完結後の次の一手: 本 Vol1-4 パイプラインに Bedrock Agents を組み込み、AI 駆動の自律型 CI/CD へと発展させることが可能

8-1. シリーズ完結宣言

本記事 Vol4 をもって、aws-code-family シリーズ全4巻が完結した。

Vol1 でサービス選定の軸を確立し、Vol2 で CodeBuild によるビルド基盤を構築、Vol3 で CodePipeline V2 + CodeDeploy による本番デプロイパイプラインを実装、そして Vol4 (本記事) で CodeArtifact による社内パッケージ管理と CodeGuru による継続的なコード品質・パフォーマンス改善を補完運用として追加した。これにより、設計 → ビルド → デプロイ → 品質保証 → パッケージ管理というエンタープライズ CI/CD パイプラインの全ライフサイクルが一本の Terraform コードベースで実現できる。

8-2. Vol1-4 チートシート

aws-code-family シリーズ各 Volume の主要 Terraform リソースと AWS CLI ワンライナーをまとめる。

Volume主要 Terraform リソースAWS CLI ワンライナー
Vol1 (選定)aws_iam_role / aws_iam_policyaws codepipeline list-pipelines
Vol2 (CodeBuild)aws_codebuild_project / aws_codebuild_source_credentialaws codebuild start-build --project-name ${PROJECT}
Vol3 (Pipeline+Deploy)aws_codepipeline / aws_codedeploy_deployment_groupaws codepipeline start-pipeline-execution --name ${PIPELINE}
Vol4 (Artifact+Guru)aws_codeartifact_domain / aws_codeartifact_repository / aws_codeguruprofiler_profiling_groupaws codeartifact get-authorization-token --domain ${DOMAIN} --query authorizationToken --output text
# Vol1: パイプライン一覧確認
aws codepipeline list-pipelines --output table

# Vol2: CodeBuild ビルド手動実行
aws codebuild start-build \
  --project-name my-build-project \
  --query 'build.{id:id,status:buildStatus}' \
  --output table

# Vol3: CodePipeline 手動実行
aws codepipeline start-pipeline-execution \
  --name my-pipeline \
  --query 'pipelineExecutionId' \
  --output text

# Vol4: CodeArtifact Token 取得 (CI 環境で毎回実行)
export CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token \
  --domain my-domain \
  --domain-owner "$(aws sts get-caller-identity --query Account --output text)" \
  --query authorizationToken \
  --output text)

8-3. よくある落とし穴10選

本シリーズ Vol1-4 を通じて遭遇しやすいトラップを集約する。

1. CodeArtifact Token の12時間期限切れ
CodeArtifact の認証トークンはデフォルト12時間で失効する。長時間稼働する CodeBuild ジョブや夜間バッチ内でトークンを再取得しないと認証エラーが発生する。buildspec.ymlpre_build フェーズで毎回取得する設計が必須。

2. upstream proxy 設定漏れで public registry に直接アクセス
upstream を設定しないと、CI が CodeArtifact を経由せず npmjs.org/pypi.org へ直接アクセスし続ける。--upstreams upstreamRepositoryName=public-npmjs-com を忘れずに設定。

3. CodeArtifact Domain の KMS 暗号化漏れ
aws_codeartifact_domainencryption_key を省略するとデフォルト暗号化になる。セキュリティポリシーでカスタム KMS キー必須の環境では Terraform 適用後に差分が発生し続ける。

4. CodeGuru Reviewer 大量 PR でコスト爆発
Standard プランで大規模リポジトリ (10万行超) に大量の PR をレビューすると月額数千ドルになる可能性がある。Enterprise プランへの切り替えや、対象ブランチ/リポジトリの絞り込みが必要。

5. CodeGuru Profiler agent の本番性能影響
Profiler エージェントはサンプリングにより CPU オーバーヘッドが発生する (通常 1-5%)。高スループット Lambda 関数では compute_platform = "AWSLambda" を指定し、サンプリング率を調整すること。

6. Profiling Group の命名衝突 (環境間)
aws_codeguruprofiler_profiling_group のリソース名はグローバル一意ではなくアカウント+リージョン内で一意。${var.env}-${var.project}-profiler のような命名規則で dev/stg/prod を区別しないと競合する。

7. CodeArtifact Repository の permissions policy 漏れ
aws_codeartifact_repository_permissions_policy を設定しないと、他チームの IAM ロールからリポジトリへのアクセスができない。クロスアカウント共有の場合は特に codeartifact:GetAuthorizationToken を明示的に許可する必要がある。

8. CodeGuru Reviewer の対応言語外で結果ゼロ
Go/Kotlin 等の言語は対応しているが、Swift/PHP は 2024年時点でサポートが限定的。対応外の言語主体のリポジトリでは Reviewer を有効化しても検出件数がゼロとなり、コスト対効果が著しく低下する。

9. Bedrock と CodeGuru の使い分け軸を曖昧に運用
「AI でコードレビューしたい」という曖昧な要件で両サービスを併用するとコストが二重になる。§7 の選定フローを参考に、「定型ルール適用 → CodeGuru Reviewer」「カスタム分析/説明文生成 → Bedrock Agents」と明確に分担すること。

10. Vol1-4 の通読なしに Vol4 だけを導入
CodeArtifact/CodeGuru は CodeBuild (Vol2) や CodePipeline (Vol3) と統合して初めて真価を発揮する。Vol4 単独での導入は設定の複雑さを増すだけになりやすい。Vol2/Vol3 の基盤が整った後に Vol4 を追加するロードマップを推奨する。

8-4. シリーズ完結後の歩み方

本シリーズを通読した読者は、以下のロードマップで本番運用品質の AWS CI/CD パイプラインを実現できる。

Week 1-2: Vol1 (サービス選定)
  → AWS Code* / GHA / ecspresso のどれを使うべきか判断軸を確立

Week 3-4: Vol2 (CodeBuild)
  → ビルド環境の Terraform 完全実装・マルチアーキテクチャ対応

Week 5-6: Vol3 (CodePipeline V2 + CodeDeploy)
  → Blue/Green + Canary デプロイ・本番ロールバック自動化

Week 7-8: Vol4 (本記事・CodeArtifact + CodeGuru)
  → 社内パッケージ管理 + コード品質/パフォーマンス継続改善

Week 9+: AI 拡張フェーズ (発展)
  → Bedrock Agents を Action Group で CodeGuru と統合
  → AI 駆動コードレビュー + 自律型 CI/CD パイプラインへ

本シリーズは AWS仕様の変更に応じて随時更新する予定だが、Terraform リソース名や CLI オプションは AWS 公式ドキュメントで常に最新版を確認することを推奨する。Vol1-4 を通じて本番運用 CI/CD パイプラインを構築・運用する全エンジニアのご健闘を祈る。

Vol1: シリーズ起点 – 全体像+選定
Vol2: CodeBuild 完全活用
Vol3: CodePipeline V2 + CodeDeploy