TerraformのIaCセキュリティをCheckovで自動検査する設計|S3・IAM・SGの設定ミスをPRマージ前に止める方法

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Terraform > TerraformのIaCセキュリティをCheckovで自動検査する設計|S3・IAM・SGの設定ミスをPRマージ前に止める方法
「Terraformでリソースを定義したのに、後の監査でS3バケットが全公開設定のままになっていた」
「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で誤検知をコントロールしながら運用できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜTerraformのIaCにセキュリティスキャンが必要か

terraform planやterraform validateは構文と参照の正確性を確かめますが、セキュリティ上の問題は検出しません。たとえば次のS3バケット定義はterraform planを正常に通過しますが、S3バケットが外部から読み取れる状態になっています。

resource "aws_s3_bucket" "example" { bucket = "my-bucket" } # Public Access Blockの定義なし # サーバーサイド暗号化の定義なし # アクセスログの定義なし

こうした「設定が存在しない」状態の問題は、terraform planの出力からは見えません。クラウドセキュリティインシデントの多くはIAMやストレージの設定ミスに起因するとされており、IaCの普及とともに「コード段階でのセキュリティチェック」が標準的なプラクティスになっています。

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レポート出力 対応 対応
TerraformだけでなくK8sマニフェストやDockerfileも同じツールで一括チェックしたい場合はCheckov、スキャン速度を優先したい場合はtfsecというのが一般的な使い分けです。この記事ではCheckovを使って解説します。

Checkovのインストールと基本的なスキャン手順

1. pipでCheckovをインストールする

# Python 3.8以降が必要 pip install checkov # バージョン確認 checkov --version

仮想環境(venv)を使う場合はプロジェクトディレクトリ内でインストールします。

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

Terraformリポジトリのルートに .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

以降、git commitを実行するたびにCheckovが自動で走ります。違反が検出されるとコミットがブロックされ、検出内容が表示されます(出力例。環境により異なります)。

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

修正してから再度git commitすると、チェックを通過してコミットが完了します。

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をTerraformのワークフローに組み込む最大のメリットは、設定ミスを「人がレビューする前」の段階で検出できる点にあります。apply後の手動修正は手間がかかり、設定変更の差分が本番に影響しますが、コード段階での検出なら修正コストが大幅に下がります。

まずはローカルで checkov -d . を実行してみてください。既存のTerraformコードにどの程度の指摘が出るかを把握することが、導入の第一歩です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、TerraformによるIaC設計の基本からCheckovによるセキュリティスキャン導入まで、実務で使えるインフラ管理の全体像を体系的に学べるリソースをご案内しています。
>> Terraform IaC設計を体系的に学ぶ

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。