「IAMポリシーにワイルドカード(*)を書いたまま本番へapplyしてしまった」
IaCはインフラの再現性を高める一方、設定ミスも同じ再現性で繰り返されます。applyする前にHCL段階で問題を検出する仕組みがなければ、同じ設定ミスが複数の環境に展開されるリスクがあります。
この記事では、TerraformのHCLファイルをCheckovで静的解析し、S3・IAM・セキュリティグループに潜む設定ミスをpre-commitとGitHub ActionsのCIに組み込んでPRマージ前に自動検出する設計を解説します。想定環境はLinux(RHEL 9系~Ubuntu 24.04 LTS)、TerraformはHashiCorp Terraform 1.5以降です。
この記事のポイント
・CheckovはTerraformのHCLをapply前に静的解析するOSSセキュリティスキャナー
・S3 Public Access Block未設定・IAMワイルドカード・SG全開放を自動検出できる
・pre-commitフックでコミット前、GitHub ActionsでPRマージ前にチェックできる
・skip_checkとbaselineで誤検知をコントロールしながら運用できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜTerraformのIaCにセキュリティスキャンが必要か
terraform planやterraform validateは構文と参照の正確性を確かめますが、セキュリティ上の問題は検出しません。たとえば次のS3バケット定義はterraform planを正常に通過しますが、S3バケットが外部から読み取れる状態になっています。resource "aws_s3_bucket" "example" { bucket = "my-bucket" } # Public Access Blockの定義なし # サーバーサイド暗号化の定義なし # アクセスログの定義なし
Checkovはこのギャップを埋める静的解析ツールです。HCLファイルを読み込み、750本以上のチェックルールと照合して問題箇所を出力します。既存のTerraformの設計・運用ガイドにこのセキュリティスキャン層を加えることで、applyする前に設定ミスを検出できます。
CheckovとtfsecをTerraformセキュリティスキャナーとして比較する
CheckovはBridgecrew(現在はPrisma Cloudに統合)が開発したOSSの静的解析ツールです。Pythonで実装されており、pipで導入できます。Terraformに特化したセキュリティスキャナーとして、同じくOSSのtfsec(Aqua Security、Go製)があります。CheckovとtfsecはどちらもTerraformのHCLを解析できますが、カバー範囲とアプローチが異なります。
| 項目 | Checkov | tfsec |
|---|---|---|
| 実装言語 | Python | Go |
| 対応フレームワーク | Terraform・CloudFormation・K8s・Helm・Dockerfileほか | Terraform専用 |
| スキャン速度 | 中程度 | 高速(Go製のため) |
| ルール数(目安) | 750以上(AWS・Azure・GCP・K8s) | 300以上(AWS・Azure・GCP) |
| カスタムルール | Python・YAML両対応 | YAML対応 |
| SARIFレポート出力 | 対応 | 対応 |
Checkovのインストールと基本的なスキャン手順
1. pipでCheckovをインストールする
# Python 3.8以降が必要 pip install checkov # バージョン確認 checkov --version
python3 -m venv .venv source .venv/bin/activate pip install checkov
2. Terraformディレクトリをスキャンする
Terraformファイル群があるディレクトリに対して-d オプションでスキャンします。# カレントディレクトリのHCLをスキャン checkov -d . # terraformフレームワークに限定する場合 checkov -d . --framework terraform
Check: CKV2_AWS_6: "Ensure that S3 bucket has a Public Access block" FAILED for resource: aws_s3_bucket.example File: /main.tf:1-3 Check: CKV_AWS_18: "Ensure the S3 bucket has access logging enabled" FAILED for resource: aws_s3_bucket.example File: /main.tf:1-3 Passed checks: 12, Failed checks: 5, Skipped checks: 0
3. よく検出される代表的なチェックルール
| チェックID | 対象リソース | 検出内容 |
|---|---|---|
| CKV2_AWS_6 | aws_s3_bucket | S3 Public Access Blockが設定されていない |
| CKV_AWS_18 | aws_s3_bucket | S3アクセスログが有効になっていない |
| CKV_AWS_19 | aws_s3_bucket | S3サーバーサイド暗号化が設定されていない |
| CKV_AWS_40 | aws_iam_policy | IAMポリシーにワイルドカード(*)が含まれる |
| CKV_AWS_25 | aws_security_group | SGインバウンドで0.0.0.0/0への22番ポートが開放 |
| CKV_AWS_24 | aws_security_group | SGインバウンドで0.0.0.0/0への3389番ポートが開放 |
| CKV_AWS_57 | aws_s3_bucket | S3バケットポリシーにPublicReadが含まれる |
pre-commitフックにCheckovを組み込む設計
Checkovをコマンドで手動実行するだけでは、実行し忘れが起きます。pre-commitフックに組み込むことで、git commitのタイミングに自動でスキャンが走る設計にできます。1. pre-commitのインストールと設定ファイルの作成
pip install pre-commit
.pre-commit-config.yaml を作成します。repos: - repo: https://github.com/bridgecrewio/checkov rev: 3.2.0 # 使用時の最新安定版に変更する hooks: - id: checkov args: ['--framework', 'terraform']
2. フックの有効化と動作確認
# フックをインストール(.git/hooks/pre-commit に登録される) pre-commit install # 全ファイルに対してテスト実行する場合 pre-commit run --all-files
Checkov.............................................Failed - hook id: checkov - exit code: 1 Check: CKV2_AWS_6: "Ensure that S3 bucket has a Public Access block" FAILED for resource: aws_s3_bucket.example File: /main.tf:1-3
GitHub ActionsでCheckovをCIに組み込む設計
pre-commitはローカルでのチェックですが、チームで使う場合はCIでも同じチェックを走らせることが重要です。CIで検出することで、pre-commitをスキップしてプッシュした変更も捕捉できます。1. ワークフローファイルの構成
.github/workflows/checkov.yml を作成します。name: Checkov IaC Security Scan on: pull_request: paths: - '**.tf' jobs: scan: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Run Checkov uses: bridgecrewio/checkov-action@master with: directory: . framework: terraform soft_fail: false output_format: cli,sarif output_file_path: console,results.sarif - name: Upload SARIF results uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: results.sarif
soft_fail: false にすると、Checkovが違反を検出したときにGitHub Actionsのステップが失敗し、PRのマージをブロックできます。SARIFファイルをアップロードすると、GitHub Securityタブで検出結果を確認できます。2. パスフィルタで.tfファイル変更時のみ起動する設計
paths: ['**.tf'] を指定することで、プルリクエストに .tf ファイルの変更が含まれる場合のみワークフローが起動します。モノレポ構成でTerraformディレクトリが複数ある場合は、directory オプションに特定のパスを指定して対象を絞れます。検出結果のハンドリング設計
Checkovを導入すると、既存の設計上の判断や特定の環境向けに意図的に設定した項目が「違反」として検出されることがあります。こうした誤検知を管理する方法が2つあります。checkov:skipで個別に抑制する
特定のリソースに対して特定のチェックをスキップしたい場合、HCLファイルにコメントで記述します。resource "aws_s3_bucket" "logs" { # checkov:skip=CKV_AWS_18:ログバケット自身のアクセスログは取得しない設計 bucket = "my-access-logs-bucket" }
--baselineで既存の指摘をベースライン除外する
既存のTerraformコードにCheckovを導入すると、大量の指摘が出ることがあります。全部一度に修正するのが難しい場合、既存の指摘をベースラインとして記録し、新しく追加した変更のみを検査対象にする設計があります。# 現状の指摘をベースラインファイルに保存 checkov -d . --create-baseline # 以降のスキャンでベースラインを除外して実行 checkov -d . --baseline .checkov.baseline
.checkov.baseline ファイルをGitで管理することで、チームで共有できます。ベースラインに登録済みの指摘が解消されたら、ベースラインファイルから該当エントリを削除し、再登録することで記録を最新に保ちます。Checkovのよくあるエラーとトラブルシュート
「checkov: command not found」が出る場合
pipでインストールしたCheckovが見つからない場合、インストール先のbinディレクトリがPATHに含まれていないことが原因です。# インストール先を確認する python3 -m site --user-base # 出力例(環境により異なります) # /home/user/.local # PATHに追加する(~/.bashrcや~/.bash_profileに記載) export PATH="$HOME/.local/bin:$PATH" source ~/.bashrc # 仮想環境を使っている場合は activate を忘れずに source .venv/bin/activate checkov --version
「Error parsing HCL」が出る場合
Checkovがモジュール参照やfor_each内の動的な値を含むHCLを解析できずエラーになる場合があります。このときは--download-external-modules false オプションでモジュールのダウンロードを無効にするか、--skip-path で解析エラーになるパスを除外してから全体をスキャンします。# 特定パスを除外してスキャン checkov -d . --skip-path ./modules/vendor # 解析可能なファイルのみに絞る(エラー時の切り分けに使う) checkov -f main.tf
【注意】checkov:skipを乱用しない
誤検知への対処としてcheckov:skip は便利ですが、理由なしにスキップを重ねると「なぜその設定が許容されているのか」が追跡できなくなります。特にS3 Public Access BlockやIAMワイルドカードは実害の大きいルールです。スキップする前に「本当にこの設定が必要か」を確認してください。スキップではなく修正で対応できる場合は修正を優先するのが実務上の鉄則です。本記事のまとめ
| やりたいこと | 方法・コマンド |
|---|---|
| TerraformのHCLを静的解析する | checkov -d . --framework terraform |
| コミット前に自動スキャンする | pre-commitフック + .pre-commit-config.yaml |
| PRマージ前にCIでスキャンする | bridgecrewio/checkov-action + GitHub Actions |
| 特定リソースの特定チェックをスキップする | HCLコメント # checkov:skip=CKV_XXX:理由 |
| 既存コードの指摘をベースライン化する | checkov -d . --create-baseline |
| マルチフレームワークをまとめてスキャンする | Checkovを選択(K8s・Helm・Dockerfileも対応) |
| スキャン速度を優先する | tfsecを選択(Terraform専用のGo製ツール) |
まずはローカルで
checkov -d . を実行してみてください。既存のTerraformコードにどの程度の指摘が出るかを把握することが、導入の第一歩です。
>> Terraform IaC設計を体系的に学ぶ
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Terraformのcreate_before_destroyでゼロダウンタイム更新する方法|ALBリスナールール・ACM証明書切り替えとlifecycle設計の実践
- この記事の属するカテゴリ:Terraformへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます