Azure Purview Ingestion Private Endpoint Creation using Bicep - azure

In most Azure resource private endpoints, I can configure them using a bicep script by calling 'Microsoft.Network/privateEndpoints'. With Purview, it has two kinds of private endpoints: the regular private endpoint and Ingestion private endpoint. When using the mentioned library, although I can create an endpoint, it is not shown under the Ingestion private endpoint connection name. If you do it through the portal, you will see that endpoint connection created there.
I also notice that there is another API named 'Microsoft.Purview/accounts/privateEndpointConnections' however, it only exposes two properties privateEndpoint.id and privateLinkServiceConnectionState - so this does not look like it will be appropriate to use either?
Therefore I wonder if anyone has tried to use Bicep to do the above? I realize that Purview Private endpoint is still under public preview so maybe there is no way to configure using Bicep yet. I also notice that we cannot export a Purview resource as an ARM template from the Azure Portal, so it leads me even more to believe that Bicep is not available for Purview? Just want to confirm with someone more knowledgeable in this before I decide to give up on it.

As Azure Purview is still In preview it is an evolving tool .
Below I am providing two ARM template one for Account and Portal endpoints and one for ingestion endpoints ( I have pasted here two ARM templates and there parametrized file)
Note :- Portal, Account and ingestion endpoint should be in same vnet and subnet
1-ARM template for Portal and account endpoint
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"privateEndpointName-account": {
"type": "String"
},
"privateEndpointName-portal": {
"type": "String"
},
"purview_account_externalid": {
"type": "String"
},
"targetSubResource-account": {
"type": "Array"
},
"targetSubResource-portal": {
"type": "Array"
},
"subnet": {
"type": "String"
},
"virtualNetworkName": {
"type": "String"
},
"privateDnsDeploymentName": {
"type": "String"
},
"virtualNetworkLinkName": {
"type": "String"
},
"privateDNS": {
"type": "String"
}
},
"resources": [
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-03-01",
"name": "[parameters('privateEndpointName-account')]",
"location": "[parameters('location')]",
"tags": {
},
"properties": {
"subnet": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), '/subnets/', parameters('subnet'))]"
},
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpointName-account')]",
"properties": {
"privateLinkServiceId": "[parameters('purview_account_externalid')]",
"groupIds": "[parameters('targetSubResource-account')]"
}
}
]
}
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-03-01",
"name": "[parameters('privateEndpointName-portal')]",
"location": "[parameters('location')]",
"tags": {
},
"properties": {
"subnet": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), '/subnets/', parameters('subnet'))]"
},
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpointName-portal')]",
"properties": {
"privateLinkServiceId": "[parameters('purview_account_externalid')]",
"groupIds": "[parameters('targetSubResource-portal')]"
}
}
]
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[parameters('privateDnsDeploymentName')]",
"dependsOn": [
"[parameters('privateEndpointName-portal')]",
"[parameters('privateEndpointName-account')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2017-05-10",
"name": "[concat(parameters('privateDnsDeploymentName'), '-zone')]",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateDnsZones",
"apiVersion": "2018-09-01",
"name": "[parameters('privateDNS')]",
"location": "global",
"tags": {
},
"properties": {
}
}
]
}
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[parameters('virtualNetworkLinkName')]",
"dependsOn": [
"[parameters('privateDnsDeploymentName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2017-05-10",
"name": "[concat(parameters('virtualNetworkLinkName'), '-link')]",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
"apiVersion": "2018-09-01",
"name": "[concat(parameters('privateDNS'), '/', uniqueString(parameters('virtualNetworkName')))]",
"location": "global",
"properties": {
"virtualNetwork": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
},
"registrationEnabled": false
}
}
]
}
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[concat(parameters('privateEndpointName-account'), '-', 'default')]",
"dependsOn": [
"[parameters('privateEndpointName-account')]",
"[parameters('privateDnsDeploymentName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"name": "[concat(parameters('privateEndpointName-account'), '/', 'default')]",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "[parameters('privateDNS')]",
"properties": {
"privateDnsZoneId": "[concat(resourceGroup().id, '/providers/Microsoft.Network/privateDnsZones/', parameters('privateDNS'))]"
}
}
]
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[concat(parameters('privateEndpointName-portal'), '-', 'default')]",
"dependsOn": [
"[parameters('privateEndpointName-portal')]",
"[parameters('privateDnsDeploymentName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"name": "[concat(parameters('privateEndpointName-portal'), '/', 'default')]",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "[parameters('privateDNS')]",
"properties": {
"privateDnsZoneId": "[concat(resourceGroup().id, '/providers/Microsoft.Network/privateDnsZones/', parameters('privateDNS'))]"
}
}
]
}
}
]
}
}
}
]}
2- Parameterized file for Account and Portal Endpoints
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "Type the location of endpoint here"
},
"privateEndpointName-account": {
"value": "Type the name of Account endpoint here"
},
"privateEndpointName-portal": {
"value": "Type the name of Portal Endpoint here"
},
"purview_account_externalid": {
"value": "Go to azure portal > Purview >Properties >Resource Id,This is resource ID of the Purview "
},
"targetSubResource-account": {
"value": [
"account"
]
},
"targetSubResource-portal": {
"value": [
"portal"
]
},
"subnet": {
"value": "Type the name subnet here "
},
"virtualNetworkName": {
"value": "Type the name of the virtual network here "
},
"privateDnsDeploymentName": {
"value": "privatelink.purview.azure.com"
},
"virtualNetworkLinkName": {
"value": ""
},
"privateDNS": {
"value": "privatelink.purview.azure.com"
}
}}
3-ARM Template for Ingestion Endpoint
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ingestionEndpointName": {
"type": "String"
},
"purviewManagedRGId": {
"type": "String"
},
"virtualNetworksName": {
"type": "String"
},
"purviewManagedRGEventHubsNamespaceId": {
"type": "String"
},
"managedStorageAccountName": {
"type": "string"
},
"resourceGroupId": {
"type": "string"
},
"subnet": {
"type": "String"
},
"privateDnsZonesLinkBlob": {
"defaultValue": "privatelink.blob.core.windows.net",
"type": "String"
},
"privateDnsZonesLinkServicebus": {
"defaultValue": "privatelink.servicebus.windows.net",
"type": "String"
},
"privateDnsZonesLinkQueue": {
"defaultValue": "privatelink.queue.core.windows.net",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-blob')]",
"location": "eastus",
"tags": {
"ContactEmail": "<not defined, please set>",
"ContactName": "<not defined, please set>",
"Department": "<not defined, please set>",
"Environment": "SANDBOX",
"OwnerName": "<not defined, please set>",
"Project": "<not defined, please set>"
},
"properties": {
"privateLinkServiceConnections": [
{
"name": "[concat(parameters('ingestionEndpointName'),'-blob')]",
"properties": {
"privateLinkServiceId": "[concat(parameters('purviewManagedRGId'),'/providers/Microsoft.Storage/storageAccounts/',parameters('managedStorageAccountName'))]",
"groupIds": [
"blob"
],
"privateLinkServiceConnectionState": {
"status": "Approved",
"description": "Auto-Approved",
"actionsRequired": "None"
}
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/virtualNetworks/',parameters('virtualNetworksName'), '/subnets/',parameters('subnet'))]"
},
"customDnsConfigs": []
}
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-namespace')]",
"location": "eastus",
"tags": {
"ContactEmail": "<not defined, please set>",
"ContactName": "<not defined, please set>",
"Department": "<not defined, please set>",
"Environment": "SANDBOX",
"OwnerName": "<not defined, please set>",
"Project": "<not defined, please set>"
},
"properties": {
"privateLinkServiceConnections": [
{
"name": "[concat(parameters('ingestionEndpointName'),'-namespace')]",
"properties": {
"privateLinkServiceId": "[parameters('purviewManagedRGEventHubsNamespaceId')]",
"groupIds": [
"namespace"
],
"privateLinkServiceConnectionState": {
"status": "Approved",
"description": "Auto-Approved",
"actionsRequired": "None"
}
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.Network/virtualNetworks/',parameters('virtualNetworksName'), '/subnets/',parameters('subnet'))]"
},
"customDnsConfigs": []
}
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-queue')]",
"location": "eastus",
"tags": {
"ContactEmail": "<not defined, please set>",
"ContactName": "<not defined, please set>",
"Department": "<not defined, please set>",
"Environment": "SANDBOX",
"OwnerName": "<not defined, please set>",
"Project": "<not defined, please set>"
},
"properties": {
"privateLinkServiceConnections": [
{
"name": "[concat(parameters('ingestionEndpointName'),'-queue')]",
"properties": {
"privateLinkServiceId": "[concat(parameters('purviewManagedRGId'),'/providers/Microsoft.Storage/storageAccounts/',parameters('managedStorageAccountName'))]",
"groupIds": [
"queue"
],
"privateLinkServiceConnectionState": {
"status": "Approved",
"description": "Auto-Approved",
"actionsRequired": "None"
}
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.Network/virtualNetworks/',parameters('virtualNetworksName'), '/subnets/',parameters('subnet'))]"
},
"customDnsConfigs": []
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-blob','/default')]",
"dependsOn": [
"[resourceId('Microsoft.Network/privateEndpoints', concat(parameters('ingestionEndpointName'),'-blob'))]"
],
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-blob-core-windows-net",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/privateDnsZones/',parameters('privateDnsZonesLinkBlob'))]"
}
}
]
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-namespace','/default')]",
"dependsOn": [
"[resourceId('Microsoft.Network/privateEndpoints', concat(parameters('ingestionEndpointName'),'-namespace'))]"
],
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-servicebus-windows-net",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/privateDnsZones/',parameters('privateDnsZonesLinkServicebus'))]"
}
}
]
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-queue','/default')]",
"dependsOn": [
"[resourceId('Microsoft.Network/privateEndpoints', concat(parameters('ingestionEndpointName'),'-queue'))]"
],
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-queue-core-windows-net",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/privateDnsZones/',parameters('privateDnsZonesLinkQueue'))]"
}
}
]
}
}
]}
4- Parameterized file for Ingestion Endpoint template
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ingestionEndpointName": {
"value": "Type the name of Ingestion Endpoint here"
},
"purviewManagedRGId": {
"value": "Go to azure portal > Purview> ManagedResource > Properties> Resource id This is the Resources ID of purview managed resource group"
},
"virtualNetworkName": {
"value": "Give the name of the Virtual network here"
},
"purviewManagedRGEventHubsNamespaceId": {
"value": "Go to azure portal > Purview>Managed Resource > Event Hubs namespace name>properties >Resource IDThis is Purview managed Event hub name space resources Id "
},
"managedStorageAccountName": {
"value": "Go to azure portal > Purview>Managed Resource > Storage Account"
},
"resourceGroupId": {
"value": "Go to azure portal > Purview> overview >resourceGroup"
},
"subnet": {
"value": "Give the name the subnet"
}
}}

