Terraformを使ってコードでAmazon Inspectorの指摘事項を管理する
こんにちは、SODAでセキュリティエンジニアとして働いている小竹です。推しSODAはコカコーラゼロとカロリミット アップルスパークリングです。どちらもオフィスの自販機で売っています。
Amazon Inspectorの通知運用、うまくいっていますか?「有効化したものの通知が鳴り止まず、結局誰も見なくなった」……いわゆる「アラート疲弊(Alert Fatigue)」に陥っていないでしょうか。
今回は、2025年5月16日にリリースされた Terraform AWS Provider v5.98.0 でサポートされた aws_inspector2_filter リソースを利用し、「本当に対応すべきアラートだけをSlackに通知する」仕組みを構築した事例を紹介します。コードの実装にはCursorを活用しつつ、人間がどのような意思決定を行ってノイズを削減したか、その設計思想を中心に紹介します。
脆弱性対応における「選択と集中」
「検出された脆弱性はすべて修正しなければならない」と考えられがちです。しかし、依存ライブラリが膨大になった現代において、CVEをゼロにし続けることは、リソース的に極めて困難です。
重要なのは「すべての穴を塞ぐこと」ではなく、「攻撃される可能性が高い穴を塞ぐこと」です。今回は、「すべての脆弱性に対応する必要はない」という事実を受け入れ、「リスクベースで通知を絞り込む」ことをゴールに設定しました。
アーキテクチャ概要
全体の流れは以下の通りです。すべての設定をTerraformで管理しています。
- Amazon Inspector: EC2やECRの脆弱性をスキャン
- Amazon EventBridge: フィルタリングされたイベントをキャッチ
- AWS Lambda: 通知内容を整形
- Slack: アラート通知
CursorとTerraformプロバイダの活用
今回の実装の要となるのが、Terraform AWS Provider v5.98.0で追加された aws_inspector2_filterリソースです。これを利用することで、Inspector側で検知した脆弱性のうち、問題ないものを「抑制(Suppression)」ステータスへ移行させられます。
今回、HCLのコーディングにはCursorを使用しました。Cursorには直近リリースされたばかりのTerraformの仕様が含まれていなかったため、当初は正確なコードが生成されませんでした。そこで、最新の公式ドキュメントのURLをチャットに入力したところ、最新仕様に準拠したコードが生成されました。最新技術を扱う際、「AIは知らないから使えない」ではなく、「ドキュメントを与えることで強力なパートナーになる」ことを改めて実感しました。おかげで、私はフィルタリングのロジックの検討に集中できました。
設定のポイント:EPSSとSeverityによるフィルタリング
生成されたコードをベースに用いて、以下の基準で指摘事項の抑制を行うフィルタを適用しました。
採用した抑制条件
-
Severity:
LOWおよびINFORMATIONALは抑制する。 - EPSS(Exploit Prediction Scoring System): 悪用される確率が 5%以下 の脆弱性は抑制する。
EPSS 5% という閾値の設定について
「EPSS 5%以下を除外する」という設定が正解かどうか、現時点では議論の余地があります。EPSSはあくまで確率論であり、「スコアが低い = 安全」とは断言できないからです。しかし、統計的に見ればスコアが5%を超える脆弱性は全体の上位数パーセントに過ぎません。「いつ攻撃されるかわからない95%」にリソースを割いて疲弊するより、「今まさに危険な5%」に集中するために、ひとまずこの値を設定しました。
Terraformでパラメータ化しているため、「まずは仮設定で運用を始め、見逃しが懸念されるなら閾値を下げる」というチューニングも容易です。この柔軟性こそがIaCの強みです。
「問題ない」という判断のコード化(IaC)
今回重視したもう一つの点が、「調査の結果、誤検知や影響なしと判断した脆弱性」を抑制するフィルタの管理です。Inspectorを運用していると、「ライブラリのバージョン的には該当するが、機能を使っていないので影響がない」というケースが多々あります。コンソール画面で「抑制」ボタンを押す運用では「誰が、いつ、なぜ抑制したのか」がブラックボックス化するという課題がありました。
そこで、こうした個別対応もすべてTerraformのリソースとして記述することにしました。
- レビュー可能:「本当に抑制していいか?」をPull Request上でチームで議論できる。
- 履歴が残る: Gitのログにより、いつ誰が追加したかが明確になる。
- 理由が残る: コメントとして抑制した理由を明記することで、属人化を防げる。
「手動で行いがちな運用判断」をコードに落とし込むことで、セキュリティ運用の透明性が格段に向上しました。
EventBridge設定における注意点
Inspector側で抑制設定を行っても、Slack通知が減らない場合があります。それが「ステータス変更」による通知です。
Inspectorでは、脆弱性が修正されたり抑制されたりすると、Findingsのステータスが CLOSED(解決済み) やSUPPRESSED(抑制済み)に変わります。単純にEventBridgeですべてのイベントを検知していると、「脆弱性が解決しました」という通知が大量に届くことになります。
解決策:ACTIVEのみを許可する
EventBridgeのイベントパターン設定で、明確に「ステータスがACTIVEであるものだけ」を通知対象とするロジックを組みました。
SUPPRESSEDを除外するのはもちろんですが、見落としがちなのがCLOSEDの除外です。「対応完了」の通知は有用なように思えますが、緊急のアラートと同じチャンネルに流れると、「未対応のアラート」が埋もれてしまう原因になります。
この設定を徹底したことで、Slackには「今すぐアクションが必要な、本当に危険な脆弱性」だけが届くようになりました。
まとめ
脆弱性管理において最も重要なのは、完璧を目指すことではなく、現実的なリスクと向き合い続けるプロセスそのものです。今回導入したEPSSによるフィルタリングも、5%という数字が絶対解ではありません。
しかし、IaCとしてコード管理されているからこそ、私たちはいつでもこの基準を見直し、組織の成長や世の中の脅威トレンドに合わせてチューニングしていくことができます。また、個別の脆弱性を抑制した判断もコードに残すことで、チーム全体の資産となります。
不要な通知が削減され、最適化されたSlackを眺めながら、浮いた時間を「次に守るべきもの」の検討と実装に使っていきたいと思います。
株式会社SODAの開発組織がお届けするZenn Publicationです。 是非Entrance Bookもご覧ください! → recruit.soda-inc.jp/engineer
Discussion