Policy-as-Code とは?
テクノロジーの世界にいれば、SRE、DevOps、IaC(Infrastructure-as-Code)など、さまざまな専門用語を耳にしたことがあるでしょう。そして、もうひとつ知っておくべきことがあります:policy-as-codeです。policy-as-codeが何なのか、不思議に思っている人もいるかもしれません。単なるテクノロジーの流行語なのでしょうか?以下では、policy-as-codeについて詳しく説明します。
Policy-as-Codeとは?
Policy-as-Codeは、インフラストラクチャルール、要件、手順、方法論、ポリシーを反復可能かつ偶発的な方法で管理する方法です。また、組織のインフラストラクチャのセキュリティ確保にも役立ちます。
ポリシーとは?
policy-as-codeを詳しく見る前に、policyとは何かを説明する必要があります。広義では、ポリシーとは、基本的に、特定の望ましい状態や条件に導くために従う必要のある一連の規則、要件、または手順のことです。
例えば、有効な運転免許証を持っていること、年齢や視力の最低条件を満たしていること、飲酒運転をしないことなどです。これらのポリシーは、望ましい状態や条件(この場合は道路上の安全)を達成するために必要なものです。同様に、ITの世界では、ネットワーク、セキュリティ、リポジトリ、インフラストラクチャなどのポリシーがあります。
Policy-as-Codeを使用する理由
上記の定義からお分かりのように、policy-as-codeは以下の分野で組織を支援します:
- ポリシーの管理 – ポリシーを一元管理することで、ITチームがそれぞれのポリシーを異なる場所に置くよりも、はるかに柔軟な方法でポリシーを管理することができます。
- バージョン管理 – ポリシーが一元管理された場所にあれば、バージョン管理(GitHub、GitLab、Bitbucket など)を行う意味があります。ポリシーをバージョン管理することで、組織はよりコントロールしやすくなり、ポリシーのチェックや履歴を確認することができます。
- 反復性 – ポリシーを一元化された場所に移し、バージョニングを実装した後は、コードを繰り返し実行できます。
- 冪等性 – コードが繰り返し実行可能な場合、同じコードを何度も実行すると同じ出力が得られます。これは非常に重要で、オペレータがデプロイを実行することをためらったり恐れたりしないようにするのに役立ちます。
- 自動化 – 上記のすべてを達成したら、プロセスを自動化することができます。
- デカップリング – デカップリングとは、ポリシーをアプリケーションロジックから分離する機能です。これにより、スパゲッティコードを避けることができます。例えば、CSSコードをアプリケーションロジックであるプログラミング言語(PHP、Ruby、Go、Pythonなど)と混在させたくありません。
- セキュリティ – これらの中で最も重要なのはセキュリティです。結局のところ、policy-as-codeの主な目的は、インフラストラクチャを安全にすることです。
Policy-as-Code のユースケース
上記では、ポリシーとは何か、ITインフラストラクチャやリソースに対してどのようにポリシーを実装できるかを理解していただくために、実際の例を挙げました。もう少し掘り下げてみましょう。
組織のインフラストラクチャには、ネットワークやセキュリティのポリシー、あるいは一般向けの Web アプリケーションのポリシーが設定されている場合があります。先に述べたように、これらのポリシーはITインフラストラクチャやリソースを保護するために構成されます。
では、異なるタイプのユースケースをいくつか見てみましょう。
認可は、ユーザがアクセスできるリソースを決定する方法です。policy-as-codeを使うことで、アプリケーションのアクセス制御を実装することができます。いくつかの例を見てみましょう:
- このポリシーでは、ユーザータイプ admin のみがアプリケーションの URL、https://yourapplication.com/admin にアクセスできます。さらに、メソッドタイプは POST のみ許可されます。
- 組織のインフラストラクチャを保護するために、LoadBalancer の一種であるすべてのサービスを拒否するポリシーを使用することができます。これにより、組織のセキュリティ体制を改善するための良いスタートを切ることができます。
- HTTPS 接続だけを許可してください。Ingress を通して外部からのリクエストがアプリケーションに到達するのを許可するのはよくあることですが、 HTTPS 接続だけを許可するのは良い習慣です。前の例と同様に、このポリシーが組織のセキュリティ体制の改善にどのように役立つかがわかります。
インフラストラクチャ・プロビジョニング
このカテゴリに分類されるポリシーのほとんどは、インフラストラクチャの作成に関連するものです。これには、リソースの必須タグ付け、ファイアウォールやネットワークの設定、リソースのプロビジョニングなどが含まれます。それらのいくつかを詳しく見てみましょう:
- アノテーション/タグ – ほとんどの組織には、ビジネスユニット、複数の開発チーム、SRE/DevOpsチーム、プラットフォーム/クラウドエンジニアリングチーム、経理/人事チームなどがあります。チームやユニットに基づいてリソースをタグ付けすることは、組織のリソース管理に確実に役立ちます。
- Allowed IP – アプリケーションが特定の外部IPアドレスからのアクセスを必要とすることがあります。これは、許可IPアドレスのリストを持つポリシーを作成することで許可できます。
- 特定タイプのリソースのプロビジョニング – 組織がさまざまなタイプのインフラストラクチャ環境(サンドボックス、開発環境、ステージング環境、プリプロダクション環境、本番環境など)を導入する場合、これらの環境用に特定のタイプのマシンを構成するのが理想的です。
Kubernetesコントロール
組織でKubernetesを使用する場合、ポリシーアズコードの一部としてポリシーを構成するのが理想的です。Pod、名前空間、ノード、リソースなどのKubernetesリソースを管理するポリシーを設定できます。また、信頼できるレジストリからのコンテナのみを使用するようにポリシーを設定することもできます(その他にもいろいろあります)。
- 信頼できるレジストリ – コンテナを保護するために、信頼できるレジストリからのイメージのみを許可するポリシーを作成するとよいでしょう。コンテナをプルできるレジストリの特定のリストを持つことができます。
- コンテナの制限と要求 – これらのポリシーは、コンテナ作成時のメモリと CPU の制限、およびメモリと CPU の要求を強制します。これは、リソースの占有やOOMキラー(Out of Memory)を防ぐために非常に重要です。
- レプリカの制限 – アプリケーションをデプロイする際には、常に稼働していることを保証したいものです。これは、レプリカの数を設定することで実現できます。アプリケーションがより多くのリソースを必要とする場合、レプリカの数を自動的に増やすことができます。しかし、この場合も、アプリケーション自体が適切に開発されておらず、そのためにリソースを大量に消費していることが判明した場合、誤った推測につながる可能性があります。これを防ぐには、組織にレプリカの最小数と最大数を設定させるポリシーを構成します。
コストコントロール
インフラ管理のもうひとつの重要な側面は、コストの管理です。一つの選択肢は、policy- as-a-codeを使用することです。例えば、リソースのラベリングやアノテーション、特定のマシン・タイプの割り当てなどのポリシーを実装できます。
- アノテーション/タグと必要なラベル – 部門やチーム(など)に基づいてリソースにラベルを付けることで、それぞれのリソースにどれだけのリソースが使用されているかを示すレポートを作成できます。
- 特定のマシンタイプ – 組織は、関係者がアプリケーション・コードの最適化または特定のマシンタイプの使用によってリソース消費を最適化する方法を決定するのに役立つレポートを作成できます。詳細は後述します。
- 費用を一定額に制限 – インフラ環境(サンドボックス、開発、ステージング、プリプロダクション、およびプロダクション環境を含む)のポリシーを作成することで、各プロジェクトのコストを制限できます。例えば、サンドボックス環境で特定のリソースの支出を一定の金額に制限するポリシーを作成することは、非常に理にかなっています。
Policy-as-Codeの実装方法
ここまで、policy-as-codeの具体的なユースケース(認可制御、インフラストラクチャ・プロビジョニング、Kubernetes制御、コスト制御など)について説明してきましたが、自分の組織でどのように実装すればいいのか悩んでいる人もいるかもしれません。これらのユースケースすべてに一度に対応することから始めるべきでしょうか?ポリシーの作成と実装を支援するアプリケーションはありますか?
そこで朗報です。OPA(Open Policy Agentの略で「オーパ」と発音します)を使用することができます。OPAはオープンソースの汎用ポリシーエンジンで、スタック全体のポリシー実施を統一します。