Related

Enable update management for automation account

I am trying to link automation account with log analytics and enable update management with below arm template. The resources are getting linked, however not enabling update management. Am I missing something in code
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"dependsOn": [
"[resourceId('Microsoft.OperationalInsights/workspaces','Dev-Loganalyticsworkspace')]",
"[resourceId('Microsoft.Automation/automationAccounts','Dev-Automationaccount')]"
],
"name": "Dev-Loganalyticsworkspace/automation",
"properties": {
"resourceId": "[resourceId('Microsoft.Automation/automationAccounts', 'Dev-Automationaccount')]"
},
"type": "Microsoft.OperationalInsights/workspaces/linkedServices",
"location": "CentralIndia",
"apiVersion": "2020-08-01"
}
]
}
Please find below the updated code. This is executing succesfully, but as mentioned, update management is unable to found
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "Dev-Automationaccount",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"sku": {
"name": "Basic"
}
},
"tags": {
"displayName": "Automation Account.",
"provider": "Kyniac"
},
"comments": "The automation account for LogAnalytics WorkSpace",
"type": "Microsoft.Automation/automationAccounts",
"location": "UK South",
"apiVersion": "2021-06-22"
},
{
"name": "Dev-Loganalyticsworkspace",
"properties": {
"features": {
"searchVersion": 1
},
"sku": {
"retentionInDays": 120,
"resourcePermissions": true,
"heartbeatTableRetention": 90,
"name": "pergb2018"
}
},
"tags": {
"displayName": "LAWorkspace for storing all the logs and metrics.",
"provider": "Kyniac"
},
"comments": "LAWorkspace for storing all the logs and metrics.",
"type": "Microsoft.OperationalInsights/workspaces",
"location": "UK South",
"apiVersion": "2021-12-01-preview"
},
{
"dependsOn": [
"[resourceId('Microsoft.OperationalInsights/workspaces','Dev-Loganalyticsworkspace')]",
"[resourceId('Microsoft.Automation/automationAccounts','Dev-Automationaccount')]"
],
"name": "Dev-Loganalyticsworkspace/automation",
"properties": {
"resourceId": "[resourceId('Microsoft.Automation/automationAccounts', 'Dev-Automationaccount')]"
},
"type": "Microsoft.OperationalInsights/workspaces/linkedServices",
"location": "UK South",
"apiVersion": "2020-08-01"
},
{
"dependsOn": [
"[resourceId('Microsoft.OperationalInsights/workspaces', 'Dev-Loganalyticsworkspace')]"
],
"name": "Updates(Dev-Loganalyticsworkspace)",
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', 'Dev-Loganalyticsworkspace')]"
},
"plan": {
"name": "Updates(Dev-Loganalyticsworkspace)",
"product": "OMSGallery/Updates",
"publisher": "Microsoft",
"promotionCode": " "
},
"type": "Microsoft.OperationsManagement/solutions",
"location": "UK South",
"apiVersion": "2015-11-01-preview"
}
]
}
I have tried running your shared arm template in my local visual studio using the PowerShell cmdlet New-AzResourceGroupDeployment Template validation is falling with below error.
New-AzResourceGroupDeployment: 14:51:17 - Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The resource 'Microsoft.Automation/automationAccounts/<automationAccount>' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.
You need to create log analytics solution to enable update management of automation account with log analytics.
I have made the necessary changes to your ARM template that you have shared earlier:
Here is the ARM template:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"automationAccountName": {
"type": "string"
},
"workspaceName": {
"type": "string"
}
},
"functions": [],
"variables": {
"updates": {
"name": "[concat('Updates', '(', parameters('workspaceName'), ')')]",
"galleryName": "Updates"
}
},
"resources": [
{
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2021-12-01-preview",
"name":"[parameters('workspaceName')]",
"location":"westus",
"properties":{
"sku": {
"name": "PerGB2018"
}
},
"resources": [
{
"type":"Microsoft.OperationsManagement/solutions",
"apiVersion":"2015-11-01-preview",
"location":"westus",
"name": "[variables('updates').name]",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('updates').name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('updates').name]",
"publisher": "Microsoft",
"promotionCode": "",
"product": "[concat('OMSGallery/', variables('updates').galleryName)]"
}
}
]
},
{
"type": "Microsoft.Automation/automationAccounts",
"apiVersion": "2021-06-22",
"name":"[parameters('automationAccountName')]",
"location":"westus",
"properties":{
"sku": {
"name": "Basic"
}
}
},
{
"type":"Microsoft.OperationalInsights/workspaces/linkedServices",
"apiVersion": "2020-08-01",
"name": "[concat(parameters('workspaceName'),'/','Automation')]",
"dependsOn":[
"[resourceId('Microsoft.OperationalInsights/workspaces',parameters('workspaceName'))]",
"[resourceId('Microsoft.Automation/automationAccounts',parameters('automationAccountName'))]"
],
"location":"westus",
"properties": {
"resourceId":"[resourceId('Microsoft.Automation/automationAccounts/',parameters('automationAccountName'))]"
}
}
],
"outputs": {}
}
I have tested the above ARM template and it is working fine from my end. I would suggest you to test it from your end as well.

