0
votes

I am trying to deploy a V2 Storage Account along with Private Endpoint and Private link using ARM Template. I already have a Resource Group, VNET and Subnet existing in my Subscription and i would like to leverage them to provision a new Storage Account with a Private Endpoint and Private Link.

When i run the command from powershell to deploy the ARM Template it throws me the error though i am able to see Private Endpoint and Storage Account being created. What i don't see is the Private Link

New-AzResourceGroupDeployment : 11:02:18 PM - The deployment 'Storacc_PvtEndpoint' 
failed with error(s). Showing 1 out of 1 error(s).
Status Message: Cannot parse the request. (Code: InvalidRequestFormat)
 - Error converting value "blob" to type 
'System.Collections.Generic.ICollection`1[System.String]'. Path 
'properties.privateLinkServiceConnections[0].properties.groupIds', line 1, position 
336. (Code:InvalidJson)
CorrelationId: 9606ab6b-35d6-49c0-a811-fa5154ff83e6
At line:1 char:1
+ New-AzResourceGroupDeployment -ResourceGroupName dops-pipeline -Templ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-AzResourceGroupDeployment], Exc 
   eption
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Imple 
   mentation.NewAzureResourceGroupDeploymentCmdlet
 


DeploymentName          : Storacc_PvtEndpoint
ResourceGroupName       : dops-pipeline
ProvisioningState       : Failed
Timestamp               : 5/26/2021 2:02:13 AM
Mode                    : Incremental
TemplateLink            : 
Parameters              : 
                          Name                                     Type              
                                   Value     
                          =======================================  
                          =========================  ==========
                          storageAccountType                       String            
                                   Standard_LRS
                          location                                 String            
                                   canadacentral
                          containerPrefix                          String            
                                   canadacentral
                          vnetName                                 String            
                                   pvt-endpoint-vnet
                          subnetName                               String            
                                   blob-pvt-endpoint-sub
                          resourceGroupName                        String            
                                   dops-pipeline
                          blobStorageAccountPrivateEndpointName    String            
                                   endpointsht5gcoc5cztq
                          
Outputs                 : 
DeploymentDebugLogLevel : 

