はじめに
今回は、Azureポリシーを用いてリソースの設定値を制限する方法の紹介です。
以前、AutomationにPowerShellスクリプトを登録して特定のNSGルールを検出し、SendGridでメール通知する、という記事を投稿しました。
これだと結局メールを確認する必要があり面倒で、NSGの作成/変更を検出して何とかしたいなぁと調べたところ、 Azureポリシーで特定の設定値を禁止できそうだったため試してみました。
「ソースIPアドレスがAnyのNSGルールは作成不可」というルールを設定します。
2022/10 追記 : 本記事のポリシーよりももっと柔軟に制御するポリシーを作りました。そっちは以下の記事を参照ください。
目次
Azureポリシー
概要
Azureポリシーは、リソースに対して名前や設定値のルールを与えることができるサービスです。 例として、[ストレージアカウントのSKUはLRSのみとする]、[東日本リージョンのみデプロイ可能]、[タグとして○○を必須とする]などが指定可能であり、それに違反するリソースをデプロイできないよう制御できます。
ポリシーは適用先としてサブスクリプションかリソースグループを選ぶことが可能なため、全体としての制御や、特定のリソースグループ内のみの制御など用途に合わせて利用します。
組み込みで用意されているルールもありますが、今回は該当するものがないため、JSONを記述して作成しています。
以下のサイトを参考にしました。
ポリシーの内容
今回使用するポリシーはこれです。
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/networkSecurityGroups/securityRules"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/access",
"equals": "Allow"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/direction",
"equals": "Inbound"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix",
"in": [
"*",
"Internet"
]
}
]
},
"then": {
"effect": "deny"
}
},
"parameters": {
}
}
policyRuleブロック内に、JSONで条件を記述します。 allOfがand、anyOfがorとしてブロック構造で条件分岐を記述するので、なかなか書きづらいです。
条件と処理部分を日本語で書くと、「"リソースの種類がNSGのルール" かつ "アクセスを許可するルール" かつ "受信ルール" かつ "ソースアドレスが *(Any) または Internetタグ"ならば、拒否する」です。
これで不特定なIPアドレスからの接続を許可するNSGルールを禁止するポリシーとして機能します。
パラメータとして指定したポート番号を使用するルールは拒否、など も可能ですが、ここでは利用していません。
公式ドキュメントにサンプルが紹介されています。
ポリシーの定義、割り当て
実際にポリシーを作成し適用します。まずは、適用するポリシー(ルール)を定義します。

[定義の場所]ではサブスクリプションを指定します。 その他は任意に指定します。

ポリシー定義に先ほどのJSONを貼り付け、保存します。

[種類]を"カスタム"に変更すると自作ポリシーのみ表示されるため、先ほど作成したポリシーの名前をクリックします。

[割り当て]をクリックします。

[スコープ]や[除外]の欄を用いることで、サブスクリプションの中の特定のリソースグループまたはリソースにのみ ポリシーを適用することや、一部のリソースグループやリソースを適用対象外とすることが可能です。
今回はサブスクリプション全体に適用するのでこのままです。 パラメータがあるポリシーを定義した場合は、パラメータタブにて指定することができます。

修復タブでは、ポリシー用のマネージドIDの作成を指定できます。 ポリシーの作成の仕方によっては、ルールに合致した際に自動設定や自動修正が可能であり、それ用のIDです。 これはそのうち試してみたいですが、今回はそのままにして割り当てを実行。

サービスIDについては以前にちょこっと書いたのでそれ参照。
これでポリシーの定義と割り当ては完了です。
テスト
早速、適用したポリシーの動作をテストします。
送信元がAnyのNSGルールを追加してみます。

すると。。。
ルールの作成時にエラーが表示され、「ポリシーにより許可されませんでした」とあります。
Azureポリシーを用いて、ルールに合致した設定値を拒否することができました。

もちろん、ソースIPアドレスを指定したルールであれば作成可能です。
ポリシー準拠状況の確認
概要からポリシー名をクリックすると、そのポリシーの適用範囲に存在するリソースについて、 ポリシーの準拠状況や、準拠していないリソース、拒否されたイベント発生数などを確認することができます。
※割り当て後、状況取得にはある程度時間がかかります。

以下は別のポリシーのキャプチャですが、時間が経つとポリシーの準拠していないリソースがどのくらいあるのか表示してくれます。

イベントを発生させたユーザーもわかるので、誰が設定を行おうとしたか、ばっちりわかります。

料金
Azureポリシーの利用料金は発生しないため、好きなだけ使えます。
気になること
ルールに合致した設定を拒否できるAzureポリシーですが、ちょっと気になる箇所があります。
それは、ユーザーが自分で設定した際は拒否してくれるのですが、システム的に設定される場合は拒否されない、という点です。
例として試したのは、VM作成時の以下の設定です。

このチェック用いると、VMデプロイ時のインターフェースに割り当てられるNSGに対して自動でルールを追加してくれます。 ただし、ソースIPアドレスがAnyなのです。
しかも悲しいことに、今回のポリシーを適用していても、拒否されずにデプロイされてしまいます。
まぁ、以前は警告なくAny許可でしたが、最近は「すべてのIPアドレスからアクセス可能になります」と注意を明記してくれるだけマシになりました。 システム的に防ぎたいところですがダメそうです。。。
このオプションを使ってデプロイすることは防げなさそうなので、自動で修復するようにポリシー側を整備しておくしかないのかなと思います。
おわりに
今回は、Azureポリシーでリソースの設定値を制限する、ということを紹介しました。
組み込みのポリシーで済むようであればそれだけで、費用なく設定が可能です。 もし求めるものがない場合は作成するしかありませんが、記事中で紹介したサンプルページもあるため、それを参考にするのが良いかと思います。
環境全てをポリシーで制御しようと思うとひたすらJSON記述になり大変ですが、これは絶対使わせない!という設定を制御するにはよいかと思います。