網路介面 (NIC):維護指定虛擬網路/子網路中私人 IP 位址的網路介面。 這是當您部署虛擬機 (VM) 時所部署的完全相同資源,但是不是指派給 VM,而是由私人端點所擁有。
私人 DNS 區域:如果您之前從未對此虛擬網路部署過私人端點,系統將會為虛擬網路部署新的私人 DNS 區域。 此 DNS 區域中的 Azure 資源也會建立 DNS A 記錄。 如果您已在此虛擬網路中部署私人端點,將會在現有的 DNS 區域中新增一筆 Azure 資源記錄。 部署 DNS 區域是選擇性的,但強烈建議您簡化所需的 DNS 管理。
注意
本文使用適用於 Azure 公用區域的 DNS 尾碼、適用於儲存體帳戶的 core.windows.net,以及儲存體同步服務的 afs.azure.net。 這也適用於 Azure 主權雲端,例如 Azure US Government 雲端,只需將適當的後綴取代為您的環境即可。
# Disable private endpoint network policies
$subnet.PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork = $virtualNetwork | `
Set-AzVirtualNetwork -ErrorAction Stop
# Create a private link service connection to the storage account.
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "$storageAccountName-Connection" `
-PrivateLinkServiceId $storageAccount.Id `
-GroupId "file" `
-ErrorAction Stop
# Create a new private endpoint.
$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName $storageAccountResourceGroupName `
-Name "$storageAccountName-PrivateEndpoint" `
-Location $virtualNetwork.Location `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnection `
-ErrorAction Stop
建立 Azure 私人 DNS 區域可讓儲存體帳戶的原始名稱 (例如 storageaccount.file.core.windows.net) 解析為虛擬網路內的私人 IP。 雖然從建立私人端點的角度來看,這是選擇性項目,但直接使用 AD 使用者主體來掛接 Azure 檔案共用或透過 REST API 來存取時,這確實是必要項目。
# Get the desired storage account suffix (core.windows.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
$storageAccountSuffix = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty StorageEndpointSuffix
# For public cloud, this will generate the following DNS suffix:
# privatelink.file.core.windows.net.
$dnsZoneName = "privatelink.file.$storageAccountSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create new one.
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
建立 Azure 私人 DNS 區域可讓儲存體帳戶的原始名稱 (例如 storageaccount.file.core.windows.net) 解析為虛擬網路內的私人 IP。 雖然從建立私人端點的角度來看,這是選擇性項目,但使用 AD 使用者主體來掛接 Azure 檔案共用或透過 REST API 來存取時,這確實是必要項目。
# Get the desired storage account suffix (core.windows.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
storageAccountSuffix=$(az cloud show \
--query "suffixes.storageEndpoint" | \
tr -d '"')
# For public cloud, this will generate the following DNS suffix:
# privatelink.file.core.windows.net.
dnsZoneName="privatelink.file.$storageAccountSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
possibleDnsZones=""
possibleDnsZones=$(az network private-dns zone list \
--query "[?name == '$dnsZoneName'].id" \
--output tsv)
dnsZone=""
possibleDnsZone=""
for possibleDnsZone in $possibleDnsZones
do
possibleResourceGroupName=$(az resource show \
--ids $possibleDnsZone \
--query "resourceGroup" | \
tr -d '"')
link=$(az network private-dns link vnet list \
--resource-group $possibleResourceGroupName \
--zone-name $dnsZoneName \
--query "[?virtualNetwork.id == '$virtualNetwork'].id" \
--output tsv)
if [ -z $link ]
then
echo "1" > /dev/null
else
dnsZoneResourceGroup=$possibleResourceGroupName
dnsZone=$possibleDnsZone
break
fi
done
if [ -z $dnsZone ]
then
# No matching DNS zone attached to virtual network, so create a new one
dnsZone=$(az network private-dns zone create \
--resource-group $virtualNetworkResourceGroupName \
--name $dnsZoneName \
--query "id" | \
tr -d '"')
az network private-dns link vnet create \
--resource-group $virtualNetworkResourceGroupName \
--zone-name $dnsZoneName \
--name "$virtualNetworkName-DnsLink" \
--virtual-network $virtualNetwork \
--registration-enabled false \
--output none
dnsZoneResourceGroup=$virtualNetworkResourceGroupName
fi
現在您已有私人 DNS 區域的參考,接下來您必須為儲存體帳戶建立 A 記錄。
privateEndpointNIC=$(az network private-endpoint show \
--ids $privateEndpoint \
--query "networkInterfaces[0].id" | \
tr -d '"')
privateEndpointIP=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[0].privateIPAddress" | \
tr -d '"')
az network private-dns record-set a create \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--name $storageAccountName \
--output none
az network private-dns record-set a add-record \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--record-set-name $storageAccountName \
--ipv4-address $privateEndpointIP \
--output none
如果您的虛擬網路內有 VM,或已如設定 Azure 檔案儲存體 的 DNS 轉送中所述設定 DNS 轉送,您可以測試您的私人端點是否已使用下列命令正確設定:
# Get the desired Storage Sync Service suffix (afs.azure.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
$azureEnvironment = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty Name
switch($azureEnvironment) {
"AzureCloud" {
$storageSyncSuffix = "afs.azure.net"
}
"AzureUSGovernment" {
$storageSyncSuffix = "afs.azure.us"
}
"AzureChinaCloud" {
$storageSyncSuffix = "afs.azure.cn"
}
default {
Write-Error
-Message "The Azure environment $_ is not currently supported by Azure File Sync." `
-ErrorAction Stop
}
}
# For public cloud, this will generate the following DNS suffix:
# privatelink.afs.azure.net
$dnsZoneName = "privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create new one.
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
# Get the desired storage account suffix (afs.azure.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
azureEnvironment=$(az cloud show \
--query "name" |
tr -d '"')
storageSyncSuffix=""
if [ $azureEnvironment == "AzureCloud" ]
then
storageSyncSuffix="afs.azure.net"
elif [ $azureEnvironment == "AzureUSGovernment" ]
then
storageSyncSuffix="afs.azure.us"
else
echo "Unsupported Azure environment $azureEnvironment."
fi
# For public cloud, this will generate the following DNS suffix:
# privatelinke.afs.azure.net.
dnsZoneName="privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
possibleDnsZones=""
possibleDnsZones=$(az network private-dns zone list \
--query "[?name == '$dnsZoneName'].id" \
--output tsv)
dnsZone=""
possibleDnsZone=""
for possibleDnsZone in $possibleDnsZones
do
possibleResourceGroupName=$(az resource show \
--ids $possibleDnsZone \
--query "resourceGroup" | \
tr -d '"')
link=$(az network private-dns link vnet list \
--resource-group $possibleResourceGroupName \
--zone-name $dnsZoneName \
--query "[?virtualNetwork.id == '$virtualNetwork'].id" \
--output tsv)
if [ -z $link ]
then
echo "1" > /dev/null
else
dnsZoneResourceGroup=$possibleResourceGroupName
dnsZone=$possibleDnsZone
break
fi
done
if [ -z $dnsZone ]
then
# No matching DNS zone attached to virtual network, so create a new one
dnsZone=$(az network private-dns zone create \
--resource-group $virtualNetworkResourceGroupName \
--name $dnsZoneName \
--query "id" | \
tr -d '"')
az network private-dns link vnet create \
--resource-group $virtualNetworkResourceGroupName \
--zone-name $dnsZoneName \
--name "$virtualNetworkName-DnsLink" \
--virtual-network $virtualNetwork \
--registration-enabled false \
--output none
dnsZoneResourceGroup=$virtualNetworkResourceGroupName
fi
現在您已有私人 DNS 區域的參考,接下來您必須為儲存體同步服務建立 A 記錄。
privateEndpointNIC=$(az network private-endpoint show \
--ids $privateEndpoint \
--query "networkInterfaces[0].id" | \
tr -d '"')
privateIpAddresses=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[].privateIpAddress" \
--output tsv)
hostNames=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[].privateLinkConnectionProperties.fqdns[]" \
--output tsv)
i=0
for privateIpAddress in $privateIpAddresses
do
j=0
targetHostName=""
for hostName in $hostNames
do
if [ $i == $j ]
then
targetHostName=$hostName
break
fi
j=$(expr $j + 1)
done
endpointName=$(echo $targetHostName | \
cut -c1-$(expr $(expr index $targetHostName ".") - 1))
az network private-dns record-set a create \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--name "$endpointName.$storageSyncServiceRegion" \
--output none
az network private-dns record-set a add-record \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--record-set-name "$endpointName.$storageSyncServiceRegion" \
--ipv4-address $privateIpAddress \
--output none
i=$(expr $i + 1)
done
# This assumes $storageAccount is still defined from the beginning of this of this guide.
$storageAccount | Update-AzStorageAccountNetworkRuleSet `
-DefaultAction Deny `
-Bypass AzureServices `
-WarningAction SilentlyContinue `
-ErrorAction Stop | `
Out-Null
# This assumes $storageAccountResourceGroupName and $storageAccountName
# are still defined from the beginning of this guide.
az storage account update \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--bypass "AzureServices" \
--default-action "Deny" \
--output none
serviceEndpoints=$(az network vnet subnet show \
--resource-group $restrictToVirtualNetworkResourceGroupName \
--vnet-name $restrictToVirtualNetworkName \
--name $subnetName \
--query "serviceEndpoints[].service" \
--output tsv)
foundStorageServiceEndpoint=false
for serviceEndpoint in $serviceEndpoints
do
if [ $serviceEndpoint = "Microsoft.Storage" ]
then
foundStorageServiceEndpoint=true
fi
done
if [ $foundStorageServiceEndpoint = false ]
then
serviceEndpointList=""
for serviceEndpoint in $serviceEndpoints
do
serviceEndpointList+=$serviceEndpoint
serviceEndpointList+=" "
done
serviceEndpointList+="Microsoft.Storage"
az network vnet subnet update \
--ids $subnet \
--service-endpoints $serviceEndpointList \
--output none
fi