今回は Private Subnet を強制する方法を Azure Policy で考えてみました
更新履歴
日付 | 内容 |
---|---|
2023-12-29 | Audit Policy について追記しました |
2023-12-29 | サブネットの委任ついて考慮しました |
Private Subnet とは
Private Subnet の話をするためには規定の送信アクセスを理解する必要があります
興味がある人は以下を見てみてください
企業で Azure を利用する場合, 通信を管理するために Firewall や NVA を使うケースがあります
しかし, 規定の送信アクセスが働くことで Firewall や NVA を介さずにインターネットに通信できてしまいます
Private Subnet を有効化すると規定の送信アクセスを無効化することができます
よって, 上で書いたような “Firewall や NVA を介さずにインターネットに通信する” ことを防げます
Private Subnet の有効化
Private Subnet の有効化方法は以下の公開情報に記載されています
- Azure portal で、Virtual Network の作成エクスペリエンスの一部としてサブネットを作成するときに、次に示すように、プライベート サブネットを有効にするオプションが選択されていることを確認します。
- CLI を使用して、az network vnet subnet create でサブネットを作成する場合は、–default-outbound オプションを使用し、“false” を選択します
- Azure Resource Manager テンプレートを使用して、defaultOutboundAccess パラメータの値を “false” に設定します
Azure での既定の送信アクセス - Azure Virtual Network | Microsoft Learn
これらの方法はサブネットを作成するユーザーが有効化するかどうかを決定できます
ユーザーに委任するのではなく Private Subnet を強制したいというのが今回の目的です
前提条件
- この記事は 2023/12 時点の情報に基づいています
- Private Subnet はプレビュー中なので使用する際は注意してください
- 今回は Azure Portal を使ってデプロイする場合だけを対象にしています
サブネット作成の挙動
サブネット作成の挙動でハマった点が2つあります
実装方法だけ知りたい場合は読み飛ばして 実装イメージ から読んでください
Vnet のプロパティ? サブネットというリソース?
そのままなのですが, サブネットは作成するタイミングによって
- Vnet (Microsoft.Network/virtualNetworks) のプロパティと扱われる場合
- Subnet (Microsoft.Network/virtualNetworks/subnets) というリソースの種類として扱われる場合
があるようです
たとえば、
https://github.com/NakayamaKento/AzurePolicy/blob/main/CustomPolicy/DenydefaultSubnet.json
に記載したポリシーを適用してみます
ポリシー規則のところだけ書き出してみました
|
|
想定する動作としては ‘default’ という名前のサブネットであれば作成を拒否するものです
対象となるリソースの種類をサブネット (Microsoft.Network/virtualNetworks/subnets) としています
実際に適用して、新規 Vnet を作成してみます

このように作成前の検証が通り、実際に作成も成功します
一方、既存 Vnet に ‘default’ という名前のサブネットを追加してみます

今度はポリシーによって操作が拒否されました
このことから
- Vnet を新規作成するとき (VM の新規作成の時と一緒に作るときも含める) は 1 に該当
- Vnetのプロパティと扱われる
- 既存の Vnet にサブネットを追加する場合は 2 に該当
- Subnet というリソースの種類として扱われる
ということがわかりました
Azure Policy を適用する場合は “なんのリソースの種類” に対するポリシーなのかを定義する必要があります
そのため, 1 と 2 の場合でポリシーを分けて考える必要があります
Private Subnet のパラメータ (defaultOutboundAccess) が存在しない
Private Subnet の有効化 で記載した通り、Private Subnet を有効化するのは ARM template 的には defaultOutboundAccess というパラメータを使います
Vnet の新規作成画面で、サブネットを編集すると図のように Private Subnet のオプションが表示されています
ここのチェックの有無で defaultOutboundAccess が true (=既定の送信アクセスが有効) または false (=既定の送信アクセスが無効) になります

次に、既存の Vnet にサブネットを追加してみます
Azure Portal の画面は下記のとおり、Private Subnet に関する項目がありません

その結果、そもそも Private Subnet を有効化することができません
ARM Template レベルで見ても defaultOutboundAccess のプロパティがそもそも存在していないことがわかります

