ポリシー・アズ・コード:インフラ変更を統制下に置く
開発、ステージング、本番の3つの環境があるとしよう。それぞれはInfrastructure as Code(IaC)で管理され、パイプラインは正常に動作し、プランも問題なく、変更は適用される。しかしある日、誰かが間違ったリージョンにリソースを作成してしまう。また別の時には、必須のコストセンタータグがないままクラウドリソースが立ち上がる。誰も気づかず、請求書が届いて初めて問題が発覚する。
環境を分離すれば、本番に変更を適用する前にテストできる。しかし、組織のルールに違反する変更を人が行う問題は解決できない。必要なのは、誰も読まないドキュメントではなく、ルールを自動的に強制する仕組みだ。
手動ルールが機能しない理由
ほとんどのチームには、どこかにポリシーが書かれている。Wikiページには「すべてのリソースに environment タグを付けること」とある。Slackのメッセージには「本番リソースは ap-southeast-1 のみ」と書かれている。ミーティングでの決定事項として「ファイアウォールルールの変更にはセキュリティチームの承認が必要」と決まっている。
ルールは存在するが、人間の記憶と善意に依存している。人は忘れる。新しいメンバーはWikiの存在を知らない。緊急の変更はレビュープロセスをすり抜ける。そして問題が起きたとき、ルールが守られたかどうかを証明する方法がない。
手動によるガバナンスは、安全性を提供せずに摩擦を生むだけだ。ルールはあるが、被害が出てからでないと強制されない。
ポリシー・アズ・コード:パイプラインで実行されるルール
ポリシーとは、すべてのインフラ変更が従うべきルールである。ガバナンスとは、そのルールが実際に守られていることを確実にする仕組みだ。両方をコードとして記述し、パイプラインで実行するのが「ポリシー・アズ・コード」である。
考え方はシンプルだ。ルールをドキュメントに書く代わりに、変更が適用される前に実行されるチェック可能なコードとして記述する。パイプラインは、提案された変更をポリシーに対して評価する。ポリシー違反があれば、パイプラインは停止し、何が問題かを正確に報告する。
以下は、すべてのリソースに environment タグを必須とするシンプルなSentinelポリシーである。
# すべてのリソースに "environment" タグを必須とする
mandatory_tag = rule {
all tfplan.resources as _, resource {
resource.applied.tags contains "environment"
}
}
main = rule {
mandatory_tag
}
これはInfrastructure as Codeと同じ原理である。ルールをインフラ定義と同じように扱う。ルールはリポジトリに置かれ、レビューされ、テストされ、一貫して適用される。
よくある強制可能なポリシー
タグ付け要件は最も一般的な出発点だ。多くの組織は、すべてのクラウドリソースに environment、owner、cost-center などのタグを必須としている。強制がなければ、タグの不統一、欠落、タイポが発生する。ポリシー・アズ・コードを使えば、パイプラインがプラン出力をチェックし、タグ付けルールを満たさないリソースを拒否する。
リージョン制限もよくあるポリシーだ。組織が本番ワークロードを特定のリージョンでのみ実行すると決めた場合、パイプラインでそれを強制すべきである。深夜のデプロイ中に開発者が誤って別のリージョンを指定しても、ポリシーがリソース作成前に検出する。
承認ワークフローもポリシーに組み込める。すべての変更が同じリスクを持つわけではない。ステージングでのファイアウォールルール変更には1人のレビュアーで済むが、本番での同じ変更にはセキュリティチームの承認が必要かもしれない。パイプラインは環境、リソースタイプ、変更範囲をチェックし、必要な承認パスを決定できる。
実際の動作フロー
典型的なフローは次のようになる。インフラプランが生成され、適用ステップが実行される前に、パイプラインがポリシーチェックを実行する。このチェックはプラン出力を読み取り、ルールに照らして評価する。
以下はそのフローの視覚的な表現である。
複雑なポリシーにはOpen Policy Agent(OPA)やSentinelのような専用ツールを使える。あるいは、プランをパースして特定の条件をチェックするシンプルなスクリプトを書くこともできる。ツールよりも重要なのは、チェックが自動的で、一貫性があり、ブロッキングであることだ。
ポリシー違反が見つかれば、パイプラインは停止する。出力には、どのルールに違反したか、どのリソースがトリガーしたか、期待される値は何かが正確に表示される。開発者は3日後に来るチケットではなく、即座にフィードバックを得られる。
例外もシステムの一部
ポリシーは絶対的な障壁であってはならない。例外を認める正当な理由は存在する。新しいビジネス要件により、これまで承認されていなかったリージョンにリソースが必要になるかもしれない。緊急修正では通常のタグ付けルールをバイパスする必要があるかもしれない。
重要なのは、例外を可視化し、文書化することだ。誰かが黙ってポリシーを回避する代わりに、例外リクエストを提出する。リクエストは承認プロセスを経て、承認された例外は監査証跡に記録される。パイプラインは承認済み例外をチェックし、変更を許可することもできる。
これにより、例外はシャドウプロセスから文書化された決定へと変わる。誰が、いつ、なぜ承認したかがわかる。この情報は監査、ポストモーテム、将来のポリシー見直しに役立つ。
なぜチームが高速化するのか
逆説的に聞こえるかもしれない。パイプラインに自動チェックを追加すると、遅くなるように思える。しかし実際は逆である。
ポリシー・アズ・コードがない場合、機密領域に触れる可能性のある変更はすべて手動レビューが必要になる。レビュアーはプランを確認し、ルールを思い出し、判断を下さなければならない。時間がかかり、見落としも発生する。
ポリシー・アズ・コードがあれば、ルーチンチェックは自動的に行われる。パイプラインは明らかに無効な変更を数秒で拒否する。レビュアーは本当に人間の判断が必要な変更だけを見ればよい。自動化できるものに手動チェックを待つ必要がなくなり、チームはより速く動ける。
そして問題が起きたとき、明確な監査証跡がある。何が変更され、誰が承認し、どのポリシーが関係していたかがわかる。推測も、責任のなすり合いも、「そんなルールがあるのを知らなかった」もなくなる。
始めるためのクイックチェックリスト
インフラパイプラインにポリシー・アズ・コードを導入する場合、以下の手順で始めるとよい。
- 現在最も問題になっているポリシーを1つ選ぶ。タグ付けが良い出発点になることが多い。
- ポリシーをスクリプトとして書くか、OPAのようなツールを使う。既知の違反に対してテストする。
- ポリシーチェックをパイプラインのプランと適用の間に追加する。
- まずは非ブロッキングモードで実行する。違反をログに記録するが、パイプラインは継続させる。
- 1週間ほど違反を確認する。誤検知を修正し、ルールを調整する。
- ブロッキングモードに切り替える。違反があった場合、パイプラインを停止させる。
- 例外プロセスを文書化する。オーバーライドをリクエストする方法を明確にする。
まとめ
ポリシー・アズ・コードは、インフラのルールを忘れられたドキュメントから自動化されたガードへと変える。本番に到達する前に違反を検出し、明確な監査証跡を提供し、ルーチンチェックを自動化することでチームのスピードを向上させる。ルールはリポジトリに置かれ、コードのようにレビューされ、すべてのパイプライン実行で動作する。これこそが、誰も読まないWikiページに載っているガバナンスではなく、実際に機能するガバナンスである。