上図に示すように、ユーザーが OPA 対応サービスに対して開始するすべてのリクエストは、定義されたポリシーに基づいて OPA で評価できます。
OPAエコシステムにはOPAがサポートするサービスがいくつかあります(完全なリストはこちら)。代表的なものは以下のとおりです:
- Kubernetesアドミッションコントロールと認証
- Terraform
- Envoy
- Docker
- Google Kubernetes Engine (GKE)
- Istio
- AWS CloudFormation
- Ceph
- SSH and Sudo Auth with Linux
上図に示すように、サービスとそのユーザーが公開するデータは、OPAのネイティブなクエリー言語であるRegoを使用して検査および変換することができます。ご心配なく、Rego は単なるプログラミング言語です。OPA を実装するために高度な Rego を知る必要はありません。
OPAの使い方を説明する前に、上の図からもう1つ重要なことを強調しておきます。ご覧のとおり、サービス(アプリケーション・ロジックと見なすことができます)はポリシーから遠く離れています。これは、OPAがポリシーの決定をポリシーの実施から切り離すためです。
もう十分です。それでは、OPA を実際に使用した簡単な例をいくつか見てみましょう。

上の画像にあるように、OPAはこのように機能します:
- ユーザがアプリケーションやサービスにリクエストを送信します。
- リクエストは、”role “という値を持つポリシー入力(JSON)で構成されます: 「admin」。
- OPA は入力を受信して処理します。
- OPA で定義されたポリシーに基づき、出力は値 “admin_allowed”: true で返されます。
このシナリオでは、入力文書と出力文書の間に定義さ れた方針に基づく正しい方針決定を表すマッピングが存在 し ます。このマッピングは OPA 方針によって定義されます。上の例の入力、ポリシー、出力を詳しく見てみましょう:
入力(JSON):上の図によると、入力は JSON 形式でなければなりません。図 2 (上) に基づいて、この入力は、ユーザーが管理ページにログインするボタンをクリックしたときに生成されたと仮定できます。ボタンがクリックされると、この入力情報が OPA エンジンに送信されます。そして、ポリシーがそれを処理します。
{
"method": "POST",
"role": "admin"
}
Code language: JSON / JSON with Comments (json)
方針(Rego):ソースファイルがパッケージの一部であることを宣言するために、package playを使いました。そして、変数admin_allowを宣言し、値falseを代入しました。(この変数のオーバーライドがなければ、デフォルトが使用されます)。次の行(admin_allow = true)には2つの条件があり、それらは2つの括弧({ })の中で定義されています。これがRegoでAND条件を定義する方法です。
package play
default admin_allow = false
admin_allow = true {
input.role = "admin"
input.method = "POST"
}
Code language: JSON / JSON with Comments (json)
そして出力(JSON): 上記の入力をポリシーに対して実行すると、”admin_allow”: true が出力されました。では、入力を “method “に変更したらどうなるでしょうか?「GET “に変更したらどうなるでしょうか?その場合、出力は “admin_allow”: falseとなります。これらは、入力が処理された後にアプリケーションやサービスに返される出力のタイプです。上の例では、ユーザはアプリケーションの管理セクションにログインできるようになります。
{
"admin_allow": true
}
Code language: JSON / JSON with Comments (json)
OPAとRegoを学びたい方のために、OPA公式サイトでは、入力、ポリシー、出力を試すことができるプレイグラウンドを親切にも提供してくれています。
例えば、上記のシナリオのプレイグラウンドはこちらです。3つのケースを試して、入力を変更したときに生成される出力を確認できます。お楽しみください
Conclusion
“DevOps “という言葉を作ったパトリック・デボワは、”In-depth research and trends analyzed from 50+ different concepts as code “という素晴らしいブログ記事を書きました。彼が議論したコンセプトの1つは、policy-as-codeです。この投稿の中で、彼はpolicy-as-codeを “ポリシーを管理し自動化するために高レベル言語でコードを書くこと “と定義しています。
この記事で説明したように、policy-as-codeは、アクセス制御、リソースのプロビジョニング、コスト管理、そして最も重要なセキュリティなど、多くの点で組織に利益をもたらします。さらに、Patrick Debois氏は、DevSecOpsに関するセクションの一部として、policy-as-codeを取り上げました。
サイバーセキュリティの脅威が増加する中、policy-as-codeのようなセキュリティのレイヤーを1つ組織に追加することは、Win-Winの状況です。実際、人気のある新しいゼロ・トラスト・モデルは、「決して信頼せず、常に検証する」というモットーでセキュリティにアプローチしており、インフラストラクチャにpolicy-as-codeを追加することは、まさにそのための素晴らしい第一歩となります。