Terraform 運用 #4 セキュリティ・コストスキャン — trivy、checkov、Infracost で PR ガードレール

読了 4分

#3 までのチェックは、コードが正しいかを見ていました。今回の 2 つのチェックは、安全なのか、そしていくらなのかという別の問いを投げます。セキュリティグループをインターネットに全開にするコードも、月に数百ドルかかるインスタンスを立ち上げるコードも、文法的には完璧なので、これまでのチェックをすべて通過してしまいます。この 2 種類の事故を PR の段階で捕まえることが、今回の目標です。

セキュリティ静的分析 — trivy と checkov #

IaC セキュリティスキャナーは、リソースの設定を既知のリスクパターンと照合します。代表的なツールは 2 つです。

  • trivy: コンテナスキャナーとして有名な Aqua の統合ツールです。Terraform 専用だった tfsec が trivy に統合されたので、検索で tfsec の資料を見つけたら「今は trivy」と読み替えれば大丈夫です。
  • checkov: Prisma Cloud(Palo Alto)系列のスキャナーで、ルール数が多く、コンプライアンスフレームワークへのマッピングが強力です。

どちらか 1 つで十分で、実習ではインストールが軽い trivy でいきます。実践シリーズのコードに回してみます。

スキャン実行
$ trivy config envs/dev
HIGH: S3 bucket does not have logging enabled
MEDIUM: Instance metadata service v1 is enabled
...

問題なく動いていたコードでも指摘は出てきます。スキャナーの指摘は 3 種類に分けて処理します。実際のリスク(直せば済みます)、把握したうえで受け入れたリスク(例外処理)、チームの状況に合わないルール(ルールの無効化)です。重要なのは 2 番目の処理の仕方です。

main.tf
#trivy:ignore:AVD-AWS-0089 -- 実習環境のためアクセスログバケット未構成。prod 移行時に有効化
resource "aws_s3_bucket" "assets" {
  # ...
}

例外は範囲をそのリソースに絞り、理由をコメントとして残します。理由のない ignore が積み重なったコードはスキャナーを止めたのと同じになり、理由があれば例外そのものがレビューの対象になります。checkov も #checkov:skip コメントで同じ方式をサポートしています。

CI に載せる #

PR ワークフロー(#1)にステップを 1 つ追加します。

.github/workflows/terraform-plan.yml
      - name: trivy scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: config
          scan-ref: envs/dev
          exit-code: "1"
          severity: CRITICAL,HIGH

severity の調整が運用のコツです。最初から MEDIUM まで失敗扱いにすると、既存コードの指摘があふれてチームがスキャナーを恨むようになります。CRITICAL・HIGH だけをブロックする設定から始めて、既存の指摘を整理しながら基準を引き上げていく段階的な導入のほうが、定着率が高くなります。

Infracost — PR に値札をつける #

コスト事故の構造的な原因は、コストが見える時点にあります。コードをレビューするときには見えず、月末の請求書で見えます。実践 #2 の NAT の個数や実践 #5 のインスタンスクラスのような判断はすべてコストの判断でしたが、レビュアーがその金額を暗算できるはずがありません。Infracost は plan の結果に単価表を掛け合わせて、PR にコメントとしてつけてくれるツールです。

コメント例
Infracost コメントの例:
  aws_db_instance.main
    ~ instance_class: db.t4g.micro → db.r6g.large
  Monthly cost change: +$210 (total $XX → $XX)

インスタンスクラスの 1 行の変更が「+$210/月」として見えた瞬間、コストレビューは請求書の段階から PR の段階に前倒しされます。CI 連携は公式アクション(infracost/actions)で行い、無料ティアから始められます(料金ポリシーは導入時点で確認することをおすすめします)。絶対額が完璧ではなくても(トラフィックの従量課金などは推定に限界があります)、変更の方向と規模を見るには十分です。

タグ — 事後追跡の基盤 #

PR ガードレールが事前の防御だとすれば、事後追跡の基盤はタグです。実践 #1 で default_tags によってすべてのリソースに Project と Env をつけておいたおかげで、Cost Explorer でタグを基準に「myapp の dev がいくらか」にすぐ答えられます。スキャナーのルールのうちタグ必須化のルールを有効にしておけば、タグの欠落も PR で捕まります。すでに無駄が疑われるアカウントなら、AWS コスト無駄チェックリストの点検項目と並行して進めれば大丈夫です。

まとめ #

今回扱った内容です。

  • セキュリティスキャナーは trivy(tfsec 統合)または checkov のどちらか 1 つで十分です。文法的に完璧な危険設定を、既知のパターンとの照合で捕まえます
  • 例外処理はリソース単位に絞り、理由をコメントとして残します。理由のない ignore の蓄積は、スキャナーを止めたのと同じです
  • CI のブロック基準は CRITICAL・HIGH から始めて段階的に引き上げます
  • Infracost は PR に月額コストの変化をコメントとしてつけ、コストレビューを請求書から PR に前倒しします
  • default_tags ベースのタグが事後のコスト追跡の軸で、タグ必須化のルールで欠落も防ぎます

次回(#5 大規模の構造化)では、コードとチームが大きくなるときの構造を扱います。state をスタックに分ける基準、スタック間の参照、そして Terragrunt が必要になるタイミングです。

X