ARM template for Appservice integrating with existing VNET Subnets - azure

i have an ARM template that creates a new App Service in an existing AppPlan and a new KeyVault that allows access to the App Service's Identity. I would also like to add an existing VNET/Subnet to the App Service but I am not having any luck. My script runs but the VNET/Subnet does not get tied to the App Service. Thanks for any help.
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"subscriptionId": {
"type": "string"
},
"name": {
"type": "string"
},
"keyVaultUserObjectId": {
"type": "string",
"defaultValue": "XXXXXXXXXXXXXXXXXXXXXX",
"metadata": {
"description": "ObjectID for user to get full rights to keyvault. Default is Henry's I account"
}
},
"hostingEnvironment": {
"type": "string"
},
"Division": {
"type": "string"
},
"OwnerName": {
"type": "string",
"defaultValue": "aValue",
"metadata": {
"description": "Used to distinquish who in is responsible for the resource"
}
},
"hostingPlanName": {
"type": "string",
"defaultValue": "hostingPlanName",
"metadata": {
"description": "Appservice Plan. Default = . Must supply one for Prod"
}
},
"environmentName": {
"type": "string",
"defaultValue": "uat",
"allowedValues": [ "uat", "qa", "prod" ],
"metadata": {
"description": "What environment will this run in"
}
},
//try to collapse this based on environment name
"environmentType": {
"type": "string",
"defaultValue": "nonProd",
"allowedValues": [ "nonProd", "prod" ],
"metadata": {
"description": "What type environment will this run in"
}
}
},
"variables": {
"suffix": "[uniqueString(resourceGroup().id,resourceGroup().location)]",
"environmentBasedValues": {
"nonProd": {
"fullDeployedName": "[tolower(substring(concat(parameters('name'),'-',substring(parameters('environmentName'),0,1),'-',variables('suffix')),0,24))]",
"keyVaultDeployedName": "[tolower(substring(concat(parameters('name'),'-',substring(parameters('environmentName'),0,1),'-',variables('suffix')),0,24))]",
"hostingPlanDeployedName": "[parameters('hostingPlanName')]",
"serverFarmResourceGroupDeployedName": "[resourceGroup().name]"
},
"prod": {
"fullDeployedName": "[tolower(substring(concat(parameters('name'),'-',variables('suffix')),0,24))]",
"keyVaultDeployedName": "[tolower(substring(concat(parameters('name'),'-',variables('suffix')),0,24))]",
"hostingPlanDeployedName": "[parameters('hostingPlanName')]",
"serverFarmResourceGroupDeployedName": "[resourceGroup().name]"
}
},
"Agency": "AGENCY",
"OwnerName": "[parameters('OwnerName')]",
"alwaysOn": true,
"currentStack": "dotnetcore",
"phpVersion": "OFF",
"errorLink": "[concat('https://',variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName,'.scm.azurewebsites.net/detectors?type=tools&name=eventviewer')]"
},
"resources": [
{
"apiVersion": "2016-08-01",
"name": "[variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName]",
"type": "Microsoft.Web/sites",
//"location": "[parameters('location')]",
"location": "[resourceGroup().location]",
"tags": {
"Agency": "[variables('agency')]",
"OwnerName": "[variables('OwnerName')]",
"Application": "[parameters('name')]",
"Division": "[parameters('Division')]",
"Environment": "[parameters('environmentName')]"
},
"identity": {
"type": "SystemAssigned"
},
"dependsOn": [],
"properties": {
"name": "[variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName]",
"siteConfig": {
"appSettings": [
{
"name": "ANCM_ADDITIONAL_ERROR_PAGE_LINK",
"value": "[variables('errorLink')]"
},
{
"name": "ASPNETCORE_ENVIRONMENT",
"value": "[parameters('environmentName')]"
}
],
"metadata": [
{
"name": "CURRENT_STACK",
"value": "[variables('currentStack')]"
}
],
"phpVersion": "[variables('phpVersion')]",
"alwaysOn": "[variables('alwaysOn')]"
},
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', variables('environmentBasedValues')[parameters('environmentType')].serverFarmResourceGroupDeployedName, '/providers/Microsoft.Web/serverfarms/', variables('environmentBasedValues')[parameters('environmentType')].hostingPlanDeployedName)]",
"hostingEnvironment": "[parameters('hostingEnvironment')]",
"clientAffinityEnabled": true
},
"resources": [
{
"apiVersion": "2018-02-01",
"location": "[resourceGroup().location]",
"name": "virtualNetwork",
"properties": {
"subnetResourceId": "[resourceId('NetworkRG','Microsoft.Network/virtualNetworks/Subnets/','VNETNAME' ,'SUBNETNAME')]",
"swiftSupported": true
},
"type": "config",
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName)]"
// "[concat(resourceId('NetworkRG','Microsoft.Network/virtualNetworks','PrimaryVNet'))]"
]
}
]
},
{
"apiVersion": "2016-10-01",
"location": "[resourceGroup().location]",
"name": "[variables('environmentBasedValues')[parameters('environmentType')].keyVaultDeployedName]",
"type": "Microsoft.KeyVault/vaults",
"tags": {
"Agency": "[variables('agency')]",
"OwnerName": "[variables('OwnerName')]",
"Application": "[parameters('name')]",
"Division": "[parameters('Division')]",
"Environment": "[parameters('environmentName')]"
},
"properties": {
"sku": {
"family": "A",
"name": "Standard"
},
"tenantId": "[subscription().tenantId]",
"accessPolicies": [
{
"tenantId": "[subscription().tenantId]",
"objectId": "[reference(resourceId('Microsoft.Web/sites', variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName),'2018-11-01','Full').identity.principalId]",
"permissions": {
"keys": [],
"secrets": [ "get","list" ],
"certificates": []
}
},
{
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('keyVaultUserObjectId')]",
"permissions": {
"keys": [ "all" ],
"secrets": [ "all" ],
"certificates": [ "all" ]
}
}
]
}
}
],
"outputs": {
"resourceGroupName": {
"type": "string",
"value": "[resourceGroup().name]"
},
"mykeyVaultUserObjectId": {
"type": "string",
"value": "[parameters('keyVaultUserObjectId')]"
},
"myAppIdentity": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Web/sites', variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName),'2018-11-01','Full').identity.principalId]"
},
"myFullDeployedName": {
"type": "string",
"value": "[variables('environmentBasedValues')[parameters('environmentType')].fullDeployedName]"
},
"myEnvironmentType": {
"type": "string",
"value": "[parameters('environmentType')]"
},
"myVnetID": {
"type": "string",
"value": "[concat(resourceId('NetworkRG','Microsoft.Network/virtualNetworks','VNETNAME'))]"
},
"mySubnetID": {
"type": "string",
"value": "[concat(resourceId('NetworkRG','Microsoft.Network/virtualNetworks', 'VNETNAME'), '/subnets/SUBNETNAME')]"
}
}
}

It looks like the template above does work. I ran it again and check the site and the VNET/Subnet were configured correctly. I don't know if I was looking at a cached version or the wrong instance before but this is ok. Thanks for the help!

Related

How can I attach Private End Point to Logic App created using ARM Template

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.

azure ARm Template - Fails to associate AD app registration with function app

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

ARM template fails when creating event hub in multiple regions with multiple auth rules

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"
]
}
},

Appservice and slots deployment issues with ARM template

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.

Problem deploying multiple resources using ARM Subscription Level Deployment

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.

Resources