Related
I am creating a logic app using an ARM template and inside the ARM template, I am creating a Private Endpoint for the storage account, and this private endpoint I want to attach to the Logic App.
The private endpoint is getting created but not getting attached. I have searched but I didn't get any results or demo on the same.
Is there any way I can attach the existing private endpoint to my logic app using the ARM template, Via portal I am able to attach it but I want to use the ARM template to do so?
Below is the JSON template:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"logicAppFEname": {
"type": "String"
},
"use32BitWorkerProcess": {
"type": "Bool"
},
"location": {
"defaultValue": "[resourceGroup().location]",
"type": "String",
"metadata": {
"description": "Location to deploy resources to."
}
},
"subnetNameForPrivateEndpoint": {
"type": "string"
},
"hostingPlanFEName": {
"type": "String"
},
"contentStorageAccountName": {
"type": "String"
},
"sku": {
"type": "String"
},
"skuCode": {
"type": "String"
},
"workerSize": {
"type": "String"
},
"workerSizeId": {
"type": "String"
},
"numberOfWorkers": {
"type": "String"
},
"vnetName": {
"defaultValue": "VirtualNetwork",
"type": "String",
"metadata": {
"description": "Name of the VNET that the Function App and Storage account will communicate over."
}
},
"subnetName": {
"type": "String"
}
},
"variables": {
"privateEndpointFileStorageName": "[concat(parameters('contentStorageAccountName'), '-fileshare-pe')]",
"fileShareName": "[concat(toLower(parameters('logicAppFEname')), 'b86e')]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[parameters('contentStorageAccountName')]",
"location": "[parameters('Location')]",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"defaultAction": "Deny"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
}
}
},
{
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
"apiVersion": "2021-04-01",
"name": "[concat(parameters('contentStorageAccountName'), '/default/', toLower(variables('fileShareName')))]",
"dependsOn": [
"[parameters('contentStorageAccountName')]"
]
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-06-01",
"name": "[variables('privateEndpointFileStorageName')]",
"location": "[parameters('Location')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/fileServices/shares', parameters('contentStorageAccountName'), 'default',toLower(variables('fileShareName')))]"
],
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetNameForPrivateEndpoint'))]"
},
"privateLinkServiceConnections": [
{
"name": "MyStorageQueuePrivateLinkConnection",
"properties": {
"privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('contentStorageAccountName'))]",
"groupIds": [
"file"
]
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetNameForPrivateEndpoint') )]"
}
}
},
{
"type": "Microsoft.Insights/components",
"apiVersion": "2020-02-02",
"name": "[parameters('logicAppFEname')]",
"location": "[parameters('Location')]",
"kind": "web",
"properties": {
"Application_Type": "web"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[parameters('logicAppFEname')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanFEName'))]"
],
"tags": {},
"kind": "functionapp,workflowapp",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "[parameters('logicAppFEname')]",
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', parameters('logicAppFEname')), '2015-05-01').InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[reference(resourceId('Microsoft.Insights/components', parameters('logicAppFEname')), '2015-05-01').ConnectionString]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('contentStorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('contentStorageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('contentStorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('contentStorageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('fileShareName'))]"
},
{
"name": "APP_KIND",
"value": "workflowApp"
},
{
"name": "WEBSITE_VNET_ROUTE_ALL",
"value": "1"
},
{
"name": "AzureFunctionsJobHost__extensionBundle__id",
"value": "Microsoft.Azure.Functions.ExtensionBundle.Workflows",
"slotSetting": false
},
{
"name": "AzureFunctionsJobHost__extensionBundle__version",
"value": "[1.*, 2.0.0)",
"slotSetting": false
},
{
"name": "WEBSITE_CONTENTOVERVNET",
"value": "1",
"slotSetting": false
}
],
"use32BitWorkerProcess": "[parameters('use32BitWorkerProcess')]",
"cors": {
"allowedOrigins": [
"https://afd.hosting.portal.azure.net",
"https://afd.hosting-ms.portal.azure.net",
"https://hosting.portal.azure.net",
"https://ms.hosting.portal.azure.net",
"https://ema-ms.hosting.portal.azure.net",
"https://ema.hosting.portal.azure.net",
"https://ema.hosting.portal.azure.net"
]
}
},
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms/', parameters('hostingPlanFEName'))]",
"clientAffinityEnabled": true
},
"resources": [
{
"type": "networkconfig",
"apiVersion": "2018-11-01",
"name": "virtualNetwork",
"location": "[parameters('location')]",
"dependsOn": [
"[parameters('logicAppFEname')]"
],
"properties": {
"subnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets',parameters('vnetName'), parameters('subnetName'))]",
"swiftSupported": true
}
}
]
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-11-01",
"name": "[parameters('hostingPlanFEName')]",
"location": "[parameters('location')]",
"dependsOn": [],
"tags": {},
"sku": {
"Tier": "[parameters('sku')]",
"Name": "[parameters('skuCode')]"
},
"kind": "",
"properties": {
"name": "[parameters('hostingPlanFEName')]",
"workerSize": "[parameters('workerSize')]",
"workerSizeId": "[parameters('workerSizeId')]",
"numberOfWorkers": "[parameters('numberOfWorkers')]",
"maximumElasticWorkerCount": "20"
}
}
]
}
Your ARM template shows few errors, I recommend using Visual Studio Code with ARM Template extension which will help you validate it.
Back to your problem, I suspect you attempt to achieve this
[
At the original Source an ARM template valid is present. Let me know if it solves your issue.
Background
I am trying to create an AD app registration for my function app to use for authentication.
I would like it to be for just our tenant, using Azure AD. The app is function app made up of a few endpoints
When I deploy the ARM template below, I don't get any errors, but in poking around and comparing it with what happens when I create authentication manually for my app, i see the following problems:
the application registration is created but there's no Application ID URI specified. When I create this manually via the portal I believe it's auto filled with a value "api://[applicationClientId]"
there are no scopes defined. again, when i create an authentication policy for my app manually via the portal, it does create a user_impersonation scope for me.
When i open up the function app in the portal, under "authentication" this new app registration hasn't been associated with it / or added.
Code
Here's what the ARM template looks like:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"functionAppName": {
"type": "string",
"defaultValue": "[concat('widgets-', uniqueString(resourceGroup().id),'-app')]",
"minLength": 2,
"metadata": {
"description": "my function app"
}
},
"storageAccountName": {
"type": "string",
"defaultValue": "[concat('widgets', uniqueString(resourceGroup().id))]",
"minLength": 2,
"metadata": {
"description": "StorageAccount"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"serviceBusNamespaceName": {
"type": "string",
"defaultValue": "[concat('widgets-', uniqueString(resourceGroup().id),'-bus')]",
"metadata": {
"description": "Name of the Service Bus namespace"
}
},
"serviceBusQueueName": {
"type": "string",
"defaultValue": "workspaces",
"metadata": {
"description": "Name of the Queue"
}
},
"queueAuthorizationRuleName": {
"type": "string",
"defaultValue": "myRule",
"metadata": {
"description": "Name of the Queue AuthorizationRule"
}
},
"aadAppClientId": {
"type": "string"
},
"tenant": {
"type": "string"
}
},
"variables": {
"appServicePlanPortalName": "[concat(parameters('functionAppName'),'servicePlan')]",
"appInsightsName": "[concat(parameters('functionAppName'),'-insights')]",
"identityName": "[concat(parameters('functionAppName'),'-userId')]",
"clientSecret": ""
},
"resources": [
{
"name": "[variables('identityName')]",
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"apiVersion": "2018-11-30",
"location": "[parameters('location')]"
},
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageAccountName')]",
"apiVersion": "2019-06-01",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
}
},
{
"type": "Microsoft.Storage/storageAccounts/queueServices",
"apiVersion": "2020-08-01-preview",
"name": "[concat(parameters('storageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
"properties": {
"cors": {
"corsRules": []
}
}
},
{
"type": "Microsoft.Storage/storageAccounts/queueServices/queues",
"apiVersion": "2020-08-01-preview",
"name": "[concat(parameters('storageAccountName'), '/default/workspaces')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/queueServices', parameters('storageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
"properties": {
"metadata": {}
}
},
{
"type": "Microsoft.Storage/storageAccounts/tableServices/tables",
"apiVersion": "2021-06-01",
"name": "[concat(parameters('storageAccountName'), '/default/provisionedWorkspaces')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
"properties": {
"partitionName": "workspaces"
}
},
{
"type": "Microsoft.ServiceBus/namespaces",
"apiVersion": "2017-04-01",
"name": "[parameters('serviceBusNamespaceName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {}
},
{
"type": "Microsoft.ServiceBus/namespaces/queues",
"apiVersion": "2017-04-01",
"name": "[format('{0}/{1}', parameters('serviceBusNamespaceName'), parameters('serviceBusQueueName'))]",
"properties": {
"lockDuration": "PT5M",
"maxSizeInMegabytes": 1024,
"requiresDuplicateDetection": false,
"requiresSession": false,
"defaultMessageTimeToLive": "P10675199DT2H48M5.4775807S",
"deadLetteringOnMessageExpiration": false,
"duplicateDetectionHistoryTimeWindow": "PT10M",
"maxDeliveryCount": 10,
"autoDeleteOnIdle": "P10675199DT2H48M5.4775807S",
"enablePartitioning": false,
"enableExpress": false
},
"resources": [
{
"apiVersion": "2017-04-01",
"name": "[parameters('queueAuthorizationRuleName')]",
"type": "AuthorizationRules",
"dependsOn": ["[parameters('serviceBusQueueName')]"],
"properties": {
"rights": ["Listen", "Send", "Manage"]
}
}
],
"dependsOn": [
"[resourceId('Microsoft.ServiceBus/namespaces', parameters('serviceBusNamespaceName'))]"
]
},
{
"apiVersion": "2015-05-01",
"name": "[variables('appInsightsName')]",
"type": "Microsoft.Insights/components",
"kind": "web",
"location": "[parameters('location')]",
"tags": {
"[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', parameters('functionAppName'))]": "Resource"
},
"properties": {
"Application_Type": "web",
"ApplicationId": "[variables('appInsightsName')]"
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2020-06-01",
"name": "[variables('appServicePlanPortalName')]",
"location": "[parameters('location')]",
"sku": {
"tier": "Standard",
"name": "S1"
},
"kind": "functionapp,linux",
"properties": {
"name": "[variables('appServicePlanPortalName')]",
"reserved": true
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2020-06-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp,linux",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]": {}
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]"
],
"properties": {
"reserved": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
"siteConfig": {
"linuxFxVersion": "DOTNETCORE|6.0",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', variables('appInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
}
],
"resources": [
{
"type": "config",
"apiVersion": "2020-12-01",
"name": "authsettingsV2",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('functionAppName'))]"
],
"properties": {
"platform": {
"enabled": true,
"runtimeVersion": "~1"
},
"identityProviders": {
"azureActiveDirectory": {
"isAutoProvisioned": false,
"registration": {
"clientId": "[parameters('aadAppClientId')]",
"clientSecret": "[variables('clientSecret')]",
"openIdIssuer": "[concat('https://sts.windows.net/', parameters('tenant'), '/v2.0')]"
},
"validation": {
"allowedAudiences": [
"https://management.core.windows.net/"
]
}
}
}
},
"login": {
"routes": {},
"tokenStore": {
"enabled": true,
"tokenRefreshExtensionHours": 72,
"fileSystem": {},
"azureBlobStorage": {}
},
"preserveUrlFragmentsForLogins": false,
"allowedExternalRedirectUrls": [],
"cookieExpiration": {
"convention": "FixedTime",
"timeToExpiration": "08:00:00"
},
"nonce": {
"validateNonce": true,
"nonceExpirationInterval": "00:05:00"
}
},
"globalValidation": {
"redirectToProvider": "azureactivedirectory",
"unauthenticatedClientAction": "RedirectToLoginPage"
},
"httpSettings": {
"requireHttps": true,
"routes": {
"apiPrefix": "/.auth"
},
"forwardProxy": {
"convention": "NoProxy"
}
}
}
]
}
}
}
]
}
Two comments in case they help / are relevant:
client secret - As you can see I have a variable defined, but its blank. I'm not supplying a client secret value because I was assuming it would auto create for me. But maybe I shouldn't include that parameter at all?
Also, I'm using a linux container for the web app.
Any tips on how to fix these issues would be appreciated.
EDIT 1
I manually created and added an authencation policy and then I've been using resources.azure.com to see what's been created for me. I have two relevant sections under config.
One is called authsettings and looks like this:
And the other is under authsettingsV2 and looks like this:
I'm trying to use the authsettingsV2 for now... but it's not clear where I should paste it into in the ARM template.
Any suggestions?
EDIT 2
Added all the authsettingsv2 stuff under the site resource. No errors. but still the same results.
Found out that I can use the Az Powershell commandlets:
New-AzADApplication
New-AzADAppCredential
I have an ARM template that creates Event Hub namespaces in two regions (eastus and westus2) with a event hub and multiple auth rules (on the even hub). This was working until ~16-Nov-2020 12:00PM.
Arm template:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location-region1": {
"type": "string",
"defaultValue": "eastus",
"metadata": {
"description": "Name of an azure region"
}
},
"location-region2": {
"type": "string",
"defaultValue": "westus2",
"metadata": {
"description": "Name of an Azure region"
}
},
"appName": {
"type": "string",
"defaultValue": "jklm",
"metadata": {
"description": "Short name of the app or service"
}
},
"uniqueSuffix": {
"type": "string",
"defaultValue": "tst",
"metadata": {
"description": "Unique Suffix to use for the azure resources of the app or service"
}
},
"environment": {
"type": "string",
"defaultValue": "int",
"allowedValues": [
"poc",
"dev",
"int",
"uat",
"prod"
],
"metadata": {
"description": "The name of the environment"
}
},
"progressRecordsEventHubName": {
"type": "string",
"defaultValue": "progressrecords"
}
},
"variables": {
"eventHubNMApiVersion": "2018-01-01-preview",
"eventHubApiVersion": "2017-04-01",
"parentResourceGroupName": "[resourceGroup().name]",
"regionCount": 2,
"location": [
"[parameters('location-region1')]",
"[parameters('location-region2')]"
],
"appName": "[concat(parameters('appName'),'-',parameters('uniqueSuffix'),'-')]",
"copy": [
{
"name": "regionSuffix",
"count": "[variables('regionCount')]",
"input": "[concat('r',copyIndex('regionSuffix',1))]"
},
{
"name": "eventHubName",
"count": "[variables('regionCount')]",
"input": "[concat(variables('appName'),'ehub-',variables('regionSuffix')[copyIndex('eventHubName')],'-',parameters('environment'))]"
}
]
},
"resources": [
{
"type": "Microsoft.EventHub/namespaces",
"apiVersion": "[variables('eventHubNMApiVersion')]",
"name": "[variables('eventHubName')[copyIndex()]]",
"copy": {
"name": "resourceLoop",
"count": "[variables('regionCount')]"
},
"location": "[variables('location')[copyIndex()]]",
"sku": {
"name": "Standard",
"tier": "Standard",
"capacity": 1
},
"properties": {
"zoneRedundant": false,
"isAutoInflateEnabled": true,
"maximumThroughputUnits": 1,
"kafkaEnabled": true
},
"resources": [
{
"type": "Microsoft.EventHub/namespaces/eventhubs",
"apiVersion": "[variables('eventHubApiVersion')]",
"name": "[concat(variables('eventHubName')[copyIndex()], '/',parameters('progressRecordsEventHubName'))]",
"location": "[variables('location')[copyIndex()]]",
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces', variables('eventHubName')[copyIndex()])]"
],
"properties": {
"messageRetentionInDays": 3,
"partitionCount": 1,
"status": "Active"
},
"resources": [
{
"type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules",
"apiVersion": "[variables('eventHubApiVersion')]",
"name": "[concat(variables('eventHubName')[copyIndex('resourceLoop')], '/',parameters('progressRecordsEventHubName'),'/Listen')]",
"location": "[variables('location')[copyIndex()]]",
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces/eventhubs', variables('eventHubName')[copyIndex()],parameters('progressRecordsEventHubName'))]"
],
"properties": {
"rights": [
"Listen"
]
}
},
{
"type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules",
"apiVersion": "[variables('eventHubApiVersion')]",
"name": "[concat(variables('eventHubName')[copyIndex('resourceLoop')], '/',parameters('progressRecordsEventHubName'),'/Send')]",
"location": "[variables('location')[copyIndex()]]",
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces/eventhubs', variables('eventHubName')[copyIndex()], parameters('progressRecordsEventHubName'))]"
],
"properties": {
"rights": [
"Send"
]
}
}
]
}
]
}
],
"functions": [
],
"outputs": {}
}
Now this template fails when I run Test-AzureRmResourceGroupDeployment (add -Debug to see real error)
Error:
Test-AzureRmResourceGroupDeployment : Encountered internal server error. Diagnostic information: timestamp '20201119T072227Z' ......
After some troubleshooting I identified that removing the second auth rule in the template fixes the issue.
I actually need more than 1 auth rule. What could be causing the above template to fail? I can't seem to find anything wrong with it.
Below you can find successful template - With 1 auth rule on the Event Hub
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location-region1": {
"type": "string",
"defaultValue": "eastus"
},
"location-region2": {
"type": "string",
"defaultValue": "westus2"
},
"appName": {
"type": "string",
"defaultValue": "jklm",
"metadata": {
"description": "Short name of the app or service"
}
},
"uniqueSuffix": {
"type": "string",
"defaultValue": "tst",
"metadata": {
"description": "Unique Suffix to use for the azure resources of the app or service"
}
},
"environment": {
"type": "string",
"defaultValue": "int",
"allowedValues": [
"poc",
"dev",
"int",
"uat",
"prod"
],
"metadata": {
"description": "The name of the environment"
}
},
"progressRecordsEventHubName": {
"type": "string",
"defaultValue": "progressrecords"
}
},
"variables": {
"eventHubNMApiVersion": "2018-01-01-preview",
"eventHubApiVersion": "2017-04-01",
"parentResourceGroupName": "[resourceGroup().name]",
"regionCount": 2,
"location": [
"[parameters('location-region1')]",
"[parameters('location-region2')]"
],
"appName": "[concat(parameters('appName'),'-',parameters('uniqueSuffix'),'-')]",
"copy": [
{
"name": "regionSuffix",
"count": "[variables('regionCount')]",
"input": "[concat('r',copyIndex('regionSuffix',1))]"
},
{
"name": "eventHubName",
"count": "[variables('regionCount')]",
"input": "[concat(variables('appName'),'ehub-',variables('regionSuffix')[copyIndex('eventHubName')],'-',parameters('environment'))]"
}
]
},
"resources": [
{
"type": "Microsoft.EventHub/namespaces",
"apiVersion": "[variables('eventHubNMApiVersion')]",
"name": "[variables('eventHubName')[copyIndex()]]",
"copy": {
"name": "resourceLoop",
"count": "[variables('regionCount')]"
},
"location": "[variables('location')[copyIndex()]]",
"sku": {
"name": "Standard",
"tier": "Standard",
"capacity": 1
},
"properties": {
"zoneRedundant": false,
"isAutoInflateEnabled": true,
"maximumThroughputUnits": 1,
"kafkaEnabled": true
},
"resources": [
{
"type": "Microsoft.EventHub/namespaces/eventhubs",
"apiVersion": "[variables('eventHubApiVersion')]",
"name": "[concat(variables('eventHubName')[copyIndex()], '/',parameters('progressRecordsEventHubName'))]",
"location": "[variables('location')[copyIndex()]]",
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces', variables('eventHubName')[copyIndex()])]"
],
"properties": {
"messageRetentionInDays": 3,
"partitionCount": 1,
"status": "Active"
},
"resources": [
{
"type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules",
"apiVersion": "[variables('eventHubApiVersion')]",
"name": "[concat(variables('eventHubName')[copyIndex('resourceLoop')], '/',parameters('progressRecordsEventHubName'),'/Listen')]",
"location": "[variables('location')[copyIndex()]]",
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces/eventhubs', variables('eventHubName')[copyIndex()],parameters('progressRecordsEventHubName'))]"
],
"properties": {
"rights": [
"Listen"
]
}
}
]
}
]
}
],
"functions": [
],
"outputs": {}
}
Worked with Azure support on this. There was an issue on the Azure side. It auto resolved today (11/19/2020). Template no longer fails with multiple auth rules.
This article may be useful: https://www.rickvandenbosch.net/blog/error-creating-service-bus-authorization-rules-using-arm/.
I think the template is not expecting the same resource twice, because these Listen, Send authorization rules can be combined like below:
"resources": [
{
"type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules",
"apiVersion": "[variables('eventHubApiVersion')]",
"name": "[concat(variables('eventHubName')[copyIndex('resourceLoop')], '/',parameters('progressRecordsEventHubName'),'/Listen')]",
"location": "[variables('location')[copyIndex()]]",
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces/eventhubs', variables('eventHubName')[copyIndex()],parameters('progressRecordsEventHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Send"
]
}
},
I have a ARM template code to deploy the webapp and slot creating along with app with respective the environment based on the condition. When i try to deploy the resource using the template it only deploys the web app and the slot is not created using the settings on the App. I am new to the ARM stuff could any one please help me out on what i have done wrong with my template.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceGroup": {
"type": "string"
},
"displayNameTag": {
"type": "string"
},
"appInsightName": {
"type": "string"
},
"environment": {
"type": "string"
},
"appType": {
"type": "string"
},
"appServicePlanName": {
"type": "string"
},
"alwaysOn": {
"type": "bool"
},
"currentStack": {
"type": "string"
},
"netFrameworkVersion": {
"type": "string",
"defaultValue": "v4.0"
},
"secondaryApp":{
"type":"string"
}
},
"variables": {
"AustraliaEast": {
"countryCode": "au",
"regionShortCode": "aue",
"regionShortCodePair": "aue",
"omsLocation": "AustraliaEast",
"omsLocationShortCode": "aue",
"PrimaryRegion": true,
"SecondaryRegion": "AustraliaSoutheast",
"regionLocation":"AustraliaEast"
},
"AustraliaSoutheast": {
"countryCode": "au",
"regionShortCode": "aus",
"regionShortCodePair": "aue",
"PrimaryRegion": false,
"regionLocation":"AustraliaSoutheast"
},
"regionSpec": "[variables(resourceGroup().location)]",
"applicationRegion" : "[if(equals(parameters('secondaryApp'),'Yes'),variables('AustraliaSoutheast'),variables('regionspec'))]",
"appName": "[concat('myapp-',parameters('environment'),'-',parameters('appType'),'-',variables('applicationRegion').regionShortcode,'-',parameters('displayNameTag'))]"
},
"resources": [
{
"apiVersion": "2018-11-01",
"name": "[variables('appName')]",
"type": "Microsoft.Web/sites",
"location": "[variables('applicationRegion').regionLocation]",
"tags": {
"displayName": "[parameters('displayNameTag')]",
"environment": "[parameters('environment')]"
},
"dependsOn": [],
"properties": {
"name": "[variables('appName')]",
"mode": "incremental",
"siteConfig": {
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', parameters('appInsightName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[concat('InstrumentationKey=',reference(resourceId('Microsoft.Insights/components', parameters('appInsightName')), '2015-05-01').InstrumentationKey)]"
}
],
"metadata": [
{
"name": "CURRENT_STACK",
"value": "[parameters('currentStack')]"
}
],
"netFrameworkVersion": "[parameters('netFrameworkVersion')]",
"alwaysOn": "[parameters('alwaysOn')]"
},
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
"clientAffinityEnabled": true
}
},
{
"condition":"[equals(parameters('secondaryApp'),'Yes')]",
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites/slots",
"name": "[concat(variables('appName'), '/', 'Slot-Staging')]",
"location": "[variables('applicationRegion').regionLocation]",
"comments": "This specifies the web app slots.",
"tags": {
"displayName": "WebAppSlots"
},
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('appName'))]"
]
}
],
"outputs": {
"webAppName": {
"type": "string",
"value": "[variables('appName')]"
}
}
}'
Please have a try to add the json code snipped in the ARM template.
"resources": [
{
"apiVersion": "2015-08-01",
"name": "appsettings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites/Slots', variables('webSiteName'), 'Staging')]"
],
"properties": {
"AppSettingKey1": "Some staging value",
"AppSettingKey2": "My second staging setting",
"AppSettingKey3": "My third staging setting"
}
}
]
Follow this SO for complete reference.
I'm rewriting an ARM template because we no longer use Linked Templates. The Linked templates give us versioning headaches. I'm using a subscription level deployment to deploy a resource group, with nested a deletion lock, storage account, keyvault, 2 functionapps, user assigned managed identity and a keyvault access policy.
ARM Template I use:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"deplocation": {
"type": "string",
"allowedValues": [
"West Europe",
"North Europe"
],
"defaultValue": "West Europe",
"metadata": {
"description": "Location for all resources."
}
},
"tags": {
"type": "object"
},
"rgName": {
"type": "string"
},
"saName": {
"type": "string",
"metadata": {
"description": "The name of the resource."
}
},
"saType": {
"type": "string",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS"
],
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Gets or sets the SKU name. Required for account creation; optional for update. Note that in older versions, SKU name was called accountType. - Standard_LRS, Standard_GRS, Standard_RAGRS, Standard_ZRS, Premium_LRS, Premium_ZRS, Standard_GZRS, Standard_RAGZRS"
}
},
"saKind": {
"type": "string",
"allowedValues": [
"StorageV2",
"BlobStorage",
"FileStorage",
"BlockBlobStorage"
],
"defaultValue": "StorageV2",
"metadata": {
"description": "Indicates the type of storage account. - Storage, StorageV2, BlobStorage, FileStorage, BlockBlobStorage"
}
},
"saAccessTier": {
"type": "string"
},
"saSupportsHttpsTrafficOnly": {
"type": "bool"
},
"kvName": {
"type": "string"
},
"kvSkuName": {
"type": "string"
},
"kvSkuFamily": {
"type": "string"
},
"kvSecretsPermissions": {
"type": "array"
},
"uamiName": {
"type": "string"
},
"fa1Name": {
"type": "string"
},
"fa2Name": {
"type": "string"
},
"aspName": {
"type": "string"
},
"aspRg": {
"type": "string"
},
"appInsightsName": {
"type": "string"
},
"appInsightsRg": {
"type": "string"
}
},
"variables": {
"tenantId": "[subscription().tenantId]",
"subscriptionId": "[subscription().subscriptionId]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('depLocation')]",
"name": "[parameters('rgName')]",
"tags": "[parameters('tags')]",
"properties": {
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "resourceDeployment",
"resourceGroup": "[parameters('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "DeletionLock",
"type": "Microsoft.Authorization/locks",
"apiVersion": "2017-04-01",
"properties": {
"level": "CanNotDelete",
"notes": "[parameters('rgName')]"
}
},
{
"name": "[parameters('saName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"sku": {
"name": "[parameters('saType')]"
},
"kind": "[parameters('saKind')]",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"properties": {
"accessTier": "[parameters('saAccessTier')]",
"supportsHttpsTrafficOnly": "[parameters('saSupportsHttpsTrafficOnly')]"
}
},
{
"name": "[concat(parameters('saName'), '/default')]",
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-04-01",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('saName'))]"
],
"properties": {
"cors": {
"corsRules": [
]
},
"deleteRetentionPolicy": {
"enabled": false
}
}
},
{
"name": "[parameters('kvName')]",
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2018-02-14",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"properties": {
"tenantId": "[variables('tenantId')]",
"accessPolicies": [
],
"sku": {
"name": "[parameters('kvSkuName')]",
"family": "[parameters('kvSkuFamily')]"
}
}
},
{
"name": "[parameters('uamiName')]",
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"apiVersion": "2018-11-30",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"properties": {
}
},
{
"name": "[parameters('fa1Name')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"kind": "functionapp",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"dependsOn": [
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('uamiName'))]",
"[resourceId('Microsoft.Storage/storageAccounts/', parameters('saName'))]"
],
"identity": {
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"[concat('/subscriptions/', variables('subscriptionId'), '/resourceGroups/', parameters('rgName'), '/providers/Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('uamiName'))]": {
}
}
},
"properties": {
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
},
{
"name": "WEBSITE_TIME_ZONE",
"value": "W. Europe Standard Time"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('saName'),';AccountKey=',listKeys(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value,';')]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "1"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('appInsightsRg'),'/providers/microsoft.insights/components/',parameters('appInsightsName')),providers('microsoft.insights', 'components').apiVersions[0]).InstrumentationKey]"
}
],
"alwaysOn": true
},
"serverFarmId": "[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('aspRg'),'/providers/Microsoft.Web/serverfarms/',parameters('aspName'))]",
"httpsOnly": true
}
},
{
"name": "[parameters('fa2Name')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"kind": "functionapp",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"dependsOn": [
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]",
"[resourceId('Microsoft.Storage/storageAccounts/', parameters('saName'))]"
],
"identity": {
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]": {
}
}
},
"properties": {
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
},
{
"name": "WEBSITE_TIME_ZONE",
"value": "W. Europe Standard Time"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('saName'),';AccountKey=',listKeys(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value,';')]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "1"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('appInsightsRg'),'/providers/microsoft.insights/components/',parameters('appInsightsName')),providers('microsoft.insights', 'components').apiVersions[0]).InstrumentationKey]"
}
],
"alwaysOn": true
},
"serverFarmId": "[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('aspRg'),'/providers/Microsoft.Web/serverfarms/',parameters('aspName'))]",
"httpsOnly": true
}
},
{
"name": "[concat(parameters('kvName'), '/add')]",
"type": "Microsoft.KeyVault/vaults/accessPolicies",
"apiVersion": "2018-02-14",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', parameters('kvName'))]",
"[resourceId('Microsoft.Web/sites', parameters('fa1Name'))]",
"[resourceId('Microsoft.Web/sites', parameters('fa2Name'))]"
],
"properties": {
"accessPolicies": [
{
"tenantId": "[variables('tenantId')]",
"objectId": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Web/sites/', parameters('fa1Name'), '/providers/Microsoft.ManagedIdentity/Identities/default'),providers('Microsoft.ManagedIdentity', 'Identities').apiVersions[0]).principalId]",
"permissions": {
"secrets": "[parameters('kvSecretsPermissions')]"
}
}
,
{
"tenantId": "[variables('tenantId')]",
"objectId": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Web/sites/', parameters('fa2Name'), '/providers/Microsoft.ManagedIdentity/Identities/default'),providers('Microsoft.ManagedIdentity', 'Identities').apiVersions[0]).principalId]",
"permissions": {
"secrets": "[parameters('kvSecretsPermissions')]"
}
}
]
}
}
]
}
}
}
],
"outputs": {
// "uamiPrincipalId": {
// "value": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('uamiName')), providers('Microsoft.ManagedIdentity', 'userAssignedIdentities').apiVersions[0]).principalId]",
// "type": "string"
// }
}
}
Powershell code to deploy the template.
#region variableDeclaration
$ErrorActionPreference = "Stop"
$subscriptionId = "subscription id here"
$location = "West Europe"
#endregion variableDeclaration
Set-location -path $PSScriptRoot
#region connectToSubscription
Connect-AzAccount -ErrorAction Stop
Set-AzContext -Subscription $subscriptionId
#endregion connectToSubscription
#region createAzureResources
$workloadInputResources = #{
depLocation = $location
tags = #{
dienst = "-"
kostenplaats = "-"
omgeving = "-"
contactpersoon = "-"
eigenaar = "-"
referentie = "-"
omschrijving = "-"
}
rgName = "resources-dev-rg"
saName = "resourcesdevsa"
saType = "Standard_LRS"
saKind = "StorageV2"
saAccessTier = "Hot"
saSupportsHttpsTrafficOnly = $true
kvName = "resourcesdevkv"
kvSkuName = "Standard"
kvSkuFamily = "A"
kvSecretsPermissions = #("get", "list" )
uamiName = "resources-dev-uami"
fa1Name = "resources-dev-fa1"
fa2Name = "resources-dev-fa2"
aspName = "resources-dev-asp"
aspRg = "resources-asp-dev-rg"
appInsightsName = "resources-dev-appins"
appInsightsRg = "resources-appins-dev-rg"
}
New-AzDeployment -Name "deployResources" -Location $location -TemplateFile .\deploy.json #workloadInputResources
#endregion createAzureResources
Problems:
When deploying the arm template as-is I get the following error:
Resource Microsoft.Storage/storageAccounts 'resourcesdevsa' failed with message '{
"error": {
"code": "ResourceGroupNotFound",
"message": "Resource group 'resources-dev-rg' could not be found."
}
}'
But the creation of the resource group is successful.
When rerunning the script I get the following error:
Resource Microsoft.Storage/storageAccounts 'resourcesdevsa' failed with message '{
"error": {
"code": "ResourceNotFound",
"message": "The Resource 'Microsoft.Storage/storageAccounts/saName' under resource group 'resources-dev-rg' was not found."
}
}'
The second problem disappears when I comment out the deployment fa1, fa2 and the access policy
I was under the impression that using dependsOn solves the dependency issues but apparently I'm either wrong, using it incorrectly or missing a dependsOn somewhere.
Have been staring at this problem for hours now and I can't seem to find the problem.
Any help is appreciated.
Small update because parts of it are solved. Still a couple of issues though.
I have rewritten the ARM Template file as shown below
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"deplocation": {
"type": "string",
"allowedValues": [
"West Europe",
"North Europe"
],
"defaultValue": "West Europe",
"metadata": {
"description": "Location for all resources."
}
},
"tags": {
"type": "object"
},
"rgName": {
"type": "string"
},
"saName": {
"type": "string",
"metadata": {
"description": "The name of the resource."
}
},
"saType": {
"type": "string",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS"
],
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Gets or sets the SKU name. Required for account creation; optional for update. Note that in older versions, SKU name was called accountType. - Standard_LRS, Standard_GRS, Standard_RAGRS, Standard_ZRS, Premium_LRS, Premium_ZRS, Standard_GZRS, Standard_RAGZRS"
}
},
"saKind": {
"type": "string",
"allowedValues": [
"StorageV2",
"BlobStorage",
"FileStorage",
"BlockBlobStorage"
],
"defaultValue": "StorageV2",
"metadata": {
"description": "Indicates the type of storage account. - Storage, StorageV2, BlobStorage, FileStorage, BlockBlobStorage"
}
},
"saAccessTier": {
"type": "string"
},
"saSupportsHttpsTrafficOnly": {
"type": "bool"
},
"kvName": {
"type": "string"
},
"kvSkuName": {
"type": "string"
},
"kvSkuFamily": {
"type": "string"
},
"kvSecretsPermissions": {
"type": "array"
},
"uamiName": {
"type": "string"
},
"fa1Name": {
"type": "string"
},
"fa2Name": {
"type": "string"
},
"aspName": {
"type": "string"
},
"aspRg": {
"type": "string"
},
"appInsightsName": {
"type": "string"
},
"appInsightsRg": {
"type": "string"
}
},
"variables": {
"tenantId": "[subscription().tenantId]",
"subscriptionId": "[subscription().subscriptionId]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "[parameters('depLocation')]",
"name": "[parameters('rgName')]",
"tags": "[parameters('tags')]",
"properties": {
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "resourceDeployment",
"resourceGroup": "[parameters('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "DeletionLock",
"type": "Microsoft.Authorization/locks",
"apiVersion": "2017-04-01",
"properties": {
"level": "CanNotDelete",
"notes": "[parameters('rgName')]"
}
},
{
"name": "[parameters('saName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"sku": {
"name": "[parameters('saType')]"
},
"kind": "[parameters('saKind')]",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"properties": {
"accessTier": "[parameters('saAccessTier')]",
"supportsHttpsTrafficOnly": "[parameters('saSupportsHttpsTrafficOnly')]"
},
"resources": [
]
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-04-01",
"name": "[concat(parameters('saName'), '/default')]",
"dependsOn": [
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName'))]"
],
"properties": {
"cors": {
"corsRules": [
]
},
"deleteRetentionPolicy": {
"enabled": false
}
}
},
{
"name": "[parameters('uamiName')]",
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"apiVersion": "2018-11-30",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"properties": {
}
},
{
"name": "[parameters('fa1Name')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"kind": "functionapp",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"dependsOn": [
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]",
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName'))]"
],
"identity": {
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]": {
}
}
},
"properties": {
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
},
{
"name": "WEBSITE_TIME_ZONE",
"value": "W. Europe Standard Time"
},
// {
// "name": "AzureWebJobsStorage",
// "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('saName'),';AccountKey=',listKeys(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value,';')]"
// },
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "0"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('appInsightsRg'),'/providers/microsoft.insights/components/',parameters('appInsightsName')),providers('microsoft.insights', 'components').apiVersions[0]).InstrumentationKey]"
}
],
"alwaysOn": true
},
"serverFarmId": "[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('aspRg'),'/providers/Microsoft.Web/serverfarms/',parameters('aspName'))]",
"httpsOnly": true
}
},
{
"name": "[parameters('fa2Name')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"kind": "functionapp",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"dependsOn": [
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]",
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName'))]"
],
"identity": {
"type": "SystemAssigned, UserAssigned",
"userAssignedIdentities": {
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]": {
}
}
},
"properties": {
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
},
{
"name": "WEBSITE_TIME_ZONE",
"value": "W. Europe Standard Time"
},
// {
// "name": "AzureWebJobsStorage",
// "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('saName'),';AccountKey=',listKeys(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value,';')]"
// },
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "0"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('appInsightsRg'),'/providers/microsoft.insights/components/',parameters('appInsightsName')),providers('microsoft.insights', 'components').apiVersions[0]).InstrumentationKey]"
}
],
"alwaysOn": true
},
"serverFarmId": "[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('aspRg'),'/providers/Microsoft.Web/serverfarms/',parameters('aspName'))]",
"httpsOnly": true
}
},
{
"name": "[parameters('kvName')]",
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2018-02-14",
"location": "[parameters('deplocation')]",
"tags": "[parameters('tags')]",
"dependsOn": [
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Web/sites/',parameters('fa1Name'))]",
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Web/sites/',parameters('fa2Name'))]"
],
"properties": {
"tenantId": "[variables('tenantId')]",
"accessPolicies": [
// {
// "tenantId": "[variables('tenantId')]",
// "objectId": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Web/sites/', parameters('fa1Name'), '/providers/Microsoft.ManagedIdentity/Identities/default'),providers('Microsoft.ManagedIdentity', 'Identities').apiVersions[0]).principalId]",
// "permissions": {
// "secrets": "[parameters('kvSecretsPermissions')]"
// }
// },
// {
// "tenantId": "[variables('tenantId')]",
// "objectId": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Web/sites/', parameters('fa2Name'), '/providers/Microsoft.ManagedIdentity/Identities/default'),providers('Microsoft.ManagedIdentity', 'Identities').apiVersions[0]).principalId]",
// "permissions": {
// "secrets": "[parameters('kvSecretsPermissions')]"
// }
// }
],
"sku": {
"name": "[parameters('kvSkuName')]",
"family": "[parameters('kvSkuFamily')]"
}
}
}
]
}
}
}
],
"outputs": {
// "uamiPrincipalId": {
// "value": "[reference(concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('uamiName')), providers('Microsoft.ManagedIdentity', 'userAssignedIdentities').apiVersions[0]).principalId]",
// "type": "string"
// }
}
}
This work flawlessly very time, but as you can see I have 3 sections commented out. This is the problem area now. They are all dependsOn issues. When I uncomment the AzureWebJobsStorage part in the function app deployments the deployment fails with this message:
12:00:18 - Resource Microsoft.Storage/storageAccounts 'resourcesdevsa' failed with message '{
"error": {
"code": "ResourceGroupNotFound",
"message": "Resource group 'resources-dev-rg' could not be found."
}
}'
I have added the StorageAccount to the dependsOn section
"dependsOn": [
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('uamiName'))]",
"[concat('/subscriptions/',variables('subscriptionId'),'/resourceGroups/',parameters('rgName'),'/providers/Microsoft.Storage/storageAccounts/',parameters('saName'))]"
],
But that doesn't seem to do the trick.
Any ideas?
Update 28/11/2019
Oke. I'm getting slightly frustrated. I now have a fully functional resourcegroup level deployment. I'm creating the resourcegroup and resourcegroup deletionlock in powershell and after that a New-AzResourceGroupDeployment. When I try to rewrite this into a subscription level deployment I keep getting dependency issues. For instance; creating the KeyVault Access Policies results in an error that the function app couldn't be found. And a similar error for setting the AzureWebJobsStorage setting for the function app. But than offcourse a reference to the storageaccount.