ARM Template Coginitive services

I need a ARM template for Form Recognizer. It would be helpful if anyone can share a working template for this
ARM template for Form Recognizer
We have tried to create form recognizer in Azure and test the deployment using below template.
ARM TEMPLETE:-
sample.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"resourceGroupName": {
"type": "string"
},
"resourceGroupId": {
"type": "string"
},
"sku": {
"type": "string"
},
"tagValues": {
"type": "object"
},
"virtualNetworkType": {
"type": "string"
},
"vnet": {
"type": "object"
},
"ipRules": {
"type": "array"
},
"identity": {
"type": "object"
},
"privateEndpoints": {
"type": "array"
},
"isCommitmentPlanForDisconnectedContainerEnabled": {
"type": "bool"
},
"commitmentPlanForDisconnectedContainer": {
"type": "object"
}
},
"variables": {
"defaultVNetName": "frCSDefaultVNet9901",
"defaultSubnetName": "frCSDefaultSubnet9901",
"defaultAddressPrefix": "13.41.6.0/26"
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "deployVnet",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-04-01",
"name": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').name, variables('defaultVNetName'))]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').addressPrefixes, json(concat('[{\"', variables('defaultAddressPrefix'),'\"}]')))]"
},
"subnets": [
{
"name": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').subnets.subnet.name, variables('defaultSubnetName'))]",
"properties": {
"serviceEndpoints": [
{
"service": "Microsoft.CognitiveServices",
"locations": [
"[parameters('location')]"
]
}
],
"addressPrefix": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').subnets.subnet.addressPrefix, variables('defaultAddressPrefix'))]"
}
}
]
}
}
]
},
"parameters": {}
},
"condition": "[and(and(not(empty(parameters('vnet'))), equals(parameters('vnet').newOrExisting, 'new')), equals(parameters('virtualNetworkType'), 'External'))]"
},
{
"apiVersion": "2021-04-30",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"type": "Microsoft.CognitiveServices/accounts",
"kind": "FormRecognizer",
"tags": "[if(contains(parameters('tagValues'), 'Microsoft.CognitiveServices/accounts'), parameters('tagValues')['Microsoft.CognitiveServices/accounts'], json('{}'))]",
"sku": {
"name": "[parameters('sku')]"
},
"identity": "[parameters('identity')]",
"properties": {
"customSubDomainName": "[toLower(parameters('name'))]",
"publicNetworkAccess": "[if(equals(parameters('virtualNetworkType'), 'Internal'), 'Disabled', 'Enabled')]",
"networkAcls": {
"defaultAction": "[if(equals(parameters('virtualNetworkType'), 'External'), 'Deny', 'Allow')]",
"virtualNetworkRules": "[if(equals(parameters('virtualNetworkType'), 'External'), json(concat('[{\"id\": \"', concat(subscription().id, '/resourceGroups/', parameters('vnet').resourceGroup, '/providers/Microsoft.Network/virtualNetworks/', parameters('vnet').name, '/subnets/', parameters('vnet').subnets.subnet.name), '\"}]')), json('[]'))]",
"ipRules": "[if(or(empty(parameters('ipRules')), empty(parameters('ipRules')[0].value)), json('[]'), parameters('ipRules'))]"
}
},
"resources": [
{
"type": "commitmentPlans",
"apiVersion": "2021-10-01",
"name": "DisconnectedContainer-FormRecognizer-1",
"properties": "[parameters('commitmentPlanForDisconnectedContainer')]",
"condition": "[parameters('isCommitmentPlanForDisconnectedContainerEnabled')]",
"dependsOn": [
"[parameters('name')]"
]
}
],
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', 'deployVnet')]"
]
},
{
"apiVersion": "2017-05-10",
"name": "[concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpoint.name)]",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('privateEndpoints')[copyIndex()].resourceGroup.value.name]",
"subscriptionId": "[parameters('privateEndpoints')[copyIndex()].subscription.subscriptionId]",
"dependsOn": [
"[parameters('name')]"
],
"condition": "[equals(parameters('virtualNetworkType'), 'Internal')]",
"copy": {
"name": "privateendpointscopy",
"count": "[length(parameters('privateEndpoints'))]"
},
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"location": "[parameters('location')]",
"name": "[parameters('privateEndpoints')[copyIndex()].privateEndpoint.name]",
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-03-01",
"properties": {
"subnet": {
"id": "[parameters('privateEndpoints')[copyIndex()].privateEndpoint.properties.subnet.id]"
},
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpoints')[copyIndex()].privateEndpoint.name]",
"properties": {
"privateLinkServiceId": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.CognitiveServices/accounts/', parameters('name'))]",
"groupIds": "[parameters('privateEndpoints')[copyIndex()].privateEndpoint.properties.privateLinkServiceConnections[0].properties.groupIds]"
}
}
]
},
"tags": {}
}
]
}
}
},
{
"apiVersion": "2017-05-10",
"name": "[concat('deployDnsZoneGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpoint.name)]",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('privateEndpoints')[copyIndex()].resourceGroup.value.name]",
"subscriptionId": "[parameters('privateEndpoints')[copyIndex()].subscription.subscriptionId]",
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpoint.name))]"
],
"condition": "[equals(parameters('virtualNetworkType'), 'Internal')]",
"copy": {
"name": "privateendpointdnscopy",
"count": "[length(parameters('privateEndpoints'))]"
},
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"name": "[concat(parameters('privateEndpoints')[copyIndex()].privateEndpoint.name, '/', 'default')]",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-cognitiveservices-azure-com",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.Network/privateDnsZones/privatelink.cognitiveservices.azure.com')]"
}
}
]
}
}
]
}
}
}
]
}
We have Saved the parameters in different file and deploy with referencing deployment file as below.
azuredeploy.parameter.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name":{
"value": "myrecognizer"
},
"location": {
"value": "westus2"
},
"resourceGroupName":{
"value": "my_resource_group"
},
"resourceGroupId": {
"value": "/subscriptions/subscID/resourceGroups/my_resource_group"
},
"sku":{
"value": "S0"
},
"tagValues":{
"value": {}
},
"virtualNetworkType":{
"value": "None"
},
"vnet":{
"value": {}
},
"ipRules":{
"value": []
},
"identity":{
"value": {
"type": "None"
}
},
"privateEndpoints":{
"value":[]
},
"isCommitmentPlanForDisconnectedContainerEnabled":{
"value": false
},
"commitmentPlanForDisconnectedContainer":{
"value": {
"current": {},
"hostingModel": "DisconnectedContainer",
"planType": "CustomInvoice",
"autoRenew": true
}
}
}
}
Deploy using below cmd in terminal :
az deployment group create -n TestDeployment -g myresourcegroup --template-file "C:\locationfile\sample.json" --parameters "C:\locationfile\azuredeploy.parameters.json"
Below are the SCREENSHOT FOR DEPLOYMENT DETAILS:-