このことから
- defaultOutboundAccess が存在する場合は false を強制 または true を拒否
- defaultOutboundAccess が存在しない場合は、false としてプロパティごと追加
という処理のパターンを考える必要があります
実装イメージ
前述のとおりサブネットは作成のタイミングで挙動が異なります
そのため以下のように実装します
シナリオ | リソースの種類 | 条件 | 効果 |
---|---|---|---|
Vnet の新規作成 | Vnet (Microsoft.Network/virtualNetworks) | すべてのサブネットで defaultOutboundAccess: false が設定されていない | 拒否(deny) |
(2023/12 時点) 既存 Vnet へサブネットを追加 | サブネット (Microsoft.Network/virtualNetworks/subnets) | defaultOutboundAccess: false が設定されていない | 追加 (append) |
(将来的に) 既存 Vnet へサブネットを追加 | サブネット (Microsoft.Network/virtualNetworks/subnets) | defaultOutboundAccess: false が設定されていない | 拒否(deny) |
考慮漏れ対策 | サブネット (Microsoft.Network/virtualNetworks/subnets) | defaultOutboundAccess: false が設定されていない | 監査 (Audit) |
Azure Policy ではポリシーにどんな機能を持たせるかを定義することができます
これを公式では効果と呼んでいます
効果には Audit, Deny, Modify などがあります
今回は defaultOutboundAccess を false に強制したいので modify で修正させたいです
しかし AzurePolicy/CustomPolicy/ModifyPrivateSubnet.json をデプロイしよとすると以下のエラーが表示されました
New-AzPolicyDefinition: InvalidPolicyRuleModifyDetails : The policy definition ‘Modify not Private Subnet’ has operations referring to aliases that are not modifiable: ‘Microsoft.Network/virtualnetworks/subnets/defaultOutboundAccess’. CorrelationId: 4c8ba7e9-39e4-4c56-a77c-41b74f25ba25
おそらく defaultOutboundAccess が新しいため Modify が対応していないのが原因です
公開情報にも以下の記載があり, Modify がサポートされていないという状況は存在します
そこで, Modify を諦めて Deny を使うことに決めました
※Append はプロパティが競合してエラーになりました
ただし、マネージド ID を作成できない場合や、リソース プロパティのエイリアスが Modify でまだサポートされていない場合は、Append を使用することをお勧めします。
実装
使用する Azure Policy をカスタムポリシーとして作成しました
ポリシー規則のところだけ書き出しておきます
シナリオ:Vnet の新規作成
|
|
AzurePolicy/CustomPolicy/DenyNotPrivateSubnet_NewVnet.json at main · NakayamaKento/AzurePolicy
同じでなければ作成を拒否する
シナリオ:(2023/12 時点) 既存 Vnet へサブネットを追加
|
|
AzurePolicy/CustomPolicy/AppendPrivateSubnet.json at main · NakayamaKento/AzurePolicy
シナリオ:(将来的に) 既存 Vnet へサブネットを追加
|
|
AzurePolicy/CustomPolicy/DenyNotPrivateSubnet_ExitingVnet.json at main · NakayamaKento/AzurePolicy
シナリオ:考慮漏れ対策
|
|
AzurePolicy/CustomPolicy/AuditNotPrivateSubnet.json at main · NakayamaKento/AzurePolicy
検証
実際に シナリオ:Vnet の新規作成 と シナリオ:(2023/12 時点) 既存 Vnet へサブネットを追加 を適用して Private Subnet が強制されるか確認してみます
Vnet の新規作成
新規 Vnet を作成するときに、1つだけサブネットを含むように作成しています

Private Subnet を有効化していないので、作成前の検証でポリシーで弾かれています

Private Subnet を有効化すると検証は無事に通りました
次にサブネットを2個作成するようにします

1つでも Private Subnet が有効化していないものがあれば、ポリシーで弾かれています

すべてのサブネットで Private Subnet を有効化すると検証は通りました
既存 Vnet へサブネットを追加
既存 Vnet にサブネットを追加します
検証時は Private Subnet を有効化するメニューはないので、通常通り作成します

作成後、ARM template を確認してみると defaultOutboundAccess:false が追加されていました

(2023/12/29 追加) 既存 Vnet へサブネットを追加。サブネットの委任付き
Private Subnet が有効化されているとサブネットの委任ができないことがわかりました

そこで Azure Policy を修正してサブネットの委任が設定されていない場合にだけ Private Subnet を有効化するようにしました
|
|
実際にサブネットの委任を設定してサブネットを追加すると、defaultOutboundAccess が追加されないようにできました

上記のポリシーでは以下のことは対応できません
- 既存のサブネットに対して委任設定を追加する
- Vnet の新規作成時に委任サブネットを作成する
- こちらについては Azure Portal の GUI 上ではそもそも作成できないので、今回は検討外とします
- 検証はしていませんが、一応ポリシーを考えています AzurePolicy/CustomPolicy/Preview_DenyNotPrivateSubnet_NewVnet.json
インターネットに出れないことの確認
defaultOutboundAccess:false にさせることができたので、実際にインターネットに出れないことを確認します
検証した VM は以下の通りです
VM 名 | 属するサブネット | サブネットの説明 |
---|---|---|
VM1 | default1 | Vnet の新規作成時に GUI で Private Subnet を有効化 |
VM2 | default2 | Vnet の新規作成時に GUI で Private Subnet を有効化 |
VM3 | default3 | Vnet の作成後にサブネットを追加。ポリシーで defaultOutboundAccess:false を追加 |



すべての VM において次のことがわかりました
- www.bing.com の名前解決はできているが、ブラウザでのアクセスができていない
- タスクバー上のネットワーク接続状態インジケーター を見るとインターネットアクセスができていない
まとめ
Azure Policy を使って Private Subnet を強制させることができました
強制した Private Subnet からインターネットに出れないことも確認できました
はじめてカスタムの Azure Policy を作成したので、うまくできてよかったです
参考
- Public preview: Private subnet | Azure の更新情報 | Microsoft Azure
- Azure での既定の送信アクセス - Azure Virtual Network | Microsoft Learn
- Azure Policy の概要 - Azure Policy | Microsoft Learn
- チュートリアル:カスタム ポリシー定義の作成 - Azure Policy | Microsoft Learn
- 効果のしくみを理解する - Azure Policy | Microsoft Learn
- ネットワーク接続状態インジケーター (NCSI) の概要とトラブルシュート | Microsoft Japan Windows Technology Support Blog