├── README.md ├── images ├── architecture.png ├── nslookup.png └── resourcegroup.png ├── scripts ├── deploy.sh └── file_nslookup.sh └── templates ├── azuredeploy.json └── azuredeploy.parameters.json /README.md: -------------------------------------------------------------------------------- 1 | # Connecting to an Azure File Share via a Private Endpoint # 2 | 3 | [![Deploy To Azure](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.svg?sanitize=true)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fpaolosalvatori%2Ffile-share-private-endpoint%2Fmaster%2Ftemplates%2Fazuredeploy.json) 4 | [![Deploy To Azure US Gov](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazuregov.svg?sanitize=true)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fpaolosalvatori%2Ffile-share-private-endpoint%2Fmaster%2Ftemplates%2Fazuredeploy.json) 5 | [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.svg?sanitize=true)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2Fpaolosalvatori%2Ffile-share-private-endpoint%2Fmaster%2Ftemplates%2Fazuredeploy.json) 6 | 7 | This sample demonstrates how to create a Linux Virtual Machine in a virtual network that privately accesses [Azure File Share](https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction) and an ADLS Gen 2 blob storage account using two [Azure Private Endpoints](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-overview). Azure Private Endpoint is a network interface that connects you privately and securely to a service powered by Azure Private Link. Private Endpoint uses a private IP address from your virtual network, effectively bringing the service into your virtual network. The service could be an Azure service such as Azure Storage, Azure Cosmos DB, SQL, etc. or your own Private Link Service. For more information, see [What is Azure Private Link?](https://docs.microsoft.com/en-us/azure/private-link/private-link-overview). For more information on the DNS configuration of a private endpoint, see [Azure Private Endpoint DNS configuration](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns). 8 | 9 | ## Architecture ## 10 | 11 | The following picture shows the architecture and network topology of the sample. 12 | 13 | ![Architecture](images/architecture.png) 14 | 15 | The ARM template deploys the following resources: 16 | 17 | - Virtual Network: this virtual network has a single subnet that hosts an Linux (Ubuntu) virtual machine 18 | - Network Security Group: this resource contains an inbound rule to allow the access to the virtual machine on port 22 (SSH) 19 | - The virtual machine is created with a managed identity which is assigned the contributor role at the resource group scope level 20 | - A Public IP for the Linux virtual machine 21 | - The NIC used by the Linux virtual machine that makes use of the Public IP 22 | - A Linux virtual machine used for testing the connectivity to the storage account via a private endpoint 23 | - A Log Analytics workspace used to monitor the health status of the Linux virtual machine 24 | - An ADLS Gen 2 storage account used to store the Azure File Share 25 | - An ADLS Gen 2 storage account used to store the boot diagnostics logs of the virtual machine as blobs 26 | - A Private DNS Zone for File Storage Account private endpoints (privatelink.file.core.windows.net) 27 | - A Private DNS Zone for Blob Storage Account private endpoints (privatelink.blob.core.windows.net) 28 | - A Private Endpoint to let the virtual machine access the Azure File Share via a private IP address 29 | - A Private Endpoint to let the virtual machine store boot diagnostics logs to the second storage account via a private IP address 30 | - A Private DNS Zone Group for the File Storage Account private endpoint 31 | - A Private DNS Zone Group for the Blob Storage Account private endpoint 32 | 33 | The [PrivateDnsZoneGroup](https://docs.microsoft.com/en-us/azure/templates/microsoft.network/privateendpoints/privateDnsZoneGroups) resource type establishes a relationship between the Private Endpoint and the Private the privatelink.* DNS zone for the name resolution of the fully qualified name of the resource referenced by the Private Endpoint. 34 | 35 | - When creating a Private Endpoint, the related A record will automatically be created in the target Private DNS Zone with the private IP address of the network interface associated to the Private Endpoint and the name of the Azure resource referenced by the Private Endpoint 36 | - When deleting a Private Endpoint, the related A record gets automatically deleted from the corresponding Private DNS Zone. 37 | 38 | The two storage accounts are accessed via a different endpoint, hence their private endpoints need different Private DNS Zone: 39 | 40 | | Storage Service | Zone Name | 41 | | :-- | :--| 42 | | Blob service | privatelink.blob.core.windows.net | 43 | | File service | privatelink.file.core.windows.net | 44 | 45 | For more information, see [Use private endpoints for Azure Storage](https://docs.microsoft.com/en-us/azure/storage/common/storage-private-endpoints#dns-changes-for-private-endpoints). 46 | 47 | The ARM template uses the [Azure Custom Script Extension](https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-linux) to download and run the following Bash script on the virtual machine. The script performs the following steps: 48 | 49 | - Validates the parameters received by the Custom Script extension 50 | - Updates the system and upgrades packages 51 | - Installs curl and traceroute packages 52 | - Runs the nslookup command against the public URL of the ADLS Gen 2 storage account to verify that this gets resolved to a private address 53 | - Runs the nslookup command against the public URL of the second storage account to verify that this gets resolved to a private address 54 | 55 | ```bash 56 | #!/bin/bash 57 | 58 | # Variables 59 | fileServicePrimaryEndpoint=$1 60 | blobServicePrimaryEndpoint=$2 61 | 62 | # Parameters validation 63 | if [[ -z $fileServicePrimaryEndpoint ]]; then 64 | echo "fileServicePrimaryEndpoint parameter cannot be null or empty" 65 | exit 1 66 | fi 67 | 68 | if [[ -z $blobServicePrimaryEndpoint ]]; then 69 | echo "blobServicePrimaryEndpoint parameter cannot be null or empty" 70 | exit 1 71 | fi 72 | 73 | # Eliminate debconf warnings 74 | echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections 75 | 76 | # Update the system 77 | sudo apt-get update -y 78 | 79 | # Upgrade packages 80 | sudo apt-get upgrade -y 81 | 82 | # Run nslookup to verify that public hostname of the Service Bus namespace 83 | # is properly mapped to the private address of the provate endpoint 84 | nslookup $fileServicePrimaryEndpoint 85 | 86 | # Run nslookup to verify that public hostname of the Blob storage account 87 | # is properly mapped to the private address of the provate endpoint 88 | nslookup $blobServicePrimaryEndpoint 89 | ``` 90 | 91 | ## Deployment ## 92 | 93 | You can use the template.json ARM template and parameters.json file included in this repository to deploy the sample. Make sure to edit the parameters.json file to customize the installation. You can also use the deploy.sh Bash script under the scripts folder to deploy the ARM template. The following figure shows the resources deployed by the ARM template in the target resource group. 94 | 95 | ![Resource Group](images/resourcegroup.png) 96 | 97 | ## Testing ## 98 | 99 | if you open an ssh session to the Linux virtual machine and manually run the nslookup command, you should see an output like the following: 100 | 101 | ![Architecture](images/nslookup.png) 102 | -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paolosalvatori/file-share-private-endpoint/da7807ce9a5bf765731d1449d6d65d28b5851daa/images/architecture.png -------------------------------------------------------------------------------- /images/nslookup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paolosalvatori/file-share-private-endpoint/da7807ce9a5bf765731d1449d6d65d28b5851daa/images/nslookup.png -------------------------------------------------------------------------------- /images/resourcegroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paolosalvatori/file-share-private-endpoint/da7807ce9a5bf765731d1449d6d65d28b5851daa/images/resourcegroup.png -------------------------------------------------------------------------------- /scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables 4 | resourceGroupName="FilePrivateEndpointRG" 5 | location="WestEurope" 6 | deploy=1 7 | 8 | # ARM template and parameters files 9 | template="../templates/azuredeploy.json" 10 | parameters="../templates/azuredeploy.parameters.json" 11 | 12 | # SubscriptionId of the current subscription 13 | subscriptionId=$(az account show --query id --output tsv) 14 | 15 | # Check if the resource group already exists 16 | createResourceGroup() { 17 | local resourceGroupName=$1 18 | local location=$2 19 | 20 | # Parameters validation 21 | if [[ -z $resourceGroupName ]]; then 22 | echo "The resource group name parameter cannot be null" 23 | exit 24 | fi 25 | 26 | if [[ -z $location ]]; then 27 | echo "The location parameter cannot be null" 28 | exit 29 | fi 30 | 31 | echo "Checking if [$resourceGroupName] resource group actually exists in the [$subscriptionId] subscription..." 32 | 33 | if ! az group show --name "$resourceGroupName" &>/dev/null; then 34 | echo "No [$resourceGroupName] resource group actually exists in the [$subscriptionId] subscription" 35 | echo "Creating [$resourceGroupName] resource group in the [$subscriptionId] subscription..." 36 | 37 | # Create the resource group 38 | if az group create --name "$resourceGroupName" --location "$location" 1>/dev/null; then 39 | echo "[$resourceGroupName] resource group successfully created in the [$subscriptionId] subscription" 40 | else 41 | echo "Failed to create [$resourceGroupName] resource group in the [$subscriptionId] subscription" 42 | exit 43 | fi 44 | else 45 | echo "[$resourceGroupName] resource group already exists in the [$subscriptionId] subscription" 46 | fi 47 | } 48 | 49 | # Validate the ARM template 50 | validateTemplate() { 51 | local resourceGroupName=$1 52 | local template=$2 53 | local parameters=$3 54 | local arguments=$4 55 | 56 | # Parameters validation 57 | if [[ -z $resourceGroupName ]]; then 58 | echo "The resource group name parameter cannot be null" 59 | fi 60 | 61 | if [[ -z $template ]]; then 62 | echo "The template parameter cannot be null" 63 | fi 64 | 65 | if [[ -z $parameters ]]; then 66 | echo "The parameters parameter cannot be null" 67 | fi 68 | 69 | if [[ -z $arguments ]]; then 70 | echo "The arguments parameter cannot be null" 71 | fi 72 | 73 | echo "Validating [$template] ARM template..." 74 | 75 | if [[ -z $arguments ]]; then 76 | error=$(az deployment group validate \ 77 | --resource-group "$resourceGroupName" \ 78 | --template-file "$template" \ 79 | --parameters "$parameters" \ 80 | --query error \ 81 | --output json) 82 | else 83 | error=$(az deployment group validate \ 84 | --resource-group "$resourceGroupName" \ 85 | --template-file "$template" \ 86 | --parameters "$parameters" \ 87 | --arguments $arguments \ 88 | --query error \ 89 | --output json) 90 | fi 91 | 92 | if [[ -z $error ]]; then 93 | echo "[$template] ARM template successfully validated" 94 | else 95 | echo "Failed to validate the [$template] ARM template" 96 | echo "$error" 97 | exit 1 98 | fi 99 | } 100 | 101 | # Deploy ARM template 102 | deployTemplate() { 103 | local resourceGroupName=$1 104 | local template=$2 105 | local parameters=$3 106 | local arguments=$4 107 | 108 | # Parameters validation 109 | if [[ -z $resourceGroupName ]]; then 110 | echo "The resource group name parameter cannot be null" 111 | exit 112 | fi 113 | 114 | if [[ -z $template ]]; then 115 | echo "The template parameter cannot be null" 116 | exit 117 | fi 118 | 119 | if [[ -z $parameters ]]; then 120 | echo "The parameters parameter cannot be null" 121 | exit 122 | fi 123 | 124 | if [ $deploy != 1 ]; then 125 | return 126 | fi 127 | 128 | # Deploy the ARM template 129 | echo "Deploying [$template$] ARM template..." 130 | 131 | if [[ -z $arguments ]]; then 132 | az deployment group create \ 133 | --resource-group $resourceGroupName \ 134 | --template-file $template \ 135 | --parameters $parameters 1>/dev/null 136 | else 137 | az deployment group create \ 138 | --resource-group $resourceGroupName \ 139 | --template-file $template \ 140 | --parameters $parameters \ 141 | --parameters $arguments 1>/dev/null 142 | fi 143 | 144 | if [[ $? == 0 ]]; then 145 | echo "[$template$] ARM template successfully provisioned" 146 | else 147 | echo "Failed to provision the [$template$] ARM template" 148 | exit -1 149 | fi 150 | } 151 | 152 | # Create Resource Group 153 | createResourceGroup \ 154 | "$resourceGroupName" \ 155 | "$location" 156 | 157 | # Deploy ARM Template 158 | deployTemplate \ 159 | "$resourceGroupName" \ 160 | "$template" \ 161 | "$parameters" -------------------------------------------------------------------------------- /scripts/file_nslookup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Variables 4 | fileServicePrimaryEndpoint=$1 5 | blobServicePrimaryEndpoint=$2 6 | 7 | # Parameters validation 8 | if [[ -z $fileServicePrimaryEndpoint ]]; then 9 | echo "fileServicePrimaryEndpoint parameter cannot be null or empty" 10 | exit 1 11 | fi 12 | 13 | if [[ -z $blobServicePrimaryEndpoint ]]; then 14 | echo "blobServicePrimaryEndpoint parameter cannot be null or empty" 15 | exit 1 16 | fi 17 | 18 | # Eliminate debconf warnings 19 | echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections 20 | 21 | # Update the system 22 | sudo apt-get update -y 23 | 24 | # Upgrade packages 25 | sudo apt-get upgrade -y 26 | 27 | # Run nslookup to verify that public hostname of the Service Bus namespace 28 | # is properly mapped to the private address of the provate endpoint 29 | nslookup $fileServicePrimaryEndpoint 30 | 31 | # Run nslookup to verify that public hostname of the Blob storage account 32 | # is properly mapped to the private address of the provate endpoint 33 | nslookup $blobServicePrimaryEndpoint -------------------------------------------------------------------------------- /templates/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "location": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().location]", 8 | "metadata": { 9 | "description": "Specifies the location for all the resources." 10 | } 11 | }, 12 | "virtualNetworkName": { 13 | "defaultValue": "UbuntuVnet", 14 | "type": "string", 15 | "metadata": { 16 | "description": "Specifies the name of the virtual network hosting the virtual machine." 17 | } 18 | }, 19 | "virtualNetworkAddressPrefix": { 20 | "defaultValue": "10.0.0.0/16", 21 | "type": "string", 22 | "metadata": { 23 | "description": "Specifies the address prefix of the virtual network hosting the virtual machine." 24 | } 25 | }, 26 | "subnetName": { 27 | "defaultValue": "DefaultSubnet", 28 | "type": "string", 29 | "metadata": { 30 | "description": "Specifies the name of the subnet hosting the virtual machine." 31 | } 32 | }, 33 | "subnetAddressPrefix": { 34 | "defaultValue": "10.0.0.0/24", 35 | "type": "string", 36 | "metadata": { 37 | "description": "Specifies the address prefix of the subnet hosting the virtual machine." 38 | } 39 | }, 40 | "vmName": { 41 | "type": "string", 42 | "defaultValue": "TestVm", 43 | "metadata": { 44 | "description": "Specifies the name of the virtual machine." 45 | } 46 | }, 47 | "vmSize": { 48 | "type": "string", 49 | "defaultValue": "Standard_DS3_v2", 50 | "metadata": { 51 | "description": "Specifies the size of the virtual machine." 52 | } 53 | }, 54 | "imagePublisher": { 55 | "type": "string", 56 | "defaultValue": "Canonical", 57 | "metadata": { 58 | "description": "Specifies the image publisher of the disk image used to create the virtual machine." 59 | } 60 | }, 61 | "imageOffer": { 62 | "type": "string", 63 | "defaultValue": "UbuntuServer", 64 | "metadata": { 65 | "description": "Specifies the offer of the platform image or marketplace image used to create the virtual machine." 66 | } 67 | }, 68 | "imageSku": { 69 | "type": "string", 70 | "defaultValue": "18.04-LTS", 71 | "metadata": { 72 | "description": "Specifies the Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version." 73 | } 74 | }, 75 | "authenticationType": { 76 | "type": "string", 77 | "defaultValue": "password", 78 | "allowedValues": [ 79 | "sshPublicKey", 80 | "password" 81 | ], 82 | "metadata": { 83 | "description": "Specifies the type of authentication when accessing the Virtual Machine. SSH key is recommended." 84 | } 85 | }, 86 | "adminUsername": { 87 | "type": "string", 88 | "defaultValue": "azadmin", 89 | "metadata": { 90 | "description": "Specifies the name of the administrator account of the virtual machine." 91 | } 92 | }, 93 | "adminPasswordOrKey": { 94 | "type": "securestring", 95 | "metadata": { 96 | "description": "Specifies the SSH Key or password for the virtual machine. SSH key is recommended." 97 | } 98 | }, 99 | "diskStorageAccounType": { 100 | "type": "string", 101 | "defaultValue": "Premium_LRS", 102 | "allowedValues": [ 103 | "Standard_LRS", 104 | "Standard_GRS", 105 | "Standard_RAGRS", 106 | "Standard_ZRS", 107 | "Premium_LRS", 108 | "Premium_ZRS", 109 | "Standard_GZRS", 110 | "Standard_RAGZRS" 111 | ], 112 | "metadata": { 113 | "description": "Specifies the storage account type for OS and data disk." 114 | } 115 | }, 116 | "numDataDisks": { 117 | "type": "int", 118 | "defaultValue": 1, 119 | "minValue": 0, 120 | "maxValue": 64, 121 | "metadata": { 122 | "description": "Specifies the number of data disks of the virtual machine." 123 | } 124 | }, 125 | "osDiskSize": { 126 | "type": "int", 127 | "defaultValue": 50, 128 | "metadata": { 129 | "description": "Specifies the size in GB of the OS disk of the VM." 130 | } 131 | }, 132 | "dataDiskSize": { 133 | "type": "int", 134 | "defaultValue": 50, 135 | "metadata": { 136 | "description": "Specifies the size in GB of the OS disk of the virtual machine." 137 | } 138 | }, 139 | "dataDiskCaching": { 140 | "type": "string", 141 | "defaultValue": "ReadWrite", 142 | "metadata": { 143 | "description": "Specifies the caching requirements for the data disks." 144 | } 145 | }, 146 | "scriptFilePath": { 147 | "type": "string", 148 | "defaultValue": "https://raw.githubusercontent.com/paolosalvatori/servicebus-private-endpoint/master/scripts", 149 | "metadata": { 150 | "description": "Specifies the relative path of the scripts used to initialize the virtual machine." 151 | } 152 | }, 153 | "scriptFileName": { 154 | "type": "string", 155 | "defaultValue": "servicebus_nslookup.sh", 156 | "metadata": { 157 | "description": "Specifies the script to download from the URI specified by the scriptFilePath parameter." 158 | } 159 | }, 160 | "deployLogAnalytics": { 161 | "type": "bool", 162 | "defaultValue": true, 163 | "metadata": { 164 | "description": "Specifies whether to deploy a Log Analytics workspace to monitor the health and performance of the virtual machine." 165 | } 166 | }, 167 | "workspaceName": { 168 | "type": "string", 169 | "metadata": { 170 | "description": "Specifies the globally unique name of the Log Analytics workspace." 171 | } 172 | }, 173 | "workspaceSku": { 174 | "type": "string", 175 | "allowedValues": [ 176 | "PerGB2018", 177 | "Free", 178 | "Standalone", 179 | "PerNode", 180 | "Standard", 181 | "Premium" 182 | ], 183 | "defaultValue": "PerGB2018", 184 | "metadata": { 185 | "description": "Specifies the SKU of the Log Analytics workspace." 186 | } 187 | }, 188 | "fileStorageAccountName": { 189 | "type": "string", 190 | "defaultValue": "[concat('file', uniquestring(resourceGroup().id))]", 191 | "metadata": { 192 | "description": "Specifies the name of the Azure Storage account hosting the File Share." 193 | } 194 | }, 195 | "fileShareName": { 196 | "type": "string", 197 | "defaultValue": "documents", 198 | "minLength": 3, 199 | "maxLength": 63, 200 | "metadata": { 201 | "description": "Specifies the name of the File Share. File share names must be between 3 and 63 characters in length and use numbers, lower-case letters and dash (-) only." 202 | } 203 | }, 204 | "shareQuota": { 205 | "type": "int", 206 | "defaultValue": 5120, 207 | "metadata": { 208 | "description": "Specifies the maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5TB (5120). For Large File Shares, the maximum size is 102400." 209 | } 210 | }, 211 | "blobStorageAccountName": { 212 | "type": "string", 213 | "defaultValue": "[concat('boot', uniquestring(resourceGroup().id))]", 214 | "metadata": { 215 | "description": "Specifies the globally unique name for the storage account used to store the boot diagnostics logs of the virtual machine." 216 | } 217 | }, 218 | "fileStorageAccountPrivateEndpointName": { 219 | "type": "string", 220 | "defaultValue": "FileSharePrivateEndpoint", 221 | "metadata": { 222 | "description": "Specifies the name of the private link to the boot diagnostics storage account." 223 | } 224 | }, 225 | "blobStorageAccountPrivateEndpointName": { 226 | "type": "string", 227 | "defaultValue": "BlobStorageAccountPrivateEndpoint", 228 | "metadata": { 229 | "description": "Specifies the name of the private link to the boot diagnostics storage account." 230 | } 231 | }, 232 | "networkAclsDefaultAction": { 233 | "type": "string", 234 | "defaultValue": "Deny", 235 | "allowedValues": [ 236 | "Allow", 237 | "Deny" 238 | ], 239 | "metadata": { 240 | "description": "Allow or disallow public access to all blobs or containers in the storage accounts. The default interpretation is true for this property." 241 | } 242 | }, 243 | "allowBlobPublicAccess": { 244 | "type": "bool", 245 | "defaultValue": true, 246 | "metadata": { 247 | "description": "Allow or disallow public access to all blobs or containers in the storage accounts. The default interpretation is true for this property." 248 | } 249 | } 250 | }, 251 | "variables": { 252 | "fileStorageAccountId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('fileStorageAccountName'))]", 253 | "fileShareId": "[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', parameters('fileStorageAccountName'), 'default', parameters('fileShareName'))]", 254 | "customScriptExtensionName": "CustomScript", 255 | "omsAgentForLinuxName": "LogAnalytics", 256 | "nicName": "[concat(parameters('vmName'), 'Nic')]", 257 | "nsgName": "[concat(parameters('subnetName'), 'Nsg')]", 258 | "publicIPAddressName": "[concat(parameters('vmName'), 'PublicIp')]", 259 | "publicIPAddressType": "Dynamic", 260 | "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceName'))]", 261 | "subnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]", 262 | "publicIpId": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]", 263 | "nicId": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]", 264 | "vnetId": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]", 265 | "nsgId": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('nsgName'))]", 266 | "vmId": "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]", 267 | "customScriptId": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('vmName'), variables('customScriptExtensionName'))]", 268 | "omsAgentForLinuxId": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('vmName'), variables('omsAgentForLinuxName'))]", 269 | "scriptFileUri": "[concat(parameters('scriptFilePath'), '/', parameters('scriptFileName'))]", 270 | "linuxConfiguration": { 271 | "disablePasswordAuthentication": true, 272 | "ssh": { 273 | "publicKeys": [ 274 | { 275 | "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", 276 | "keyData": "[parameters('adminPasswordOrKey')]" 277 | } 278 | ] 279 | }, 280 | "provisionVMAgent": true 281 | }, 282 | "blobStorageAccountId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('blobStorageAccountName'))]", 283 | "filePublicDNSZoneForwarder": "[concat('.file.', environment().suffixes.storage)]", 284 | "blobPublicDNSZoneForwarder": "[concat('.blob.', environment().suffixes.storage)]", 285 | "filePrivateDnsZoneName": "[concat('privatelink', variables('filePublicDNSZoneForwarder'))]", 286 | "blobPrivateDnsZoneName": "[concat('privatelink', variables('blobPublicDNSZoneForwarder'))]", 287 | "filePrivateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', variables('filePrivateDnsZoneName'))]", 288 | "blobPrivateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', variables('blobPrivateDnsZoneName'))]", 289 | "fileServicePrimaryEndpoint": "[concat(parameters('fileStorageAccountName'), variables('filePublicDNSZoneForwarder'))]", 290 | "blobServicePrimaryEndpoint": "[concat(parameters('blobStorageAccountName'), variables('blobPublicDNSZoneForwarder'))]", 291 | "fileStorageAccountPrivateEndpointId": "[resourceId('Microsoft.Network/privateEndpoints', parameters('fileStorageAccountPrivateEndpointName'))]", 292 | "blobStorageAccountPrivateEndpointId": "[resourceId('Microsoft.Network/privateEndpoints', parameters('blobStorageAccountPrivateEndpointName'))]", 293 | "fileStorageAccountPrivateEndpointGroupName": "file", 294 | "blobStorageAccountPrivateEndpointGroupName": "blob", 295 | "filePrivateDnsZoneGroup": "[concat(parameters('fileStorageAccountPrivateEndpointName'),'/', variables('fileStorageAccountPrivateEndpointGroupName'), 'PrivateDnsZoneGroup')]", 296 | "blobPrivateDnsZoneGroup": "[concat(parameters('blobStorageAccountPrivateEndpointName'),'/', variables('blobStorageAccountPrivateEndpointGroupName'), 'PrivateDnsZoneGroup')]" 297 | }, 298 | "resources": [ 299 | { 300 | "apiVersion": "2019-06-01", 301 | "type": "Microsoft.Storage/storageAccounts", 302 | "name": "[parameters('fileStorageAccountName')]", 303 | "location": "[parameters('location')]", 304 | "sku": { 305 | "name": "Standard_LRS", 306 | "tier": "Standard" 307 | }, 308 | "kind": "StorageV2", 309 | "properties": { 310 | "accessTier": "Hot", 311 | "networkAcls": { 312 | "defaultAction": "[parameters('networkAclsDefaultAction')]", 313 | "bypass": "AzureServices", 314 | "ipRules": [], 315 | "virtualNetworkRules": [] 316 | }, 317 | "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]" 318 | } 319 | }, 320 | { 321 | "type": "Microsoft.Storage/storageAccounts/fileServices/shares", 322 | "apiVersion": "2019-06-01", 323 | "name": "[concat(parameters('fileStorageAccountName'), '/default/', parameters('fileShareName'))]", 324 | "dependsOn": [ 325 | "[variables('fileStorageAccountId')]" 326 | ], 327 | "properties": { 328 | "shareQuota": "[parameters('shareQuota')]" 329 | } 330 | }, 331 | { 332 | "type": "Microsoft.Network/privateEndpoints", 333 | "apiVersion": "2020-07-01", 334 | "name": "[parameters('fileStorageAccountPrivateEndpointName')]", 335 | "location": "[parameters('location')]", 336 | "dependsOn": [ 337 | "[variables('fileStorageAccountId')]", 338 | "[variables('fileShareId')]" 339 | ], 340 | "properties": { 341 | "privateLinkServiceConnections": [ 342 | { 343 | "name": "[parameters('fileStorageAccountPrivateEndpointName')]", 344 | "properties": { 345 | "privateLinkServiceId": "[variables('fileStorageAccountId')]", 346 | "groupIds": [ 347 | "[variables('fileStorageAccountPrivateEndpointGroupName')]" 348 | ] 349 | } 350 | } 351 | ], 352 | "subnet": { 353 | "id": "[variables('subnetId')]" 354 | } 355 | } 356 | }, 357 | { 358 | "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", 359 | "apiVersion": "2020-07-01", 360 | "name": "[variables('filePrivateDnsZoneGroup')]", 361 | "location": "[parameters('location')]", 362 | "dependsOn": [ 363 | "[variables('filePrivateDnsZoneId')]", 364 | "[variables('fileStorageAccountPrivateEndpointId')]" 365 | ], 366 | "properties": { 367 | "privateDnsZoneConfigs": [ 368 | { 369 | "name": "dnsConfig", 370 | "properties": { 371 | "privateDnsZoneId": "[variables('filePrivateDnsZoneId')]" 372 | } 373 | } 374 | ] 375 | } 376 | }, 377 | { 378 | "apiVersion": "2019-06-01", 379 | "type": "Microsoft.Storage/storageAccounts", 380 | "name": "[parameters('blobStorageAccountName')]", 381 | "location": "[parameters('location')]", 382 | "sku": { 383 | "name": "Standard_LRS" 384 | }, 385 | "kind": "StorageV2", 386 | "properties": { 387 | "accessTier": "Hot", 388 | "networkAcls": { 389 | "defaultAction": "[parameters('networkAclsDefaultAction')]", 390 | "bypass": "AzureServices", 391 | "ipRules": [], 392 | "virtualNetworkRules": [] 393 | }, 394 | "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]" 395 | } 396 | }, 397 | { 398 | "apiVersion": "2020-07-01", 399 | "type": "Microsoft.Network/publicIPAddresses", 400 | "name": "[variables('publicIPAddressName')]", 401 | "location": "[parameters('location')]", 402 | "properties": { 403 | "publicIPAllocationMethod": "[variables('publicIPAddressType')]", 404 | "dnsSettings": { 405 | "domainNameLabel": "[concat(toLower(parameters('vmName')), uniquestring(resourceGroup().id))]" 406 | } 407 | } 408 | }, 409 | { 410 | "apiVersion": "2019-08-01", 411 | "type": "Microsoft.Network/networkSecurityGroups", 412 | "name": "[variables('nsgName')]", 413 | "location": "[parameters('location')]", 414 | "properties": { 415 | "securityRules": [ 416 | { 417 | "name": "AllowSshInbound", 418 | "properties": { 419 | "priority": 100, 420 | "access": "Allow", 421 | "direction": "Inbound", 422 | "destinationPortRange": "22", 423 | "protocol": "Tcp", 424 | "sourceAddressPrefix": "*", 425 | "sourcePortRange": "*", 426 | "destinationAddressPrefix": "*" 427 | } 428 | } 429 | ] 430 | } 431 | }, 432 | { 433 | "apiVersion": "2019-11-01", 434 | "type": "Microsoft.Network/virtualNetworks", 435 | "name": "[parameters('virtualNetworkName')]", 436 | "location": "[parameters('location')]", 437 | "dependsOn": [ 438 | "[variables('nsgId')]" 439 | ], 440 | "properties": { 441 | "addressSpace": { 442 | "addressPrefixes": [ 443 | "[parameters('virtualNetworkAddressPrefix')]" 444 | ] 445 | }, 446 | "subnets": [ 447 | { 448 | "name": "[parameters('subnetName')]", 449 | "properties": { 450 | "addressPrefix": "[parameters('subnetAddressPrefix')]", 451 | "networkSecurityGroup": { 452 | "id": "[variables('nsgId')]" 453 | }, 454 | "privateEndpointNetworkPolicies": "Disabled", 455 | "privateLinkServiceNetworkPolicies": "Enabled" 456 | } 457 | } 458 | ] 459 | } 460 | }, 461 | { 462 | "apiVersion": "2020-07-01", 463 | "type": "Microsoft.Network/networkInterfaces", 464 | "name": "[variables('nicName')]", 465 | "location": "[parameters('location')]", 466 | "dependsOn": [ 467 | "[variables('publicIpId')]", 468 | "[variables('vnetId')]" 469 | ], 470 | "properties": { 471 | "ipConfigurations": [ 472 | { 473 | "name": "ipconfig1", 474 | "properties": { 475 | "privateIPAllocationMethod": "Dynamic", 476 | "publicIPAddress": { 477 | "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]" 478 | }, 479 | "subnet": { 480 | "id": "[variables('subnetId')]" 481 | } 482 | } 483 | } 484 | ] 485 | } 486 | }, 487 | { 488 | "apiVersion": "2019-12-01", 489 | "type": "Microsoft.Compute/virtualMachines", 490 | "name": "[parameters('vmName')]", 491 | "location": "[parameters('location')]", 492 | "dependsOn": [ 493 | "[variables('fileStorageAccountPrivateEndpointId')]", 494 | "[variables('blobStorageAccountPrivateEndpointId')]", 495 | "[variables('nicId')]" 496 | ], 497 | "properties": { 498 | "hardwareProfile": { 499 | "vmSize": "[parameters('vmSize')]" 500 | }, 501 | "osProfile": { 502 | "computerName": "[parameters('vmName')]", 503 | "adminUsername": "[parameters('adminUsername')]", 504 | "adminPassword": "[parameters('adminPasswordOrKey')]", 505 | "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('linuxConfiguration'))]" 506 | }, 507 | "storageProfile": { 508 | "imageReference": { 509 | "publisher": "[parameters('imagePublisher')]", 510 | "offer": "[parameters('imageOffer')]", 511 | "sku": "[parameters('imageSku')]", 512 | "version": "latest" 513 | }, 514 | "osDisk": { 515 | "name": "[concat(parameters('vmName'),'_OSDisk')]", 516 | "caching": "ReadWrite", 517 | "createOption": "FromImage", 518 | "diskSizeGB": "[parameters('osDiskSize')]", 519 | "managedDisk": { 520 | "storageAccountType": "[parameters('diskStorageAccounType')]" 521 | } 522 | }, 523 | "copy": [ 524 | { 525 | "name": "dataDisks", 526 | "count": "[parameters('numDataDisks')]", 527 | "input": { 528 | "caching": "[parameters('dataDiskCaching')]", 529 | "diskSizeGB": "[parameters('dataDiskSize')]", 530 | "lun": "[copyIndex('dataDisks')]", 531 | "name": "[concat(parameters('vmName'),'-DataDisk',copyIndex('dataDisks'))]", 532 | "createOption": "Empty", 533 | "managedDisk": { 534 | "storageAccountType": "[parameters('diskStorageAccounType')]" 535 | } 536 | } 537 | } 538 | ] 539 | }, 540 | "networkProfile": { 541 | "networkInterfaces": [ 542 | { 543 | "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]" 544 | } 545 | ] 546 | }, 547 | "diagnosticsProfile": { 548 | "bootDiagnostics": { 549 | "enabled": true, 550 | "storageUri": "[reference(variables('blobStorageAccountId')).primaryEndpoints['blob']]" 551 | } 552 | } 553 | } 554 | }, 555 | { 556 | "apiVersion": "2019-12-01", 557 | "type": "Microsoft.Compute/virtualMachines/extensions", 558 | "name": "[concat(parameters('vmName'), '/', variables('customScriptExtensionName'))]", 559 | "location": "[parameters('location')]", 560 | "dependsOn": [ 561 | "[variables('vmId')]" 562 | ], 563 | "properties": { 564 | "publisher": "Microsoft.Azure.Extensions", 565 | "type": "CustomScript", 566 | "typeHandlerVersion": "2.0", 567 | "autoUpgradeMinorVersion": true, 568 | "settings": { 569 | "skipDos2Unix": false, 570 | "timestamp": 123456789, 571 | "fileUris": [ 572 | "[variables('scriptFileUri')]" 573 | ] 574 | }, 575 | "protectedSettings": { 576 | "commandToExecute": "[concat('bash ', parameters('scriptFileName'), ' ', variables('fileServicePrimaryEndpoint'), ' ', variables('blobServicePrimaryEndpoint'))]" 577 | } 578 | } 579 | }, 580 | { 581 | "apiVersion": "2019-12-01", 582 | "type": "Microsoft.Compute/virtualMachines/extensions", 583 | "name": "[concat(parameters('vmName'),'/', variables('omsAgentForLinuxName'))]", 584 | "location": "[parameters('location')]", 585 | "dependsOn": [ 586 | "[variables('vmId')]", 587 | "[variables('workspaceId')]", 588 | "[variables('customScriptId')]" 589 | ], 590 | "properties": { 591 | "publisher": "Microsoft.EnterpriseCloud.Monitoring", 592 | "type": "OmsAgentForLinux", 593 | "typeHandlerVersion": "1.12", 594 | "settings": { 595 | "workspaceId": "[reference(variables('workspaceId'), '2020-08-01').customerId]", 596 | "stopOnMultipleConnections": false 597 | }, 598 | "protectedSettings": { 599 | "workspaceKey": "[listKeys(variables('workspaceId'),'2020-08-01').primarySharedKey]" 600 | } 601 | } 602 | }, 603 | { 604 | "apiVersion": "2019-12-01", 605 | "type": "Microsoft.Compute/virtualMachines/extensions", 606 | "name": "[concat(parameters('vmName'),'/DependencyAgent')]", 607 | "location": "[parameters('location')]", 608 | "dependsOn": [ 609 | "[variables('vmId')]", 610 | "[variables('workspaceId')]", 611 | "[variables('customScriptId')]", 612 | "[variables('omsAgentForLinuxId')]" 613 | ], 614 | "properties": { 615 | "publisher": "Microsoft.Azure.Monitoring.DependencyAgent", 616 | "type": "DependencyAgentLinux", 617 | "typeHandlerVersion": "9.10", 618 | "autoUpgradeMinorVersion": true 619 | } 620 | }, 621 | { 622 | "condition": "[parameters('deployLogAnalytics')]", 623 | "apiVersion": "2020-08-01", 624 | "type": "Microsoft.OperationalInsights/workspaces", 625 | "name": "[parameters('workspaceName')]", 626 | "location": "[parameters('location')]", 627 | "properties": { 628 | "sku": { 629 | "name": "[parameters('workspaceSku')]" 630 | } 631 | }, 632 | "resources": [ 633 | { 634 | "apiVersion": "2020-08-01", 635 | "type": "dataSources", 636 | "name": "Kern", 637 | "dependsOn": [ 638 | "[variables('workspaceId')]" 639 | ], 640 | "kind": "LinuxSyslog", 641 | "properties": { 642 | "syslogName": "kern", 643 | "syslogSeverities": [ 644 | { 645 | "severity": "emerg" 646 | }, 647 | { 648 | "severity": "alert" 649 | }, 650 | { 651 | "severity": "crit" 652 | }, 653 | { 654 | "severity": "err" 655 | }, 656 | { 657 | "severity": "warning" 658 | } 659 | ] 660 | } 661 | }, 662 | { 663 | "apiVersion": "2020-08-01", 664 | "type": "dataSources", 665 | "name": "Syslog", 666 | "dependsOn": [ 667 | "[variables('workspaceId')]" 668 | ], 669 | "kind": "LinuxSyslog", 670 | "properties": { 671 | "syslogName": "syslog", 672 | "syslogSeverities": [ 673 | { 674 | "severity": "emerg" 675 | }, 676 | { 677 | "severity": "alert" 678 | }, 679 | { 680 | "severity": "crit" 681 | }, 682 | { 683 | "severity": "err" 684 | }, 685 | { 686 | "severity": "warning" 687 | } 688 | ] 689 | } 690 | }, 691 | { 692 | "apiVersion": "2020-08-01", 693 | "type": "dataSources", 694 | "name": "User", 695 | "dependsOn": [ 696 | "[variables('workspaceId')]" 697 | ], 698 | "kind": "LinuxSyslog", 699 | "properties": { 700 | "syslogName": "user", 701 | "syslogSeverities": [ 702 | { 703 | "severity": "emerg" 704 | }, 705 | { 706 | "severity": "alert" 707 | }, 708 | { 709 | "severity": "crit" 710 | }, 711 | { 712 | "severity": "err" 713 | }, 714 | { 715 | "severity": "warning" 716 | } 717 | ] 718 | } 719 | }, 720 | { 721 | "apiVersion": "2020-08-01", 722 | "type": "dataSources", 723 | "name": "SampleSyslogCollection1", 724 | "dependsOn": [ 725 | "[variables('workspaceId')]" 726 | ], 727 | "kind": "LinuxSyslogCollection", 728 | "properties": { 729 | "state": "Enabled" 730 | } 731 | }, 732 | { 733 | "apiVersion": "2020-08-01", 734 | "type": "dataSources", 735 | "name": "DiskPerfCounters", 736 | "dependsOn": [ 737 | "[variables('workspaceId')]" 738 | ], 739 | "kind": "LinuxPerformanceObject", 740 | "properties": { 741 | "performanceCounters": [ 742 | { 743 | "counterName": "% Used Inodes" 744 | }, 745 | { 746 | "counterName": "Free Megabytes" 747 | }, 748 | { 749 | "counterName": "% Used Space" 750 | }, 751 | { 752 | "counterName": "Disk Transfers/sec" 753 | }, 754 | { 755 | "counterName": "Disk Reads/sec" 756 | }, 757 | { 758 | "counterName": "Disk Writes/sec" 759 | }, 760 | { 761 | "counterName": "Disk Read Bytes/sec" 762 | }, 763 | { 764 | "counterName": "Disk Write Bytes/sec" 765 | } 766 | ], 767 | "objectName": "Logical Disk", 768 | "instanceName": "*", 769 | "intervalSeconds": 10 770 | } 771 | }, 772 | { 773 | "apiVersion": "2020-08-01", 774 | "type": "dataSources", 775 | "name": "ProcessorPerfCounters", 776 | "dependsOn": [ 777 | "[variables('workspaceId')]" 778 | ], 779 | "kind": "LinuxPerformanceObject", 780 | "properties": { 781 | "performanceCounters": [ 782 | { 783 | "counterName": "% Processor Time" 784 | }, 785 | { 786 | "counterName": "% User Time" 787 | }, 788 | { 789 | "counterName": "% Privileged Time" 790 | }, 791 | { 792 | "counterName": "% IO Wait Time" 793 | }, 794 | { 795 | "counterName": "% Idle Time" 796 | }, 797 | { 798 | "counterName": "% Interrupt Time" 799 | } 800 | ], 801 | "objectName": "Processor", 802 | "instanceName": "*", 803 | "intervalSeconds": 10 804 | } 805 | }, 806 | { 807 | "apiVersion": "2020-08-01", 808 | "type": "dataSources", 809 | "name": "ProcessPerfCounters", 810 | "dependsOn": [ 811 | "[variables('workspaceId')]" 812 | ], 813 | "kind": "LinuxPerformanceObject", 814 | "properties": { 815 | "performanceCounters": [ 816 | { 817 | "counterName": "% User Time" 818 | }, 819 | { 820 | "counterName": "% Privileged Time" 821 | }, 822 | { 823 | "counterName": "Used Memory" 824 | }, 825 | { 826 | "counterName": "Virtual Shared Memory" 827 | } 828 | ], 829 | "objectName": "Process", 830 | "instanceName": "*", 831 | "intervalSeconds": 10 832 | } 833 | }, 834 | { 835 | "apiVersion": "2020-08-01", 836 | "type": "dataSources", 837 | "name": "SystemPerfCounters", 838 | "dependsOn": [ 839 | "[variables('workspaceId')]" 840 | ], 841 | "kind": "LinuxPerformanceObject", 842 | "properties": { 843 | "performanceCounters": [ 844 | { 845 | "counterName": "Processes" 846 | } 847 | ], 848 | "objectName": "System", 849 | "instanceName": "*", 850 | "intervalSeconds": 10 851 | } 852 | }, 853 | { 854 | "apiVersion": "2020-08-01", 855 | "type": "dataSources", 856 | "name": "NetworkPerfCounters", 857 | "dependsOn": [ 858 | "[variables('workspaceId')]" 859 | ], 860 | "kind": "LinuxPerformanceObject", 861 | "properties": { 862 | "performanceCounters": [ 863 | { 864 | "counterName": "Total Bytes Transmitted" 865 | }, 866 | { 867 | "counterName": "Total Bytes Received" 868 | }, 869 | { 870 | "counterName": "Total Bytes" 871 | }, 872 | { 873 | "counterName": "Total Packets Transmitted" 874 | }, 875 | { 876 | "counterName": "Total Packets Received" 877 | }, 878 | { 879 | "counterName": "Total Rx Errors" 880 | }, 881 | { 882 | "counterName": "Total Tx Errors" 883 | }, 884 | { 885 | "counterName": "Total Collisions" 886 | } 887 | ], 888 | "objectName": "Network", 889 | "instanceName": "*", 890 | "intervalSeconds": 10 891 | } 892 | }, 893 | { 894 | "apiVersion": "2020-08-01", 895 | "type": "dataSources", 896 | "name": "MemorydataSources", 897 | "dependsOn": [ 898 | "[variables('workspaceId')]" 899 | ], 900 | "kind": "LinuxPerformanceObject", 901 | "properties": { 902 | "performanceCounters": [ 903 | { 904 | "counterName": "Available MBytes Memory" 905 | }, 906 | { 907 | "counterName": "% Available Memory" 908 | }, 909 | { 910 | "counterName": "Used Memory MBytes" 911 | }, 912 | { 913 | "counterName": "% Used Memory" 914 | } 915 | ], 916 | "objectName": "Memory", 917 | "instanceName": "*", 918 | "intervalSeconds": 10 919 | } 920 | }, 921 | { 922 | "apiVersion": "2020-08-01", 923 | "type": "dataSources", 924 | "name": "SampleLinuxPerfCollection1", 925 | "dependsOn": [ 926 | "[variables('workspaceId')]" 927 | ], 928 | "kind": "LinuxPerformanceCollection", 929 | "properties": { 930 | "state": "Enabled" 931 | } 932 | } 933 | ] 934 | }, 935 | { 936 | "type": "Microsoft.Network/privateDnsZones", 937 | "apiVersion": "2020-06-01", 938 | "name": "[variables('filePrivateDnsZoneName')]", 939 | "location": "global", 940 | "properties": { 941 | "maxNumberOfRecordSets": 25000, 942 | "maxNumberOfVirtualNetworkLinks": 1000, 943 | "maxNumberOfVirtualNetworkLinksWithRegistration": 100 944 | } 945 | }, 946 | { 947 | "type": "Microsoft.Network/privateDnsZones", 948 | "apiVersion": "2020-06-01", 949 | "name": "[variables('blobPrivateDnsZoneName')]", 950 | "location": "global", 951 | "properties": { 952 | "maxNumberOfRecordSets": 25000, 953 | "maxNumberOfVirtualNetworkLinks": 1000, 954 | "maxNumberOfVirtualNetworkLinksWithRegistration": 100 955 | } 956 | }, 957 | { 958 | "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", 959 | "apiVersion": "2020-06-01", 960 | "name": "[concat(variables('filePrivateDnsZoneName'), '/link_to_', toLower(parameters('virtualNetworkName')))]", 961 | "location": "global", 962 | "dependsOn": [ 963 | "[variables('filePrivateDnsZoneId')]", 964 | "[variables('vnetId')]" 965 | ], 966 | "properties": { 967 | "registrationEnabled": false, 968 | "virtualNetwork": { 969 | "id": "[variables('vnetId')]" 970 | } 971 | } 972 | }, 973 | { 974 | "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", 975 | "apiVersion": "2020-06-01", 976 | "name": "[concat(variables('blobPrivateDnsZoneName'), '/link_to_', toLower(parameters('virtualNetworkName')))]", 977 | "location": "global", 978 | "dependsOn": [ 979 | "[variables('blobPrivateDnsZoneId')]", 980 | "[variables('vnetId')]" 981 | ], 982 | "properties": { 983 | "registrationEnabled": false, 984 | "virtualNetwork": { 985 | "id": "[variables('vnetId')]" 986 | } 987 | } 988 | }, 989 | { 990 | "type": "Microsoft.Network/privateEndpoints", 991 | "apiVersion": "2020-07-01", 992 | "name": "[parameters('blobStorageAccountPrivateEndpointName')]", 993 | "location": "[parameters('location')]", 994 | "dependsOn": [ 995 | "[variables('vnetId')]", 996 | "[variables('blobStorageAccountId')]" 997 | ], 998 | "properties": { 999 | "privateLinkServiceConnections": [ 1000 | { 1001 | "name": "[parameters('blobStorageAccountPrivateEndpointName')]", 1002 | "properties": { 1003 | "privateLinkServiceId": "[variables('blobStorageAccountId')]", 1004 | "groupIds": [ 1005 | "[variables('blobStorageAccountPrivateEndpointGroupName')]" 1006 | ] 1007 | } 1008 | } 1009 | ], 1010 | "subnet": { 1011 | "id": "[variables('subnetId')]" 1012 | } 1013 | } 1014 | }, 1015 | { 1016 | "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", 1017 | "apiVersion": "2020-07-01", 1018 | "name": "[variables('blobPrivateDnsZoneGroup')]", 1019 | "location": "[parameters('location')]", 1020 | "dependsOn": [ 1021 | "[variables('blobPrivateDnsZoneId')]", 1022 | "[variables('blobStorageAccountPrivateEndpointId')]" 1023 | ], 1024 | "properties": { 1025 | "privateDnsZoneConfigs": [ 1026 | { 1027 | "name": "dnsConfig", 1028 | "properties": { 1029 | "privateDnsZoneId": "[variables('blobPrivateDnsZoneId')]" 1030 | } 1031 | } 1032 | ] 1033 | } 1034 | } 1035 | ], 1036 | "outputs": { 1037 | "storageAccountPrivateEndpoint": { 1038 | "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('fileStorageAccountPrivateEndpointName')), '2020-07-01', 'Full')]", 1039 | "type": "object" 1040 | }, 1041 | "blobStorageAccountPrivateEndpoint": { 1042 | "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('blobStorageAccountPrivateEndpointName')), '2020-07-01', 'Full')]", 1043 | "type": "object" 1044 | }, 1045 | "fileStorageAccount": { 1046 | "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('fileStorageAccountName')), '2019-06-01', 'Full')]", 1047 | "type": "object" 1048 | }, 1049 | "blobStorageAccount": { 1050 | "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('blobStorageAccountName')), '2019-06-01', 'Full')]", 1051 | "type": "object" 1052 | }, 1053 | "adminUsername": { 1054 | "value": "[parameters('adminUsername')]", 1055 | "type": "string" 1056 | }, 1057 | "workspaceName": { 1058 | "value": "[parameters('workspaceName')]", 1059 | "type": "string" 1060 | }, 1061 | "scriptFileUri": { 1062 | "value": "[variables('scriptFileUri')]", 1063 | "type": "string" 1064 | }, 1065 | "environment": { 1066 | "value": "[environment()]", 1067 | "type": "object" 1068 | } 1069 | } 1070 | } -------------------------------------------------------------------------------- /templates/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "virtualNetworkName": { 6 | "value": "TestVnet" 7 | }, 8 | "virtualNetworkAddressPrefix": { 9 | "value": "10.0.0.0/16" 10 | }, 11 | "subnetName": { 12 | "value": "DefaultSubnet" 13 | }, 14 | "subnetAddressPrefix": { 15 | "value": "10.0.0.0/24" 16 | }, 17 | "vmName": { 18 | "value": "TestVm" 19 | }, 20 | "vmSize": { 21 | "value": "Standard_F4s_v2" 22 | }, 23 | "imagePublisher": { 24 | "value": "Canonical" 25 | }, 26 | "imageOffer": { 27 | "value": "UbuntuServer" 28 | }, 29 | "imageSku": { 30 | "value": "18.04-LTS" 31 | }, 32 | "authenticationType": { 33 | "value": "password" 34 | }, 35 | "adminUsername": { 36 | "value": "azadmin" 37 | }, 38 | "adminPasswordOrKey": { 39 | "value": "Passw0rd!" 40 | }, 41 | "diskStorageAccounType": { 42 | "value": "Premium_LRS" 43 | }, 44 | "numDataDisks": { 45 | "value": 1 46 | }, 47 | "osDiskSize": { 48 | "value": 50 49 | }, 50 | "dataDiskSize": { 51 | "value": 50 52 | }, 53 | "dataDiskCaching": { 54 | "value": "ReadWrite" 55 | }, 56 | "scriptFilePath": { 57 | "value": "https://paolosalvatori.blob.core.windows.net/scripts" 58 | }, 59 | "scriptFileName": { 60 | "value": "servicebus_nslookup.sh" 61 | }, 62 | "deployLogAnalytics": { 63 | "value": true 64 | }, 65 | "workspaceName": { 66 | "value": "ServiceBusPrivateLinkTestWorkspace" 67 | }, 68 | "workspaceSku": { 69 | "value": "Standard" 70 | }, 71 | "networkAclsDefaultAction": { 72 | "value": "Deny" 73 | }, 74 | "allowBlobPublicAccess": { 75 | "value": true 76 | }, 77 | "fileShareName": { 78 | "value": "documents" 79 | }, 80 | "shareQuota": { 81 | "value": 5120 82 | } 83 | } 84 | } --------------------------------------------------------------------------------