Private Endpoint for a Storage Queue in ARM

I can create a Private Endpoint for a Storage Queue through the portal just fine and it works as intended when checking with nameresolver.exe from KUDU. However, I am struggling to find an ARM template that does this in one go.
I have made this template work but I can see that the A record entry does not get generated in the Private DNS Zone that is generated. I don't know how to create that A record entry and cannot seem to find a ARM template online that describes this:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"privateEndpointName": {
"type": "string",
"defaultValue": "privendpoint-sapriv01-queue"
},
"vnetName": {
"type": "string",
"defaultValue": "vn-myvnet01"
},
"subnetName": {
"type": "string",
"defaultValue": "sn-private-endpoints"
},
"groupId": {
"type": "string",
"defaultValue": "queue"
}
},
"variables": {
"privateDNSZone_name": "[concat('privatelink', '.queue.', environment().suffixes.storage)]"
},
"resources": [
{
"apiVersion": "2019-04-01",
"name": "[parameters('privateEndpointName')]",
"type": "Microsoft.Network/privateEndpoints",
"location": "[resourceGroup().Location]",
"properties": {
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpointName')]",
"properties": {
"privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', 'saprivendpointdemo')]",
"groupIds": [
"[parameters('groupId')]"
]
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName') )]"
}
}
},
{
"type": "Microsoft.Network/privateDnsZones",
"apiVersion": "2018-09-01",
"name": "[variables('privateDNSZone_name')]",
"location": "global",
"tags": {},
"properties": {}
},
{
"type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
"apiVersion": "2018-09-01",
"name": "[concat(variables('privateDNSZone_name'), '/', parameters('vnetName'), 'link' )]",
"location": "global",
"dependsOn": [
"[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZone_name'))]"
],
"properties": {
"virtualNetwork": {
"id": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
},
"registrationEnabled": false
}
}
],
"outputs": {
}
}
I think Microsoft overcomplicated this. The Private IP is auto generated and I don't know how one would reference this IP in the ARM template.
If you want to add A record in your Azure Private DNS Zone, you can define Microsoft.Network/privateEndpoints/privateDnsZoneGroups in your template.
For example
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"privateEndpointName": {
"type": "string",
"defaultValue": "testqueue"
},
"vnetName": {
"type": "string",
"defaultValue": "teststorage"
},
"subnetName": {
"type": "string",
"defaultValue": "default"
},
"groupId": {
"type": "string",
"defaultValue": "queue"
}
},
"variables": {
"privateDNSZone_name": "[concat('privatelink', '.queue.', environment().suffixes.storage)]"
},
"resources": [
{
"apiVersion": "2019-04-01",
"name": "[parameters('privateEndpointName')]",
"type": "Microsoft.Network/privateEndpoints",
"location": "[resourceGroup().Location]",
"properties": {
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpointName')]",
"properties": {
"privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', 'teststorage05')]",
"groupIds": [
"[parameters('groupId')]"
]
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName') )]"
}
}
},
{
"type": "Microsoft.Network/privateDnsZones",
"apiVersion": "2018-09-01",
"name": "[variables('privateDNSZone_name')]",
"dependsOn": [
"[parameters('privateEndpointName')]"
],
"location": "global",
"tags": {},
"properties": {}
},
{
"type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
"apiVersion": "2018-09-01",
"name": "[concat(variables('privateDNSZone_name'), '/', parameters('vnetName'), 'link' )]",
"location": "global",
"dependsOn": [
"[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZone_name'))]"
],
"properties": {
"virtualNetwork": {
"id": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
},
"registrationEnabled": false
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"name": "[concat(parameters('privateEndpointName'), '/', 'default')]",
"dependsOn": [
"[parameters('privateEndpointName')]",
"[variables('privateDNSZone_name')]"
],
"location": "[resourceGroup().Location]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-queue-core-windows-net",
"properties": {
"privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones',variables('privateDNSZone_name'))]"
}
}
]
}
}
],
"outputs": {
}
}
For more details, please refer to here and here