Please find below my ARM Template

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccountType": {
            "type": "string",
            "defaultValue": "Standard_LRS",
            "allowedValues": [
                "Standard_LRS",
                "Standard_GRS",
                "Standard_ZRS",
                "Premium_LRS"
            ],
            "metadata": {
                "description": "Storage Account type"
            }
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Storage Account Location"
            }
        },
        "containerPrefix" : {
            "type"          : "string",
            "defaultValue"  : "[resourceGroup().location]"
        },
        "vnetName" : {
            "type"           : "string",
            "defaultValue"   : "pvt-endpoint-vnet"
        },
        "subnetName"         : {
            "type"           : "string",
            "defaultValue"   : "blob-pvt-endpoint-sub"
        },
        "resourceGroupName"  : {
            "type"           : "string",
            "defaultValue"   : "dops-pipeline"
        },
        "blobStorageAccountPrivateEndpointName" : {
            "type"            : "string",
            "defaultValue"    : "[toLower(concat('endpoint',uniqueString(resourceGroup().id)))]"
        }
},
    "variables": {
        "blobstorageAccountName"                      : "[tolower(concat('stor', uniquestring(subscription().id,resourceGroup().id)))]",
        "blobStorageAccountId"                        : "[resourceId('Microsoft.Storage/storageAccounts', variables('blobStorageAccountName'))]",
        "blobPublicDNSZoneForwarder"                  : "[concat('.blob.', environment().suffixes.storage)]",
        "blobPrivateDNSZoneName"                      : "[concat('privatelink', variables('blobPublicDNSZoneForwarder'))]",
        "blobPrivateDnsZoneId"                        : "[resourceId('Microsoft.Network/privateDnsZones', variables('blobPrivateDnsZoneName'))]",
        "blobPrivateDnsZoneGroup"                     : "[concat(parameters('blobStorageAccountPrivateEndpointName'),'/', variables('blobStorageAccountPrivateEndpointGroupName'), 'PrivateDnsZoneGroup')]",
        "blobStorageAccountPrivateEndpointGroupName"  : "blob",
        "vnetId"                                      : "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',parameters('resourceGroupName'),'/providers/','Microsoft.Network/virtualNetworks/',parameters('vnetName'))]",
        "subnetId"                                    : "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/',parameters('resourceGroupName'),'/providers/','Microsoft.Network/virtualNetworks/',parameters('vnetName'),'/subnets/',parameters('subnetName'))]"
    },
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2021-01-01",
            "name": "[variables('blobstorageAccountName')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "[parameters('storageAccountType')]"
            },
            "kind": "StorageV2",
            "properties": {
                "minimumTlsVersion"     : "TLS1_2",
                "allowBlobPublicAccess" : false,
                "networkAcls": {
                    "bypass" : "AzureServices",
                    "defaultAction" : "Deny",
                    "virtualNetworkRules" : [
                        {
                            "id"     : "[variables('subnetId')]",
                            "action" : "Allow"
                        }
                    ]
                }
            }
        },
        {
            "type"      : "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
            "apiVersion": "2018-09-01",
            "name"      : "[concat(variables('blobPrivateDNSZoneName'), '/link_to_', toLower(parameters('vnetName')))]",
            "location"  : "global",
            "dependsOn" : [
                "[variables('blobPrivateDnsZoneId')]"
            ],
            "properties" : {
                "registrationEnabled" : false,
                "virtualNetwork"      : {
                    "id"              : "[variables('vnetId')]"
                }
            }
        },
        {
            "type"       : "Microsoft.Network/privateEndpoints",
            "apiVersion" : "2020-04-01",
            "name"       : "[parameters('blobStorageAccountPrivateEndpointName')]",
            "location"   : "[resourceGroup().location]",
            "dependsOn"  : [
                "[variables('blobStorageAccountId')]"
            ],
            "properties" : {
                "privateLinkServiceConnections" : [
                    {
                      "name" : "parameters('blobStorageAccountPrivateEndpointName')",
                      "properties" : { 
                            "privateLinkServiceId"  : "[variables('blobStorageAccountId')]",
                            "groupIds"              : "[variables('blobStorageAccountPrivateEndpointGroupName')]"
                        }
                    }
                ],
                "subnet" :{
                    "id" : "[variables('subnetId')]"
                },
                "customDnsConfigs" : [
                    {
                        "fqdn"     : "[concat(variables('blobStorageAccountName'),variables('blobPublicDNSZoneForwarder'))]"
                    }
                ]
            }
        },
        {
            "type"       : "Microsoft.Network/privateDnsZones",
            "apiVersion" : "2018-09-01",
            "name"       : "[variables('blobPrivateDNSZoneName')]",
            "location"   : "global",
            "properties" : {
                "maxNumberOfRecordSets"                            : 25000,
                "maxNumberOfVirtualNetworkLinks"                   : 1000,
                "maxNumberOfVirtualNetworkLinksWithRegistration"   : 100
            }
        },
        {
            "type"       : "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
            "apiVersion" : "2020-03-01",
            "name"       : "[variables('blobPrivateDnsZoneGroup')]",
            "location"   : "[resourceGroup().location]",
            "dependsOn"  : [
                "[variables('blobPrivateDnsZoneId')]",
                "[parameters('blobStorageAccountPrivateEndpointName')]"
            ],
            "properties"  : {
                "privateDnsZoneConfigs" :[
                    {
                        "name"       : "dnsConfig",
                        "properties" : {
                            "privateDnsZoneId" : "[variables('blobPrivateDnsZoneId')]"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices",
            "apiVersion": "2021-01-01",
            "name"      :"[tolower(concat(variables('blobstorageaccountname'), '/default'))]",
            "dependsOn": [
              "[resourceId('Microsoft.Storage/storageAccounts', variables('blobstorageAccountName'))]"
            ],
            "properties": {
                "isVersioningEnabled"   : true,
                "deleteRetentionPolicy" : {
                    "enabled" :  true,
                    "days"    :  30
                },
                "changeFeed"  : {
                    "enabled"        : true
                },
                "containerDeleteRetentionPolicy" :{
                    "enabled" : true,
                    "days"    : 30
                }
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "apiVersion": "2021-01-01",
            "name": "[concat(variables('blobstorageAccountName'), '/default/', parameters('containerPrefix'), copyIndex())]",
            "copy": {
                "name": "containercopy",
                "count": 2
            },
            "dependsOn": [
              "[resourceId('Microsoft.Storage/storageAccounts', variables('blobstorageAccountName'))]"
            ] 
        }
    ],
    "outputs": {
        "storageAccountName": {
            "type": "string",
            "value": "[variables('blobstorageAccountName')]"
        }
    }
}
1
you need to remove ` "[variables('vnetId')]"` from the dependsOn. You can only set depends on for resource declared in the templateThomas
Please remove [variables('vnetId')] from porperty dependsOn. Otherwise you need to define the resource in your template.Jim Xu
@Thomas I get the below error after removing the "[variables('vnetId)]", but i am able to see the storage account created along with the pvt-endpoint-vnet. But i don't see the private link though.Pallab
Which error ? you need to check all your dependson. If a resource is not defined in the template it shouldn't be used in dependsonThomas
@Thomas I have removed Depends on and pasted the new code on top if you see my main thread. I get this error now : Error converting value "blob" to typePallab

1 Answers

0
votes

This issue was solved by @Thomas's comments, just add them as an answer to close the question.

You need to remove "[variables('vnetId')]" from dependsOn, if a resource is not defined in the template it shouldn't be used in dependson, and the property groupIds is an array so should be : "groupIds": [ "[variables('blobStorageAccountPrivateEndpointGroupName')]"].

Reference - https://docs.microsoft.com/en-us/azure/templates/microsoft.network/privateendpoints?tabs=json