Private Link と DNS の大規模な統合
この記事では、ハブ アンド スポーク ネットワーク アーキテクチャに Azure プライベート DNS ゾーンがあるサービスとしてのプラットフォーム (PaaS) ソリューション用の Azure Private Link を統合する方法について説明します。
紹介
多くのお客様は、ハブアンドスポーク ネットワーク アーキテクチャを使用して Azure でネットワーク インフラストラクチャを構築します。次のような場合があります。
- ネットワーク仮想アプライアンス (NVA)、ExpressRoute/VPN ゲートウェイ、DNS サーバーなどのネットワーク共有サービスは、仮想ネットワーク
ハブにデプロイします。 - スポーク仮想ネットワークでは、仮想ネットワーク ピアリングを介して共有サービスを使用します。
ハブ アンド スポーク ネットワーク アーキテクチャでは、通常、アプリケーション所有者は Azure サブスクリプションを持っています。これには、
Azure Firewall などの中央 NVA は、インターネット送信接続を提供します。 さらに、ハブ内またはハブの近くにある、Azure Firewall DNS プロキシなどの別のサービスと組み合わせたそのデバイスは、通常、DNS 転送をカスタマイズするために使用されます。
多くのアプリケーション チームは、Azure IaaS と PaaS リソースの組み合わせを使用してソリューションを構築します。 Azure SQL Managed Instance などの一部の Azure PaaS サービスは、顧客の仮想ネットワークにデプロイできます。 その結果、トラフィックは Azure ネットワーク内でプライベートのままになり、オンプレミスから完全にルーティングできます。
ただし、Azure Storage や Azure Cosmos DB などの一部の Azure PaaS サービスは、顧客の仮想ネットワークにデプロイできないため、パブリック エンドポイント経由でアクセスできます。 場合によっては、この構成によって顧客のセキュリティ ポリシーとの競合が発生します。 企業トラフィックでは、パブリック エンドポイント経由で SQL データベースなどの企業リソースのデプロイやアクセスが許可されない場合があります。
この記事では、アプリケーション チームがプライベート エンドポイント経由でのみアクセスできる Azure PaaS サービスをサブスクリプションにデプロイする方法について説明します。
この記事では、アプリケーション チームがサービスをプライベート DNS ゾーンと自動的に統合する方法についても説明します。 Azure プライベート DNS を使用して自動化を行います。これにより、DNS でレコードを手動で作成または削除する必要がなくなります。
ハブアンドスポーク ネットワーク アーキテクチャでの Private Link と DNS の統合
プライベート DNS ゾーンは、通常、ハブ仮想ネットワークがデプロイされるのと同じ Azure サブスクリプションで一元的にホストされます。 この中央ホスティングプラクティスは、クロスプレミス DNS 名前解決 と、Windows Server Active Directory などの中央 DNS 解決に関するその他のニーズによって推進されます。 ほとんどの場合、ゾーン内の DNS レコードを管理するアクセス許可を持つのは、ネットワーク管理者と ID 管理者だけです。
アプリケーション チームには、独自のサブスクリプションで Azure リソースを作成するためのアクセス許可があります。 プライベート DNS ゾーンでの DNS レコードの管理を含む、中央ネットワーク接続サブスクリプションにはアクセス許可がありません。 このアクセス制限は、プライベート エンドポイントを使用して Azure PaaS サービスをデプロイするときに 必要な DNS レコードを
次の図は、Azure プライベート DNS を介した Private Link リソースの中央 DNS 解決と名前解決を備えたエンタープライズ環境の一般的な概要アーキテクチャを示しています。
前の図では、次の点を強調することが重要です。
オンプレミスの DNS サーバーには、ハブ仮想ネットワークでホストされている DNS プライベート リゾルバーを指す、プライベート エンドポイントパブリック DNS ゾーンごとに条件付きフォワーダーが構成されています。
ハブ仮想ネットワークでホストされている DNS プライベート リゾルバーは、フォワーダーとして Azure 提供の DNS (168.63.129.16) を使用します。
ハブ仮想ネットワークは、図に示すように、
privatelink.blob.core.windows.net
などの Azure サービスのプライベート DNS ゾーン名にリンクされている必要があります。すべての Azure 仮想ネットワークは、ハブ仮想ネットワークでホストされている DNS プライベート リゾルバーを使用します。
DNS プライベート リゾルバーは、単なるフォワーダーであるため、Active Directory ドメイン名などの顧客の企業ドメインに対して権限がありません。 DNS プライベート リゾルバーには、オンプレミスの DNS サーバー (172.16.1.10 と 172.16.1.11) またはそのようなゾーンに対して権限のある Azure にデプロイされた DNS サーバーを指す、顧客の企業ドメインへの送信エンドポイント フォワーダーが必要です。
手記
ExpressRoute ゲートウェイと共に、ハブ仮想ネットワークに DNS プライベート リゾルバーをデプロイできます。 ただし、パブリック FQDN の解決が許可され、DNS 転送ルール セットルールを介して有効な応答で対象の DNS サーバーに応答することを確認する必要があります。 一部の Azure サービスは、パブリック DNS 名を機能させるために解決する機能に依存しています。 詳細については、「DNS 転送ルール セットルールを参照してください。
前の図は単一のハブアンドスポーク アーキテクチャを示していますが、回復性、近接性、またはデータ所在地の要件に対処するために、複数のリージョンにわたって Azure フットプリントを拡張することが必要になる場合があります。 複数のシナリオでは、同じ Private Link 対応 PaaS インスタンスに複数のプライベート エンドポイントを介してアクセスする必要があります。
次の図は、プライベート リンク リソースの名前解決が Azure プライベート DNS 経由で行われるハブ (リージョンごとに 1 つ) に中央 DNS 解決がデプロイされているエンタープライズ環境の一般的な概要アーキテクチャを示しています。
PaaS インスタンスに関連付けられている複数のリージョンプライベート エンドポイントを、クライアントが存在する各リージョンに 1 つずつデプロイする必要があります。 リージョンごとに Private Link ゾーンとプライベート DNS ゾーンを有効にします。 geo 冗長ストレージ アカウントや SQL データベース フェールオーバー グループなど、ディザスター リカバリー機能が組み込まれている PaaS サービスを使用する場合は、複数のリージョンにプライベート エンドポイントが必要です。
このシナリオでは、現在のところ自動ライフサイクル管理がないため、すべてのリージョンで Private Link DNS レコード セットの手動メンテナンスと更新が必要です。
その他のユース ケースでは、1 つのグローバル プライベート エンドポイントをデプロイし、関連するリージョンから 1 つのリージョン内の単一のプライベート エンドポイントへのルーティングを追加することで、すべてのクライアントからアクセスできるようにします。
オンプレミス ネットワークから privatelink
プライベート DNS ゾーンとプライベート エンドポイントへの解決と接続を有効にするには、DNS インフラストラクチャに、条件付きフォワーダーなどの適切な DNS 構成をプロビジョニングします。
アプリケーション チームがサブスクリプションに必要な Azure PaaS リソースを作成するには、次の 2 つの条件を満たす必要があります。
中央ネットワークチームまたは中央プラットフォーム チームは、アプリケーション チームがプライベート エンドポイント経由でのみ Azure PaaS サービスをデプロイしてアクセスできるようにする必要があります。
中央ネットワークまたは中央プラットフォーム チームは、プライベート エンドポイントを作成するときに、対応するレコードの処理方法を設定する必要があります。 対応するレコードを、作成するサービスに一致する一元化されたプライベート DNS ゾーンに自動的に作成されるように設定します。
DNS レコードは、プライベート エンドポイントが削除されたときにレコードが自動的に削除されるように、プライベート エンドポイントのライフサイクルに従う必要があります。
手記
DNS 解決に基づき、Azure Firewall と Azure Firewall ポリシーのネットワーク規則 で FQDN を
次のセクションでは、アプリケーション チームが Azure Policyを使用してこれらの条件
プラットフォーム チームの構成要件
プラットフォーム チームの構成要件には、プライベート DNS ゾーンの作成、ポリシー定義の設定、ポリシーの展開、ポリシーの割り当ての設定が含まれます。
プライベート DNS ゾーンを作成する
サポートされている Private Link サービスの中央接続サブスクリプションにプライベート DNS ゾーンを作成します。 詳細については、Azure プライベート エンドポイントの DNS 構成
この場合、BLOB を使用 privatelink.blob.core.windows.net
プライベート DNS ゾーンを作成することに変換されます。
ポリシー定義を作成する
プライベート DNS ゾーンに加えて、一連のカスタム Azure Policy 定義を作成する必要もあります。 これらの定義では、プライベート エンドポイントの使用が強制され、作成した DNS ゾーンに DNS レコードの作成が自動化されます。
PaaS サービス ポリシーの
Deny
パブリック エンドポイント。このポリシーにより、ユーザーはパブリック エンドポイントを使用して Azure PaaS サービスを作成できなくなります。
リソースの作成時にプライベート エンドポイントを選択しないと、ユーザーにエラー メッセージが表示されます。
PaaS サービスによって正確なポリシー規則が異なる場合があります。 Azure Storage アカウントの場合、networkAcls.defaultAction プロパティは、パブリック ネットワークからの要求を許可するかどうかを定義します。 この場合、プロパティ networkAcls.defaultAction が
Deny
でない場合、Microsoft.Storage/storageAccounts のリソースタイプの作成を拒否するよう条件を設定します。 次のポリシー定義は、動作を示しています。{ "mode": "All", "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Storage/storageAccounts" }, { "field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction", "notEquals": "Deny" } ] }, "then": { "effect": "Deny" } } }
Deny
privatelink
プレフィックス ポリシーを使用してプライベート DNS ゾーンを作成する機能。プラットフォーム チームによって管理されるサブスクリプションでホストされている条件付きフォワーダーとプライベート DNS ゾーンを使用して、一元化された DNS アーキテクチャを使用します。 アプリケーション チームの所有者が独自の Private Link プライベート DNS ゾーンを作成し、サービスをサブスクリプションにリンクできないようにする必要があります。
アプリケーション チームがプライベート エンドポイントを作成するときに、
Integrate with private DNS zone
するオプションが Azure portal でNo
に設定されていることを確認します。Yes
を選択すると、Azure Policy によってプライベート エンドポイントが作成されなくなります。 ポリシー定義では、ゾーンにprivatelink
プレフィックスがある場合、Microsoft.Network/privateDnsZones リソースの種類を作成する機能が拒否されます。 次のポリシー定義は、privatelink
プレフィックスを示しています。{ "description": "This policy restricts creation of private DNS zones with the `privatelink` prefix", "displayName": "Deny-PrivateDNSZone-PrivateLink", "mode": "All", "parameters": null, "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Network/privateDnsZones" }, { "field": "name", "contains": "privatelink." } ] }, "then": { "effect": "Deny" } } }
DeployIfNotExists
ポリシーを使用して、中央プライベート DNS ゾーンに必要な DNS レコードを自動的に作成します。次のポリシー例は、プライベート エンドポイントで作成される
privateDNSZoneGroup
を識別するための 2 つの方法を示しています。最初のポリシー は
groupId
に依存し、2 番目のポリシー はprivateLinkServiceId
とgroupID
の両方を使用します。groupId
が競合したり、別のリソースと競合したりする場合は、2 番目のポリシー を使用します。たとえば、
groupId
SQL は、Azure Cosmos DB と Azure Synapse Analytics の両方に使用されます。 両方のリソースの種類がデプロイされ、最初のポリシー がプライベート エンドポイント エントリにprivateDNSZoneGroup
を作成するように割り当てられている場合は、Azure Cosmos DB または Azure Synapse Analytics の間違ったプライベート DNS ゾーンに作成され、マップされます。 この場合、groupId
が、最初のポリシーによってそのポリシー規則内で検索されるものと競合するために、各ゾーン間で切り替えが行われる場合があります。Private Link リソースの
groupId
の一覧については、「プライベート エンドポイントとは」のサブリソース列を参照してください。.
ヒント
Azure Policy の組み込み定義は、常に追加、削除、更新されています。 使用可能な場合は、独自のポリシーを管理する代わりに、組み込みのポリシーを使用する必要があります。 AzPolicyAdvertizer を使用して、「xxx... を使用してプライベート DNS ゾーンを使用する」の名前を持つ既存の組み込みポリシーを検索します。 さらに、Azure Landing Zones (ALZ) にはポリシー イニシアチブがあります。定期的に更新される組み込みのポリシーを含むプライベート DNS ゾーンを使用するように Azure PaaS サービスを構成します。 状況に合わせて組み込みのポリシーを使用できない場合は、Azure Policy GitHub リポジトリの
groupId のみの DeployIfNotExists ポリシー
このポリシーは、サービス固有の groupId
を持つプライベート エンドポイント リソースを作成した場合にトリガーされます。 groupId
は、このプライベート エンドポイントが接続する必要があるリモート リソース (サービス) から取得したグループの ID です。 その後、プライベート エンドポイント内で privateDNSZoneGroup
のデプロイをトリガーし、プライベート エンドポイントをプライベート DNS ゾーンに関連付けます。 この例では、Azure Storage の BLOB において、groupId
が blob
です。 他の Azure サービスの groupId
を検出すると、プライベート エンドポイント内に privateDNSZoneGroup
をデプロイし、パラメーターとして指定されたプライベート DNS ゾーン リソース ID にリンクします。 この例では、プライベート DNS ゾーンのリソース ID は次のとおりです。
/subscriptions/<subscription-id>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net
次のコード サンプルは、ポリシー定義を示しています。
{
"mode": "Indexed",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/privateEndpoints"
},
{
"count": {
"field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]",
"where": {
"field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]",
"equals": "blob"
}
},
"greaterOrEquals": 1
}
]
},
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
],
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"privateDnsZoneId": {
"type": "string"
},
"privateEndpointName": {
"type": "string"
},
"location": {
"type": "string"
}
},
"resources": [
{
"name": "[concat(parameters('privateEndpointName'), '/deployedByPolicy')]",
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "storageBlob-privateDnsZone",
"properties": {
"privateDnsZoneId": "[parameters('privateDnsZoneId')]"
}
}
]
}
}
]
},
"parameters": {
"privateDnsZoneId": {
"value": "[parameters('privateDnsZoneId')]"
},
"privateEndpointName": {
"value": "[field('name')]"
},
"location": {
"value": "[field('location')]"
}
}
}
}
}
}
},
"parameters": {
"privateDnsZoneId": {
"type": "String",
"metadata": {
"displayName": "privateDnsZoneId",
"strongType": "Microsoft.Network/privateDnsZones"
}
}
}
}
groupId と privateLinkServiceId の DeployIfNotExists ポリシー
このポリシーは、サービス固有の groupId
と privateLinkServiceId
を使用してプライベート エンドポイント リソースを作成した場合にトリガーされます。 groupId
は、このプライベート エンドポイントが接続する必要があるリモート リソース (サービス) から取得したグループの ID です。 privateLinkServiceId
は、このプライベート エンドポイントが接続する必要があるリモート リソース (サービス) のリソース ID です。 次に、プライベート エンドポイント内の privateDNSZoneGroup
のデプロイをトリガーします。これにより、プライベート エンドポイントがプライベート DNS ゾーンに関連付けられます。
この例では、Azure Cosmos DB (SQL) の groupId
が SQL
され、privateLinkServiceId
に Microsoft.DocumentDb/databaseAccounts
が含まれている必要があります。 他の Azure サービスの groupId
と privateLinkServiceId
を検出すると、プライベート エンドポイント内に privateDNSZoneGroup
をデプロイします。 また、パラメーターとして指定されているプライベート DNS ゾーン リソース ID にリンクされています。 次のポリシー定義は、プライベート DNS ゾーンリソース ID を示しています。
/subscriptions/<subscription-id>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/privateDnsZones/privatelink.documents.azure.com
次のコード サンプルは、ポリシー定義を示しています。
{
"mode": "Indexed",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/privateEndpoints"
},
{
"count": {
"field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*]",
"where": {
"allOf": [
{
"field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].privateLinkServiceId",
"contains": "Microsoft.DocumentDb/databaseAccounts"
},
{
"field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]",
"equals": "[parameters('privateEndpointGroupId')]"
}
]
}
},
"greaterOrEquals": 1
}
]
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
],
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"privateDnsZoneId": {
"type": "string"
},
"privateEndpointName": {
"type": "string"
},
"location": {
"type": "string"
}
},
"resources": [
{
"name": "[concat(parameters('privateEndpointName'), '/deployedByPolicy')]",
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "cosmosDB-privateDnsZone",
"properties": {
"privateDnsZoneId": "[parameters('privateDnsZoneId')]"
}
}
]
}
}
]
},
"parameters": {
"privateDnsZoneId": {
"value": "[parameters('privateDnsZoneId')]"
},
"privateEndpointName": {
"value": "[field('name')]"
},
"location": {
"value": "[field('location')]"
}
}
}
}
}
}
},
"parameters": {
"privateDnsZoneId": {
"type": "String",
"metadata": {
"displayName": "Private Dns Zone Id",
"description": "The private DNS zone to deploy in a new private DNS zone group and link to the private endpoint",
"strongType": "Microsoft.Network/privateDnsZones"
}
},
"privateEndpointGroupId": {
"type": "String",
"metadata": {
"displayName": "Private Endpoint Group Id",
"description": "A group Id for the private endpoint"
}
},
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "Enable or disable the execution of the policy"
},
"allowedValues": [
"DeployIfNotExists",
"Disabled"
],
"defaultValue": "DeployIfNotExists"
}
}
}
ポリシーの割り当て
ポリシー定義が展開されたら、管理グループ階層内の目的のスコープで ポリシーを割り当てます。 ポリシーの割り当てが、プライベート エンドポイント アクセスのみを使用して PaaS サービスをデプロイするためにアプリケーション チームが使用する Azure サブスクリプションを対象にしていることを確認します。
重要
ポリシーで定義されている roleDefinition を割り当てる
プラットフォーム チームが構成を完了したら、次の手順を実行します。
アプリケーション チームの Azure サブスクリプションは、排他的なプライベート エンドポイント アクセスを持つ Azure PaaS サービスをチームが作成する準備ができています。
チームは、プライベート エンドポイントの DNS レコードが対応するプライベート DNS ゾーンに自動的に登録されていること、およびプライベート エンドポイントが削除された後に DNS レコードが削除されることを確認する必要があります。
アプリケーション所有者が Azure PaaS サービスをデプロイする
プラットフォーム チームがプラットフォーム インフラストラクチャ コンポーネント (プライベート DNS ゾーンとポリシー) をデプロイした後、アプリケーション所有者は、Azure PaaS サービスを Azure サブスクリプションにデプロイしようとしたときに、次の手順を実行します。 これらの手順は、Azure portal または PowerShell や CLI などの他のクライアントを介してアクティビティを実行する場合でも同じです。これは、Azure ポリシーによってサブスクリプションが管理されるためです。
Azure portal を使用してストレージ アカウントを作成します。 [
基本 ] タブで、目的の設定を選択し、ストレージ アカウントの名前を指定して、[次へ]選択します。 [ネットワーク] タブで、[プライベート エンドポイント ] を選択します。 プライベート エンドポイント以外のオプションを選択した場合、Azure portal では、デプロイ ウィザードの [確認と作成] セクションでストレージ アカウントを作成 できません。 ポリシーを使用すると、パブリック エンドポイントが有効になっている場合に、このサービスを作成できなくなります。
ストレージ アカウントの作成後または作成後にプライベート エンドポイントを作成できます。 この例では、ストレージ アカウントの作成後にプライベート エンドポイントを作成する方法を示します。 [確認と作成] を選択して、手順を完了します。
ストレージ アカウントを作成したら、Azure portal を使用してプライベート エンドポイントを作成します。
[リソース] セクションで、前の手順で作成したストレージ アカウントを見つけます。 [ターゲット サブリソース] で [Blob] を選択し、[次へ] を選択します。
[
構成 ] セクションで、仮想ネットワークとサブネットを選択した後、プライベート DNS ゾーンとの統合 が [なし]に設定されていることを確認します。 それ以外の場合、Azure portal ではプライベート エンドポイントを作成できなくなります。 Azure Policy では、 privatelink
プレフィックスを持つプライベート DNS ゾーンを作成することはできません。[確認と作成]、[作成] の順に選択して、プライベート エンドポイントをデプロイします。
数分後に、
DeployIfNotExists
ポリシーがトリガーされます。 その後のdnsZoneGroup
デプロイでは、中央管理 DNS ゾーン内のプライベート エンドポイントに必要な DNS レコードが追加されます。プライベート エンドポイントを作成したら、それを選択し、その FQDN とプライベート IP を確認します。
プライベート エンドポイントが作成されたリソース グループのアクティビティ ログを確認します。 または、プライベート エンドポイント自体のアクティビティ ログを確認することもできます。 数分後、
DeployIfNotExist
ポリシー アクションが実行され、プライベート エンドポイントで DNS ゾーン グループが構成されます。中央ネットワーク チームが
privatelink.blob.core.windows.net
プライベート DNS ゾーンに移動した場合、作成したプライベート エンドポイントの DNS レコードが存在し、名前と IP アドレスの両方がプライベート エンドポイント内の値と一致することを確認します。
この時点で、アプリケーション チームは、ハブ アンド スポーク ネットワーク環境の任意の仮想ネットワークとオンプレミスのプライベート エンドポイントを介してストレージ アカウントを使用できます。 DNS レコードは、プライベート DNS ゾーンに自動的に記録されています。
アプリケーション所有者がプライベート エンドポイントを削除すると、プライベート DNS ゾーン内の対応するレコードが自動的に削除されます。
重要
コード ツールとしてインフラストラクチャにプライベート エンドポイントを作成することもできます。 ただし、この記事の DeployIfNotExists
ポリシー アプローチを使用する場合は、コードに DNS を統合しないでください。 プライベート DNS ゾーンに対して必要な RBAC を持つ DeployIfNotExists
ポリシーは、DNS 統合を管理します。
次の手順
- オンプレミスリソースと Azure リソースの DNS
- 仮想マシンのリモート アクセス に Azure Bastion を使用する
- クイック スタート: Bicepを使用してプライベート エンドポイントを作成します。
- Terraform Registry の azurerm_private_endpoint リソースを使用してプライベート エンドポイントを作成します。