Conditionally deploy a route table with subnet using ARM template

I am trying to conditionally deploy a route template when deploying a subnet resource using an ARM template, however, I am not able to do so using the if condition. Would anyone know the correct syntax or what am I doing wrong?
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"routeTableConfigurationObject": {
"type": "object",
"defaultValue": null
},
"vnetConfigurationObject": {
"type": "object"
},
"Tags": {
"type": "object"
}
},
"resources": [
{
"type": "Microsoft.Network/virtualNetworks/Subnets",
"name": "[concat(parameters('vnetConfigurationObject').name,'/',parameters('vnetConfigurationObject').subnets[copyIndex()].name)]",
"location": "[parameters('vnetConfigurationObject').location]",
"apiVersion": "2018-08-01",
"copy": {
"name": "vnet",
"count": "[length(parameters('vnetConfigurationObject').subnets)]",
"mode": "serial"
},
"properties": {
"addressPrefix": "[parameters('vnetConfigurationObject').subnets[copyIndex()].addressPrefix]",
"routeTable": "[if(empty('routeTableConfigurationObject'), json('null'), json(concat('{\"id\": \"', '/subscriptions/', parameters('routeTableConfigurationObject').subscriptionId, '/resourceGroups/', parameters('routeTableConfigurationObject').resourceGroupName, '/providers/Microsoft.Network/routeTables/', parameters('vnetConfigurationObject').subnets[copyIndex()].routeTable,'\"}')))]"
}
}
]
}
try this:
"variables": [
"copy": [
{
"name": "route",
"count": "[length(parameters('vnetConfigurationObject').subnets)]",
"input": {
"id": "[resourceId(parameters('routeTableConfigurationObject').subscriptionId, parameters('routeTableConfigurationObject').resourceGroupName, 'Microsoft.Network/routeTables', parameters('vnetConfigurationObject').subnets[copyIndex('route')].routeTable)]"
}
}
]
],
"resources": [
{
"type": "Microsoft.Network/virtualNetworks/Subnets",
"name": "[concat(parameters('vnetConfigurationObject').name,'/',parameters('vnetConfigurationObject').subnets[copyIndex()].name)]",
"location": "[parameters('vnetConfigurationObject').location]",
"apiVersion": "2018-08-01",
"copy": {
"name": "vnet",
"count": "[length(parameters('vnetConfigurationObject').subnets)]",
"mode": "serial"
},
"properties": {
"addressPrefix": "[parameters('vnetConfigurationObject').subnets[copyIndex()].addressPrefix]",
"routeTable": "[if(empty('routeTableConfigurationObject'), json('null'), variables('route')[copyIndex()])]"
}
}
]
I dont have time\ability to test it, but it should be pretty close

