チュートリアル: 仮想ネットワーク統合を使用して Azure App Service のバックエンド通信を分離する
この記事では、ネットワーク分離によってバックエンド サービスと安全に通信を行う App Service アプリを構成します。 「チュートリアル: Key Vault を使用して App Service からの Cognitive Services 接続を保護する」のシナリオを例として使用しています。 完了すると、Azure 仮想ネットワークを介して Key Vault と Azure AI サービスの両方にアクセスする App Service アプリが完成します。これらのバックエンド リソースに他のトラフィックがアクセスすることはできません。 仮想ネットワーク内では、仮想ネットワーク統合とプライベート エンドポイントを使用して、すべてのトラフィックが分離されます。
App Service アプリから他の Azure サービスに向かうアウトバウンド ネットワーク トラフィックは、マルチテナントのサービスとして、他のアプリや他のサブスクリプションと同じ環境を共有します。 トラフィック自体を暗号化することもできますが、一部のシナリオでは、バックエンド通信を他のネットワーク トラフィックから分離することでいっそう高いセキュリティが求められることがあります。 一般に、そのようなシナリオに対応できるのは高度なノウハウを持つ大企業に限られますが、App Service では、仮想ネットワーク統合によってそれが身近なものになります。
このアーキテクチャでは、次のことが行われます。
- バックエンド サービスへのパブリック トラフィックがブロックされます。
- App Service からのアウトバウンド トラフィックが仮想ネットワークにルーティングされてバックエンド サービスに到達できます。
- App Service はプライベート DNS ゾーンを通じて、バックエンド サービスへの DNS 解決を実行できます。
学習内容
- App Service 仮想ネットワーク統合用の仮想ネットワークとサブネットを作成する
- プライベート DNS ゾーンを作成する
- プライベート エンドポイントを作成する
- App Service で仮想ネットワーク統合を構成する
前提条件
このチュートリアルは、読者が「チュートリアル: Key Vault を使用して App Service からの Cognitive Services 接続を保護する」に従って言語検出アプリを作成済みであることを想定しています。
前のチュートリアルでも使用していた次の環境変数を引き続き使用します。 適切に設定されていることを確認してください。
groupName=myKVResourceGroup
region=westeurope
csResourceName=<cs-resource-name>
appName=<app-name>
vaultName=<vault-name>
仮想ネットワークとサブネットの作成
仮想ネットワークを作成します。 <virtual-network-name> を一意の名前に置き換えます。
# Save vnet name as variable for convenience vnetName=<virtual-network-name> az network vnet create --resource-group $groupName --location $region --name $vnetName --address-prefixes 10.0.0.0/16
App Service 仮想ネットワーク統合用のサブネットを作成します。
az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name vnet-integration-subnet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Web/serverfarms --disable-private-endpoint-network-policies false
App Service の仮想ネットワーク統合サブネットには、少なくとも
/26
の CIDR ブロックを割り当てることをお勧めします (仮想ネットワーク統合のサブネット要件を参照)。/24
では、必要以上のサイズになってしまいます。--delegations Microsoft.Web/serverfarms
では、サブネットを App Service の仮想ネットワーク統合に委任することを指定します。プライベート エンドポイント用に別のサブネットを作成します。
az network vnet subnet create --resource-group $groupName --vnet-name $vnetName --name private-endpoint-subnet --address-prefixes 10.0.1.0/24 --disable-private-endpoint-network-policies true
プライベート エンドポイントのサブネットでは、プライベート エンドポイントのネットワーク ポリシーを無効にする必要があります。
プライベート DNS ゾーンを作成する
Key Vault と Azure AI サービスのリソースは、プライベート エンドポイントの背後に置かれるため、それらのためのプライベート DNS ゾーンを定義する必要があります。 これらのゾーンはプライベート エンドポイントの DNS レコードのホストとして使用され、クライアントは、このゾーンがあることで、バックエンド サービスを名前で見つけることができます。
Azure AI サービス リソース用と Key Vault 用に 2 つのプライベート DNS ゾーンを作成します。
az network private-dns zone create --resource-group $groupName --name privatelink.cognitiveservices.azure.com az network private-dns zone create --resource-group $groupName --name privatelink.vaultcore.azure.net
これらの設定の詳細については、「Azure プライベート エンドポイントの DNS 構成」を参照してください。
仮想ネットワークにプライベート DNS ゾーンをリンクします。
az network private-dns link vnet create --resource-group $groupName --name cognitiveservices-zonelink --zone-name privatelink.cognitiveservices.azure.com --virtual-network $vnetName --registration-enabled False az network private-dns link vnet create --resource-group $groupName --name vaultcore-zonelink --zone-name privatelink.vaultcore.azure.net --virtual-network $vnetName --registration-enabled False
プライベート エンドポイントを作成する
仮想ネットワークのプライベート エンドポイント サブネットに、Cognitive Service 用のプライベート エンドポイントを作成します。
# Get Cognitive Services resource ID csResourceId=$(az cognitiveservices account show --resource-group $groupName --name $csResourceName --query id --output tsv) az network private-endpoint create --resource-group $groupName --name securecstext-pe --location $region --connection-name securecstext-pc --private-connection-resource-id $csResourceId --group-id account --vnet-name $vnetName --subnet private-endpoint-subnet
Azure AI サービス プライベート エンドポイントの DNS ゾーン グループを作成します。 DNS ゾーン グループは、プライベート DNS ゾーンとプライベート エンドポイント間のリンクです。 このリンクを使用すると、プライベート エンドポイントに更新がある場合に、プライベート DNS ゾーンを自動更新できます。
az network private-endpoint dns-zone-group create --resource-group $groupName --endpoint-name securecstext-pe --name securecstext-zg --private-dns-zone privatelink.cognitiveservices.azure.com --zone-name privatelink.cognitiveservices.azure.com
Azure AI サービス リソースに対するパブリック トラフィックをブロックします。
az rest --uri $csResourceId?api-version=2021-04-30 --method PATCH --body '{"properties":{"publicNetworkAccess":"Disabled"}}' --headers 'Content-Type=application/json' # Repeat following command until output is "Succeeded" az cognitiveservices account show --resource-group $groupName --name $csResourceName --query properties.provisioningState
Note
変更のプロビジョニングの状態が
"Succeeded"
になっていることを確認します。 その後、サンプル アプリで動作変更を観察してください。 以前と同様、アプリを読み込むことはできますが、 [Detect](検出) ボタンをクリックするとHTTP 500
エラーが返されます。 共有ネットワーク経由での Azure AI サービス リソースへの接続は失われています。Key Vault に対して上記の手順を繰り返します。
# Create private endpoint for key vault vaultResourceId=$(az keyvault show --name $vaultName --query id --output tsv) az network private-endpoint create --resource-group $groupName --name securekeyvault-pe --location $region --connection-name securekeyvault-pc --private-connection-resource-id $vaultResourceId --group-id vault --vnet-name $vnetName --subnet private-endpoint-subnet # Create DNS zone group for the endpoint az network private-endpoint dns-zone-group create --resource-group $groupName --endpoint-name securekeyvault-pe --name securekeyvault-zg --private-dns-zone privatelink.vaultcore.azure.net --zone-name privatelink.vaultcore.azure.net # Block public traffic to key vault az keyvault update --name $vaultName --default-action Deny
アプリ設定をリセットして、その Key Vault 参照の再フェッチを強制的に即時実行します (詳細については、ローテーションに関するセクションを参照してください)。
az webapp config appsettings set --resource-group $groupName --name $appName --settings CS_ACCOUNT_NAME="@Microsoft.KeyVault(SecretUri=$csResourceKVUri)" CS_ACCOUNT_KEY="@Microsoft.KeyVault(SecretUri=$csKeyKVUri)"
Note
もう一度、サンプル アプリで動作変更を観察してください。 アプリを読み込むことができません。Key Vault の参照にアクセスできなくなったためです。 共有ネットワーク経由での Key Vault への接続は失われています。
2 つのプライベート エンドポイントにアクセスできるのは、作成した仮想ネットワーク内のクライアントのみです。 Azure portal の [シークレット] ページから Key Vault 内のシークレットにアクセスすることもできません。ポータルからのアクセスにはパブリック インターネットが使用されるためです (「ロック ダウンされたリソースを管理する」を参照)。
アプリで仮想ネットワーク統合を構成する
サポートされている価格レベルにアプリをスケールアップします (「アプリを Azure 仮想ネットワークと統合する」を参照)。
az appservice plan update --name $appName --resource-group $groupName --sku S1
今回のシナリオには関係ありませんが、インバウンド要求には HTTPS を適用することが重要です。
az webapp update --resource-group $groupName --name $appName --https-only
アプリで仮想ネットワーク統合を有効にします。
az webapp vnet-integration add --resource-group $groupName --name $appName --vnet $vnetName --subnet vnet-integration-subnet
仮想ネットワーク統合により、アウトバウンド トラフィックを仮想ネットワークに直接流すことができます。 既定では、RFC-1918 で定義されているローカル IP トラフィックのみが仮想ネットワークにルーティングされます。これはプライベート エンドポイントに必要な動作です。 すべてのトラフィックを仮想ネットワークにルーティングする場合は、仮想ネットワーク統合のルーティングの管理に関するページを参照してください。 すべてのトラフィックのルーティングは、Azure Virtual Network NAT や Azure Firewall など、仮想ネットワーク経由でインターネット トラフィックをルーティングする場合にも使用できます。
ブラウザーで再び
<app-name>.azurewebsites.net
に移動し、統合が有効になるまで待ちます。 HTTP 500 エラーが発生する場合は、数分待ってからやり直してください。 ページを読み込んで検出結果を取得できた場合は、キー コンテナー参照を使用して Azure AI サービス エンドポイントに接続しています。Note
しばらく待っても HTTP 500 エラーが返される場合は、再度、Key Vault 参照の再フェッチを強制的に実行してみてください。
az webapp config appsettings set --resource-group $groupName --name $appName --settings CS_ACCOUNT_NAME="@Microsoft.KeyVault(SecretUri=$csResourceKVUri)" CS_ACCOUNT_KEY="@Microsoft.KeyVault(SecretUri=$csKeyKVUri)"
ロック ダウンされたリソースを管理する
シナリオによっては、プライベート エンドポイントによって保護されたリソースを Azure portal、Azure CLI、Azure PowerShell から管理できない場合があります (Key Vault など)。 これらのツールは、いずれも REST API 呼び出しを実行してパブリック インターネット経由でリソースにアクセスするため、ここで行った構成によってブロックされます。 ロック ダウンされたリソースには、以下に示したいくつかの方法でアクセスできます。
- Key Vault のプライベート エンドポイントによって保護されたシークレットを表示したり更新したりするには、ローカル コンピューターのパブリック IP を追加します。
- オンプレミス ネットワークが VPN ゲートウェイまたは ExpressRoute を介して Azure 仮想ネットワークに拡張されている場合、プライベート エンドポイントによって保護されたリソースをオンプレミス ネットワークから直接管理できます。
- プライベート エンドポイントによって保護されたリソースを、仮想ネットワーク内のジャンプ サーバーから管理します。
- 仮想ネットワークに Cloud Shell をデプロイします。
リソースをクリーンアップする
前の手順では、リソース グループ内に Azure リソースを作成しました。 これらのリソースが将来必要になると想定していない場合、Cloud Shell で次のコマンドを実行して、リソース グループを削除します。
az group delete --name $groupName
このコマンドの実行には、少し時間がかかる場合があります。