infra-as-code-review について
infra-as-code-reviewは、Infrastructure as Codeを体系的にレビューするスキルです。クラウド構成を管理するエンジニアリングチーム向けに、重大度別の指摘と修正案、再利用可能なチェックリストを作成し、コードがない場合はチェックリストとレポートのテンプレートを提示します。
主な機能
- 01IaCのセキュリティと信頼性の問題を確認
- 02重大度別に指摘を整理
- 03修正案とコード例を提示
- 0412のインフラレビュー分野を網羅
- 05再利用可能なIaCチェックリストを作成
活用シーン
- 01インフラコード変更のレビュー
- 02IaCプルリクエストのセキュリティ確認
- 03コードがない場合のレビュー用テンプレート作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mohitagw15856/ pm-claude-skills --skill infra-as-code-reviewインストール後、Claude Code で/infra-as-code-reviewを入力して読み込まれたか確認します。
詳細
Infrastructure-as-Code のレビュー
特定の IaC コードを対象に、セキュリティ、信頼性、運用品質の基準を適用した、体系的な Infrastructure-as-Code レビューを作成します。出力には 2 つの目的があります。対象コードに対する実用的なレビュー報告書(重大度ごとの指摘と具体的な修正手順を含む)と、チームが今後のすべての IaC 変更に適用できる再利用可能なチェックリストです。ユーザーが実際のコードを提示した場合はそれを分析し、指摘事項の表に実際の問題を記載します。コードが提示されていない場合は、チェックリストと指摘事項報告書のテンプレートを作成します。
必要な入力
すでに提示されていない場合は、以下を確認します。
- IaC ツール — Terraform、CloudFormation、Pulumi、Ansible、または CDK
- クラウドプロバイダー — AWS、GCP、Azure、またはマルチクラウド
- コードでプロビジョニングするもの — 概要(例:「決済サービス用の VPC、EKS クラスター、RDS インスタンス」)
- 適用中のセキュリティポリシーまたは命名標準 — 確認対象となる既存の組織標準。なければ妥当なデフォルトを使用します
- IaC コード自体 — 貼り付けるか、説明してください。提示されていない場合は、チェックリストのテンプレートのみを作成し、指摘事項の確認にはコードが必要であることを明記します
出力形式
IaC レビュー報告書:[プロビジョニング対象]
レビュー担当者: [氏名 / Claude] IaC ツール: [Terraform / CloudFormation / Pulumi / Ansible / CDK] クラウドプロバイダー: [AWS / GCP / Azure] コードの場所: [リポジトリのパスまたは PR のリンク] レビュー日: [日付] 全体的なリスク: [Critical / High / Medium / Low]
エグゼクティブサマリー
| 重大度 | 指摘件数 | このレビューで解決 | 持ち越しリスク |
|---|---|---|---|
| Critical | [n] | [n] | [Yes/No — 説明] |
| High | [n] | [n] | [Yes/No — 説明] |
| Medium | [n] | [n] | [Yes/No — 説明] |
| Low | [n] | [n] | [Yes/No — 説明] |
| 合計 | [n] | [n] |
推奨事項: [承認 / 必須の変更を条件に承認 / 却下 — 理由を 1 文で記載]
指摘事項
Critical の指摘事項
CRIT-01:[指摘のタイトル]
| 項目 | 詳細 |
|---|---|
| 重大度 | Critical |
| カテゴリ | [IAM / シークレット / 暗号化 / ネットワーク / 状態 / 命名 / コスト] |
| リソース | [resource_type.resource_name] |
| ファイル / 行 | [path/to/file.tf:42] |
| リスク | [起こりうる問題 — 攻撃経路や障害モードを具体的に記載] |
現在のコード:
# [paste the problematic snippet]
resource "aws_s3_bucket" "data" {
bucket = "my-bucket"
acl = "public-read" # PROBLEM: public read access
}
修正方法:
resource "aws_s3_bucket" "data" {
bucket = "my-bucket"
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
重要な理由: [データ漏えいやコンプライアンス違反など、具体的なリスクとビジネスへの影響を結び付ける 1 文]
CRIT-02:[次の Critical の指摘 — 同じ構成を繰り返す]
High の指摘事項
HIGH-01:[指摘のタイトル]
| 項目 | 詳細 |
|---|---|
| 重大度 | High |
| カテゴリ | [カテゴリ] |
| リソース | [resource_type.resource_name] |
| ファイル / 行 | [path/to/file.tf:line] |
| リスク | [具体的なリスクの説明] |
現在のコード:
# [problematic snippet]
修正方法:
# [fixed snippet]
Medium の指摘事項
MED-01:[指摘のタイトル]
| 項目 | 詳細 |
|---|---|
| 重大度 | Medium |
| カテゴリ | [カテゴリ] |
| リソース | [resource_type.resource_name] |
| ファイル / 行 | [path/to/file.tf:line] |
| リスク | [具体的なリスクの説明] |
修正方法: [この指摘にとって分かりやすい方を選び、文章またはコードスニペットで記載]
Low の指摘事項
LOW-01:[指摘のタイトル]
| 項目 | 詳細 |
|---|---|
| 重大度 | Low |
| カテゴリ | [カテゴリ] |
| リソース | [resource_type.resource_name] |
| ファイル / 行 | [path/to/file.tf:line] |
| 提案 | [改善すべき点とその理由] |
再利用可能な IaC レビューのチェックリスト
すべての IaC プルリクエストでこのチェックリストを使用します。各項目を確認し、プロビジョニングするリソースに実際に該当しない場合に限り、「該当なし」とします。
1. IAM とアクセス制御
- IAM ポリシーにワイルドカードアクション(
"*")がありません。ポリシーは最小権限の原則に従っています - コメントで明示的に正当化されている場合を除き、IAM ポリシーにワイルドカードリソース(
"*")がありません - IAM ロールでは条件キーを使用してスコープを制限しています(例:
aws:RequestedRegion、sts:ExternalId) - IAM アクセスキーや認証情報がハードコードされたり、平文の変数に含まれたりしていません
- EC2/コンピューティングインスタンスでは、ハードコードされた認証情報ではなくインスタンスプロファイルを使用しています
- バケットが明示的にパブリックアセット用である場合を除き、S3 バケットポリシーでパブリックアクセスを許可していません
- クロスアカウント信頼ポリシーでは、
"*"ではなく特定のアカウント ID を指定しています - サービスアカウント(GCP)/マネージド ID(Azure)は命名規則に従い、用途が文書化されています
2. シークレット管理
-
.tf、.yaml、.jsonファイルに、シークレット、パスワード、トークン、API キーが平文で含まれていません - 変数のデフォルト値にシークレットが含まれていません
- シークレットは Secrets Manager/Parameter Store/Vault から取得しており、プランの実行時に渡される環境変数から取得していません
- シークレットを含むすべての出力値と変数に
sensitive = trueが設定されています(Terraform) - ステートのバックエンドは暗号化されています。機密データを含む暗号化されていないステートファイルはありません
-
.gitignoreまたは同等の設定で、*.tfvars、terraform.tfstate、および解決済みのシークレットを含む可能性があるすべてのファイルを除外しています
3. 保存データの暗号化
- ストレージリソース(S3、EBS、RDS、DynamoDB、GCS、Azure Blob)で保存データの暗号化が有効になっています
- ポリシーで必要とされる場合は、AWS/GCP/Azure のマネージドキーだけに頼らず、カスタマー管理キー(CMK/KMS)を使用しています
- すべての CMK で KMS キーのローテーションが有効になっています
- データベースのスナップショットで暗号化が有効になっています
-
encrypted = falseまたは同等の設定で暗号化が無効にされていません
4. 転送中の暗号化
- ロードバランサーで TLS を終端しています。HTTP 専用リスナーは HTTPS にリダイレクトされるか、存在しません
- TLS の最小バージョンは 1.2 です。TLS 1.0 と 1.1 は明示的に無効化されています
- RDS/データベース接続で SSL が必須になっています(
require_ssl = trueまたは同等のパラメーター) - ネットワークが完全にプライベートではない場合、内部サービス間の呼び出しに TLS を使用しています
- S3 バケットポリシーに、TLS 以外のリクエストを拒否する
Deny(aws:SecureTransport: false)が含まれています
5. ネットワークとパブリックアクセス
- パブリック向けサービスのポート 80/443 を除き、セキュリティグループ/ファイアウォールルールで
0.0.0.0/0からのインバウンドを許可していません - SSH(ポート 22)と RDP(ポート 3389)を
0.0.0.0/0に公開していません - データベースはプライベートサブネットに配置され、インターネットから直接ルーティング可能ではありません
- 明示的に必要とされ、文書化されている場合を除き、RDS インスタンスで
publicly_accessible = falseに設定されています - VPC でフローログが有効になっています
- ネットワーク ACL とセキュリティグループを多層化しています(多層防御)
- アカウントレベルとバケットレベルの両方で S3 のパブリックアクセスブロックが有効になっています
6. ログ、監視、監査
- すべてのリージョンで CloudTrail/Cloud Audit Logs/Azure Monitor が有効になっています
- 機密データまたは規制対象データを含むバケットで、S3 アクセスログが有効になっています
- RDS 拡張モニタリングまたは同等の機能が有効になっています
- 重要なメトリクス(CPU、ディスク、エラー率)に対して、CloudWatch アラームまたは同等のアラームが定義されています
- ログの保持期間が定義されています。ログが無期限に保持されたり、7 日以内に削除されたりすることはありません
7. 命名とタグ付けの標準
- すべてのリソースがチームの命名規則に従っています:
[env]-[team]-[resource-type]-[identifier] - タグ付け可能なすべてのリソースに必須タグが設定されています:
-
Environment(例:prod/staging/dev) -
TeamまたはOwner -
ServiceまたはApplication -
CostCenter(財務ポリシーで必要な場合) -
ManagedBy: terraform(または同等の IaC ツールタグ)
-
- デフォルト名のリソース(例:
default-vpc、launch-wizard-1)がありません
8. 状態管理とバックエンド
- リモート状態バックエンドが設定されている — リポジトリ内にローカル状態がない
- 状態バックエンドがロックを使用している(S3 バックエンドには DynamoDB など)
- 状態バックエンドのバケット/ストレージでバージョニングが有効になっている
- 状態バックエンドのバケット/ストレージでアクセスログが有効になっている
- 環境ごとにワークスペースまたは個別の状態ファイルが使用されている — 本番と非本番で状態を共有していない
-
terraform.tfstateと*.tfstate.backupが.gitignoreに含まれている
9. モジュールとリソースの構造
- モジュールは明示的なバージョンピンでバージョン管理されている — 浮動的な
source = "git::...?ref=main"がない - プロバイダーバージョンが
required_providersでピン留めされている — 制約のない>= x.yがない - Terraform のバージョンが
required_versionでピン留めされている - モジュールは明確に単一の責務を持っている — すべてをプロビジョニングする 1 つのモジュールになっていない
- コピー&ペーストによる重複がない — 繰り返しパターンはモジュールやループ(
for_each、count)を使用している - 出力は下流の利用者が必要とするものだけを公開している — 不要な出力の乱立がない
10. 環境のパリティ
- 本番と非本番の環境が同じモジュールコードを使用し、環境変数でパラメーター化されている
- インスタンスサイズとレプリカ数は変数によって環境ごとに異なる — 別々のコード分岐によるものではない
- 非本番で「コスト削減のため」にセキュリティ制御が無効化されていない(暗号化オフ、ログオフ)
11. コストへの影響
- 大きなインスタンスタイプ(例:
r5.16xlarge)やストレージ割り当てはコメントで正当化されている - クロスリージョンまたはクロス AZ アーキテクチャではデータ転送コストが考慮されている
- 長期間稼働するリソースについて、リザーブドインスタンスまたはコミットメント利用割引の対象可否が記載されている
- 変動するワークロードに対して自動スケーリングが設定されている — スパイクのあるトラフィックに対して固定の過大なフリートがない
- 期間限定のデータ(ログ、バックアップ)を保存する S3 バケットにライフサイクルポリシーが設定されている
12. ドリフトのリスク
- コンソールで頻繁に変更されるリソースが、インポートのドキュメントなしに IaC で管理されていない
- 本番のステートフルなリソース(データベース、状態バケット)に
lifecycle { prevent_destroy = true }が設定されている -
ignore_changesは慎重に使用され、各インスタンスには根拠を示すコメントが記載されている - PR プロセスの一環として、稼働中の環境に対して plan が実行されている — レビューされていないドリフトがない
検出事項のサマリーテーブル
| ID | タイトル | 重大度 | カテゴリ | ファイル | ステータス |
|---|---|---|---|---|---|
| CRIT-01 | [タイトル] | Critical | [カテゴリ] | [file:line] | Open |
| HIGH-01 | [タイトル] | High | [カテゴリ] | [file:line] | Open |
| MED-01 | [タイトル] | Medium | [カテゴリ] | [file:line] | Open |
| LOW-01 | [タイトル] | Low | [カテゴリ] | [file:line] | Open |
マージ前に必要な対応
このコードがマージされる前に解決しなければならない Critical および High の検出事項のみを記載します:
- CRIT-01 [タイトル] — [1 行の修正指示]
- HIGH-01 [タイトル] — [1 行の修正指示]
Medium および Low の検出事項は、解決期限を約束したフォローアップ Issue として追跡する必要があります。
レビュー実施者: [Reviewer]、実施日: [Date] — チェックリストバージョン [1.0]
品質チェック
- すべての検出事項に、重大度、カテゴリ、具体的なリソース名、ファイルと行番号、現在のコード、修正後のコードが含まれている
- チェックリストが 12 のカテゴリすべてを網羅している: IAM、シークレット、保存時の暗号化、転送時の暗号化、ネットワーク、ログ、命名/タグ付け、状態、モジュール構造、環境のパリティ、コスト、ドリフト
- エグゼクティブサマリーテーブルが実際の件数で埋められている — すべてゼロやプレースホルダーばかりになっていない
- 「マージ前に必要な対応」セクションに Critical および High の項目のみが記載されている
- 検出事項のコードスニペットに、問題のあるコードと修正後のバージョンの両方が示されている
- 総合リスク評価が、最も重大度の高い未解決の検出事項によって正当化されている
- チェックリストの項目が二値的(チェック可能)である — 叙述的な所見になっていない
アンチパターン
- ハードコードされた認証情報やシークレットが何らかの形式で含まれている場合、検出事項を低リスクと判定しないでください。必ず重大と判定してください
- デプロイのコンテキストから切り離して IaC をレビューしないでください。ネットワークと IAM を併せて評価する必要があります
- 具体的なリソース名、ファイル、行番号を示さずに、文章による検出事項を提示しないでください
- 「マージ前に必要な対応」の概要を省略しないでください。レビュアーに必要なのは、レポート全体だけではなく、マージを阻止する項目の明確な一覧です
- データストアに保存時または転送時の暗号化が設定されていない場合、依頼者から明示的に指摘されていなくても、コードを承認しないでください