How to ARM Template Azure SQL Failover Group?

How can I create a Azure SQL Failover Group in a different deployment to the servers?
We use deployments within deployments to achieve concurrent deployments.
I'm trying to create 2 SQL Servers, one in UK West (primary) and one in UK South (secondary), and then create a Failover group from the Primary to Secondary.
The issue is that when creating the Failover group, I have to reference the primary server to create the FOG under. This is failing and saying that the SQL Server is not defined.
Deployment template validation failed: 'The resource 'Microsoft.Sql/servers/xxxxxx' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'
Is it possible to keep the deployments separate, yet still create the FOG which references the SQL Servers? All examples I can find are using a single template/deployment which makes matters slightly more straightforward.
maindeployment.json
{
"apiVersion": "2018-05-01",
"name": "sqlServerTemplate",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[replace(variables('templateLinkUri'), '*', 'sql-server')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"name": {
"value": "[variables('sqlServerName')]"
},
"location": {
"value": "[parameters('location')]"
},
"adminUsername": {
"value": "[variables('sqlServerAdminUsername')]"
},
"adminPassword": {
"value": "[variables('sqlServerAdminPassword')]"
}
}
}
},
{
"apiVersion": "2018-05-01",
"name": "dbTemplate",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[replace(variables('templateLinkUri'), '*', 'sql-database')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"dbName": {
"value": "[variables('dbName')]"
},
"sqlServerName": {
"value": "[variables('sqlServerName')]"
},
"location": {
"value": "[parameters('location')]"
},
"skuName": {
"value": "[parameters('dbSkuName')]"
},
"dbCapacity": {
"value": "[parameters('dbCapacity')]"
}
}
},
"dependsOn": [
"sqlServerTemplate"
]
},
{
"apiVersion": "2018-05-01",
"name": "failoverSqlServerTemplate",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[replace(variables('templateLinkUri'), '*', 'sql-server-failover')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"name": {
"value": "[variables('failoverSqlServerName')]"
},
"location": {
"value": "[parameters('failoverLocation')]"
},
"adminUsername": {
"value": "[variables('sqlServerAdminUsername')]"
},
"adminPassword": {
"value": "[variables('sqlServerAdminPassword')]"
}
}
}
},
{
"apiVersion": "2018-05-01",
"name": "sqlFailoverGroupTemplate",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[replace(variables('templateLinkUri'), '*', 'sql-failovergroup')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"failoverGroupName": {
"value": "[variables('failoverGroupName')]"
},
"sourceSqlServerName": {
"value": "[reference('sqlServerTemplate').parameters.name.value]"
},
"targetSqlServerName": {
"value": "[reference('failoverSqlServerTemplate').parameters.name.value]"
},
"sqlDatabaseNameToReplicate": {
"value": "[reference('dbTemplate').parameters.dbName.value]"
}
}
}
}
sql-failovergroup.json
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"failoverGroupName": {
"type": "string"
},
"sourceSqlServerName": {
"type": "string"
},
"targetSqlServerName": {
"type": "string"
},
"sqlDatabaseNameToReplicate": {
"type": "string"
}
},
"variables": {
"TODO": "Figure out how to reference the SQL Server as the below method is failing with... Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The resource 'Microsoft.Sql/servers/xxxxx' is not defined in the template.",
"sourceServerResourceId": "[resourceId('Microsoft.Sql/servers', parameters('sourceSqlServerName'))]",
"targetServerResourceId": "[resourceId('Microsoft.Sql/servers', parameters('targetSqlServerName'))]",
"databaseResourceId": "[concat(resourceGroup().id, '/providers/Microsoft.Sql/servers/', parameters('sourceSqlServerName'), '/databases/', parameters('sqlDatabaseNameToReplicate'))]"
},
"resources": [
{
"name": "[concat(parameters('sourceSqlServerName'), '/', parameters('failoverGroupName'))]",
"type": "Microsoft.Sql/servers/failoverGroups",
"apiVersion": "2015-05-01-preview",
"properties": {
"readWriteEndpoint": {
"failoverPolicy": "Manual",
"failoverWithDataLossGracePeriodMinutes": 60
},
"readOnlyEndpoint": {
"failoverPolicy": "Disabled"
},
"partnerServers": [
{
"id": "[variables('targetServerResourceId')]"
}
],
"databases": [
"[variables('databaseResourceId')]"
]
},
"dependsOn": [
"[variables('sourceServerResourceId')]",
"[variables('targetServerResourceId')]"
]
}
]
}
sql-server.json
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"adminUsername": {
"type": "string"
},
"adminPassword": {
"type": "string"
},
"whitelistStartIpAddress": {
"type": "string"
},
"whitelistEndIpAddress": {
"type": "string"
}
},
"variables": {
"azureStartIpAddress": "0.0.0.0",
"azureEndIpAddress": "0.0.0.0"
},
"resources": [{
"name": "[parameters('name')]",
"type": "Microsoft.Sql/servers",
"apiVersion": "2014-01-01",
"location": "[parameters('location')]",
"properties": {
"administratorLogin": "[parameters('adminUsername')]",
"administratorLoginPassword": "[parameters('adminPassword')]"
}
},
{
"name": "[concat(parameters('name'), '/WindowsAzureIps')]",
"type": "Microsoft.Sql/servers/firewallRules",
"apiVersion": "2014-04-01",
"properties": {
"startIpAddress": "[variables('azureStartIpAddress')]",
"endIpAddress": "[variables('azureEndIpAddress')]"
},
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('name'))]"
]
}
]
}
Just came across this same problem, and found the answer on this example:
https://github.com/Azure/azure-quickstart-templates/blob/master/101-sql-with-failover-group/azuredeploy.json
The bit you're missing is:
"serverName": "[parameters('sourceSqlServerName')]",
So your full resource:
{
"name": "[concat(parameters('sourceSqlServerName'), '/', parameters('failoverGroupName'))]",
"type": "Microsoft.Sql/servers/failoverGroups",
"apiVersion": "2015-05-01-preview",
"properties": {
"readWriteEndpoint": {
"failoverPolicy": "Manual",
"failoverWithDataLossGracePeriodMinutes": 60
},
"readOnlyEndpoint": {
"failoverPolicy": "Disabled"
},
"serverName": "[parameters('sourceSqlServerName')]",
"partnerServers": [
{
"id": "[variables('targetServerResourceId')]"
}
],
"databases": [
"[variables('databaseResourceId')]"
]
},
"dependsOn": [
"[variables('sourceServerResourceId')]",
"[variables('targetServerResourceId')]"
]
}

Resources