ARM template storage account not found while creating Azure Function App - azure

I have an ARM template which creates a Storage Account, App Service Plan, Application Insights and a Function App. In the dependsOn section of the Function App, I configured it to be depending on the other three resources. But when I deploy the template, it fails with the following error:
Status Message: The Resource 'Microsoft.Storage/storageAccounts/dummystorage' under resource group 'dummy-rg' was not found.
I see that the Storage Account, ASP and App Insights are being created first, followed by the Function App. So it seems the dependency is being honored. It's almost like the Storage Account provisioning is not completely finished when the Function App is being created. As you can see in the template below, the Function App resource uses the listKeys to get the Storage Account keys as part of the provisioning.
Does anybody have any idea how I can prevent this from happening? I've read everything in the docs regarding dependencies, and I believe this should just work.
One remark is that the storage account is being deployed based on a condition. I can't imagine it has something to do with my issue, but I just wanted to mention it.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"functionAppName": {
"type": "string"
},
"appServicePlanName": {
"type": "string"
},
"appInsightsName": {
"type": "string"
},
"deployStorage": {
"type": "bool",
"defaultValue": true
},
"storageAccountName": {
"type": "string"
},
"utcDateTime": {
"type": "string",
"defaultValue": "[utcNow()]"
}
},
"variables": {
"storageAccountDeploymentName": "[concat('storageDeploy-', parameters('utcDateTime'))]",
},
"resources": [
{
"name": "[parameters('functionAppName')]",
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites",
"kind": "functionapp",
"location": "[parameters('location')]",
"tags": "[parameters('tags')]",
"dependsOn": [
"[parameters('appInsightsName')]",
"[parameters('appServicePlanName')]",
"[resourceId('Microsoft.Resources/deployments', variables('storageAccountDeploymentName'))]"
],
"properties": {
"name": "[parameters('functionAppName')]",
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "powershell"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('Microsoft.Insights/components/', parameters('appInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[reference(concat('Microsoft.Insights/components/', parameters('appInsightsName')), '2015-05-01').ConnectionString]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[concat(toLower(parameters('functionAppName')), '813b')]"
}
],
"use32BitWorkerProcess": false,
"powerShellVersion": "[variables('powerShellVersion')]"
},
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
"clientAffinityEnabled": true
}
},
{
"name": "[parameters('appServicePlanName')]",
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('location')]",
"tags": "[parameters('tags')]"
// snip
},
{
"name": "[parameters('appInsightsName')]",
"apiVersion": "2020-02-02-preview",
"type": "microsoft.insights/components",
"location": "[parameters('location')]",
"tags": "[parameters('tags')]",
// snip
},
{
"name": "[variables('storageAccountDeploymentName')]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"condition": "[parameters('deployStorage')]",
"properties": {
"expressionEvaluationOptions": {
"scope": "outer"
},
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "[parameters('storageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"tags": "[parameters('tags')]",
"location": "[parameters('location')]",
// snip
}
]
}
}
}
]
}

I think you're running into this: https://bmoore-msft.blog/2020/07/26/resource-not-found-dependson-is-not-working/
TLDR;
listKeys is called in a separate job in the deployment engine and gets called early if that resource (i.e. your storage) is not in the same deployment.
you don't need to nest your storageAccount deployment, doesn't hurt but doesn't help. If your storageAccount deployment is unconditional, then it will help because ARM will wait before running listKeys.
if you need the condition, the only fix is to nest the function app deployment and set a dependency on the conditional storageAccount (the dependency need not be conditional ARM will handle that). You need to set the evaluation scope to "inner" on that nested deployment.
That help?

I noticed your dependsOn for Storage looks like this:
"dependsOn": [
"[parameters('appInsightsName')]",
"[parameters('appServicePlanName')]",
"[resourceId('Microsoft.Resources/deployments', variables('storageAccountDeploymentName'))]"
Whereas my despendsOn for Storage Account and Blob Container looks like this... could that be the reason it's not working? I have never used Microsoft.Resources/deployments (FYI my ARM Template deployment is working)
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', variables('StorageAccountName'), 'default', variables('BlobContainerName2'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"

Alternatively:
You could drop the conditional and deploy the Storage Account each time. If it exists no change, if it doesn't exist then it's created.
The only caveat to this is if you change something on the storage account post-deployment or if the Storage account has a dynamically set name based on Timestamp or GUID etc.
I realize this is a work around, but it should solve your problem barring the caveat above.

Related

How can I set dependencies on child resources in nested ARM template?

I am trying to use nested templates to deploy a resource group and multiple resources within it on subscription level.
Microsoft documentation has an example of deploying resource group and storage account that I'm trying to follow. I am trying to create another inner level of dependency between a Storage Account resource and a Container resource. That is, the container should only be deployed after the deployment of the storage account is finished. Here is simplified version of my template:
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"rgName": {
"type": "string"
},
"rgLocation": {
"type": "string"
},
"storagePrefix": {
"type": "string",
"maxLength": 11
},
"containerName": {
"type": "string"
}
},
"variables": {
"storageName": "[concat(parameters('storagePrefix'), uniqueString(subscription().id, parameters('rgName')))]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2021-04-01",
"name": "[parameters('rgName')]",
"location": "[parameters('rgLocation')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2021-04-01",
"name": "storageDeployment",
"resourceGroup": "[parameters('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[variables('storageName')]",
"location": "[parameters('rgLocation')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2"
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2021-06-01",
"name": "[format('{0}/default/{1}', variables('storageName'), parameters('containerName'))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageName'))]"
]
}
],
"outputs": {}
}
}
}
],
"outputs": {}
}
When I try to deploy this template using PowerShell script New-AzSubscriptionDeployment, I get the following error:
| InvalidTemplate - Long running operation failed with status 'Failed'. Additional Info:'Deployment template validation failed: 'The resource 'Microsoft.Storage/storageAccounts/myStorageAccount' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.'
I kind of know it has to do with the dependsOn part of the container resource. But how can I resolve this problem?
EDIT: The selected answer solves the problem with dependencies, however the issue still persists in cases where a value needs to be called using concat or listKeys expressions. Here's an example where setting the value for AzureWebJobsStorage throws an error in a nested template:
{
"type": "Microsoft.Web/sites",
[ ... ]
"dependsOn": [
"[variables('hostingPlanName')]",
"[variables('functionAppStorageAccountName')]"
],
"properties": {
"serverFarmId": "[variables('hostingPlanName')]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('functionAppstorageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionAppstorageAccountName')), '2021-04-01').keys[0].value)]"
}
[ ... ]
]
}
The value for AzureWebJobsStorage causes the deployment to fail with the following error:
`Status Message: The Resource 'Microsoft.Storage/storageAccounts/stfuncaedotestfeb16g' under resource group '<null>' was not found. For more details
| please go to https://aka.ms/ARMResourceNotFoundFix (Code:ResourceNotFound) CorrelationId: 55942377-6d0f-40ec-9733-33b9c3ea13de
I tried being more verbose by using resource group name (and then subscription ID), but that didn't solve the problem.
You should be able to use:
"dependsOn": [
"[variables('storageName')]"
]
Note that will only work if there is no other resource in the template with the same name - otherwise you have to manually construct the full resourceId, like:
[format('{0}/resourceGroups/{1}/providers/Microsoft.Storage/storageAccounts/{2}', subscription().id, parameters('rgName'), variables('storageName'))]
The latter form will always work, just a bit more verbose.
A bit more detail is that the resourceId function doesn't work as you would expect at subscription scope.

Nested ARM template and dependsOn in another Resource Group

I am trying to create a Function App with VNET Integration in ARM. I have made all that work just fine in one main template.
Now I have a new requirement where the VNET needs to be in another RG and thus seperate from the Func App RG, but the Func App still needs to have VNET integration to the VNET in the other RG.
I'm struggling how to define the ARM template, so that I deploy the Func App in one RG and VNET in another. The hard part is how to define this so that the Func App integrates into a VNET in another RG in the same ARM template using nested template.
Here is my ARM template:
"resources": [{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"name": "nestedTemplate",
"resourceGroup": "[parameters('VNETPeered_RG_Name')]",
"subscriptionId": "0a2009c0-e2ae-4991-aa0e-5c34c141e4cb",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [{
"comments": "Virtual Network for VNET integration feature in the Premium Plan for the Function App",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2019-11-01",
"name": "[variables('virtual_network_name')]",
"location": "[resourceGroup().location]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [{
"name": "[variables('subnet_name')]",
"properties": {
"addressPrefix": "[parameters('subnet1Prefix')]",
"serviceEndpoints": [{
"service": "Microsoft.Storage",
"locations": [
"[resourceGroup().location]"
]
}
}
}]
}
}]
}
}
},
{
"comments": "Function App to host the functions themselves. Integrates into a VNET and makes use of Azure DNS Private Zones.",
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"name": "[variables('function_app_name')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"nestedTemplate",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storage_account_name'))]",
"[resourceId('Microsoft.Web/serverfarms', variables('app_service_plan_name'))]"
],
"kind": "functionapp",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('app_service_plan_name'))]",
"siteConfig": {
"appSettings": [{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(variables('application_insights_resourceId'), '2018-05-01-preview').InstrumentationKey]"
}]
},
"clientAffinityEnabled": true
},
"resources": [{
"type": "networkConfig",
"apiVersion": "2019-08-01",
"name": "virtualNetwork",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('function_app_name'))]"
],
"properties": {
"subnetResourceId": "[reference(resourceId('RG-FunctionsGroup','Microsoft.Network/virtualNetworks/subnets', 'vn-MY-VNET', 'sn-MY-SUBNET'),'2020-05-01')]",
"isSwift": true
}
}]
]
}
On this I get the following error when I try to deploy it with az deployment group command from az cli:
Deployment failed. Correlation ID: 39b0173b-8a51-42c5-a796-1d3427556194. {
"error": {
"code": "InternalServerError",
"message": "There was an unexpected InternalServerError. Please try again later. x-ms-correlation-request-id: 844e9f35-2e9c-411a-817d-9045511558cb"
}
}
reference() will work but TLDR; it's a little heavyweight
https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource#resourceid
is all you need in this case. To "reference" any resource in ARM you'll use the resourceId - there are a handful of functions to help but it really helps if you understand the basics of the resourceId, which is summarized here:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource#return-value-6
When you want a resourceId to a resource in the same deployment (which is not the same as the same template) you can use the shorthand version
resourceId({namespace/resourceType}, {resourceName})
If it's in a different RG, you need to add the RG param, and if it's in a different sub you need to add that too. I can't tell for certain with your snippet, but it looks like all you need in your case is this (assuming the vnet and fn app are in the same subscription):
"subnetResourceId": "[resourceId(parameters('VNETPeered_RG_Name'), 'Microsoft.Network/virtualNetworks/subnets', variables('virtual_network_name'), variables('subnet_name'))]"
That help?
Your problem is in this part of code:
"properties": {
"subnetResourceId": "[reference(resourceId('RG-FunctionsGroup','Microsoft.Network/virtualNetworks/subnets', 'vn-MY-VNET', 'sn-MY-SUBNET'),'2020-05-01')]",
"isSwift": true
}
You are pointing the subnet with the wrong resource group. Change the resource group where the vnet and the subnet is deployed.
"properties": {
"subnetResourceId": "[reference(resourceId(parameters('VNETPeered_RG_Name'),'Microsoft.Network/virtualNetworks/subnets', variables('virtual_network_name'), variables('subnet_name')),'2020-05-01')]",
"isSwift": true
}

Deploying ARM templates from Azure Release Pipelines removes code

According to documentation "An ARM template is idempotent, which means it can be executed as many times as you wish, and the result will be the same every time". But I just learned that when I redeploy AppService (without any changes) it removes my application. Endpoints were not responding anymore and there was no application logs so I went to Azure portal console, ran DIR, and to my surprise the only file that is there is hostingstart.html! Is it documented somewhere? This changes completely how I need to handle ARM templates in my Release pipeline.
I'm using linked templates. In main template I have this resource:
{
"name": "myApp",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"dependsOn": [
"storage"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[uri(variables('templateBaseUrl'), 'myApp.json')]"
},
"parameters": {
"env": {
"value": "[parameters('env')]"
},
"myAppAppServiceSku": {
"value": "[parameters('myAppAppServiceSku')]"
},
"storageAccountName": {
"value": "[variables('storageAccountName')]"
}
}
}
}
and the linked template
"resources": [
{
"name": "[variables('myAppServerFarmName')]",
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"location": "[resourceGroup().location]",
"tags": {
"ENV": "[parameters('env')]"
},
"sku": {
"name": "[parameters('myAppAppServiceSku')]"
},
"properties": {
}
},
{
"name": "[variables('myAppWebSiteName')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"dependsOn": [
"[variables('myAppServerFarmName')]"
],
"location": "[resourceGroup().location]",
"tags": {
"ENV": "[parameters('env')]"
},
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms/', variables('myAppServerFarmName'))]",
"siteConfig": {
"alwaysOn": true
}
},
"resources": [
{
"name": "appSettings",
"type": "config",
"apiVersion": "2018-11-01",
"dependsOn": [
"[variables('myAppWebSiteName')]"
],
"tags": {
"ENV": "[parameters('env')]"
},
"properties": {
"storageAccountName": "[parameters('storageAccountName')]",
"storageKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '2019-04-01').keys[0].value]"
}
}
]
}
]
EDIT:
I have checked with deployment using Kudu ZIP Deploy. And after this deployment it redeployment of ARM templates does not remove code! So it works as expected. So deployment from Release Pipelines is different in some way.
After I execute both steps everything looks fine. But when I then just execute first step application code is removed.
This is how it looks right now.
And steps have one task each:
See Azure Functions ARM template redeployment deletes my published functions for more info. Essentially you need to add this to your template:
{ "name": "WEBSITE_RUN_FROM_PACKAGE", "value": "1" }

How to create Application Insights API Key for annotations using ARM template

I'm trying to create Application Insights API keys from ARM template. I need to have the API key for write annotations created during resource deployment to have release annotations working during application deployment from Azure Devops.
I've tried to find information on how to get this working, but I can only find examples on how to use PowerShell or Azure REST API to create the keys.
What I need to get working is to create the API keys using the ARM template.
I have tried numerous attempts with json similar to this without success;
{
"name": "[variables('applicationInsightsName')]",
"type": "Microsoft.Insights/components",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"tags": {
"displayName": "[concat('Component ', variables('applicationInsightsName'))]"
},
"properties": {
"applicationId": "[variables('applicationInsightsName')]"
},
"resources": [
{
"name": "action",
"type": "apikeys",
"location": "[resourceGroup().location]",
"apiVersion": "2015-05-01",
"properties": {
"name": "Azure Devops Release Annotations",
"linkedWriteProperties": [
"[concat(resourceId('Microsoft.Insights/components', variables('applicationName')), '/annotations')]"
],
"linkedReadProperties": []
},
"dependsOn": [
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]"
]
}
]
}
The best information I've found so far is this, but it isn't much help.
Is it possible to have the API keys created using ARM templates?
No this is not possible, ARM Templates only mimic PUT requests, whereas the Microsoft.Insights/Components/ApiKeys/Action is a POST request.
I suggest an easy way. You are able to use outputs with reference InstrumentationKey. Then you able to use it everywhere: another resource, linked template or use outputs for the next steps by Azure DevOps.
{
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string",
"defaultValue": "[concat('stackoverflow-', uniqueString(resourceGroup().name))]"
},
"type": {
"type": "string",
"defaultValue": "web"
},
"requestSource": {
"type": "string",
"defaultValue": "IbizaAIExtension"
}
},
"resources": [
{
"name": "[parameters('name')]",
"type": "microsoft.insights/components",
"location": "[resourceGroup().location]",
"apiVersion": "2014-08-01",
"properties": {
"ApplicationId": "[parameters('name')]",
"Application_Type": "[parameters('type')]",
"Flow_Type": "Redfield",
"Request_Source": "[parameters('requestSource')]"
}
}
],
"outputs":{
"APPINSIGHTS_INSTRUMENTATIONKEY":{
"type": "string",
"value": "[reference(resourceId('Microsoft.Insights/components', parameters('name')), '2014-08-01').InstrumentationKey]"
}
}
}
I used it many times.

Azure - Set WebSocket On from ARM json template

I'm trying to turn WebSockets On for an Azure WebApp from an Azure ARM json template that deploys my whole infrastructure.
Here is an extract with regards to the Azure Web App. It doesn't work, i.e the WebSockets are still Off. I unsuccessfully tried different spelling: webSocketsEnabled or WebSockets.
"resources":[
{
"name": "[variables('MyApp')]",
"type": "Microsoft.Web/sites",
"location": "Brazil South",
"apiVersion": "2016-08-01",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('MyAppPlanBrazil'))]"
],
"tags": {
"[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', variables('MyAppPlanBrazil')))]": "Resource",
"displayName": "MyAppAppBrazil"
},
"properties": {
"name": "[variables('MyAppPlanBrazil')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('MyAppPlanBrazil'))]",
"siteConfig": {
"AlwaysOn": true,
"webSocketsEnabled": true,
"connectionStrings": [
{
...
},
{
...
},
]
}
}
]
UPDATE
As suggested in answer below I updated the apiVersion to "2016-08-01" but this still doesn't work.
Also note that while my schema is the one described here, apiVersion is squiggled in VS and it says the authorized value is "2015-08-01" only.
UPDATE2
I tried the solutions below. They work for their authors but not for me. I guess the problem is elsewhere. My infrastructure is already deployed and I try to update it with webSocketsEnabled. Whereas in the solution below I imagine the authors directly create the web app with webSocketsEnabled.
Also, I coupled webSocketsEnabled with alwaysOn whereas the pricing tier of my webapp doesn't allow "AlwaysOn" (as it says in the portal I need to upgrade to use that feature) so I'll try without alwaysOn.
UPDATE3
At the end, the above template worked when I removed AlwaysOn.
Thank you to those who tried to help me.
Set your api version to this: "2016-08-01"
Use
"webSocketsEnabled": true
This is from the Microsoft.Web/sites template reference:
https://learn.microsoft.com/en-us/azure/templates/microsoft.web/sites
The api version you are using (2015-08-01) from:
https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2015-08-01/Microsoft.Web.json
Doesn't have web sockets in it, but the later one:
https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2016-08-01/Microsoft.Web.json
Does have webSocketsEnabled.
Please have a try to use the following code. It works correctly on my side.
Updated: add whole test arm template and you could have a try to use the following code with your service plan name and resource group name
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"serverFarmName": {
"type": "string",
"defaultValue": "YourPlan"
},
"serverFarmResourceGroup": {
"type": "string",
"defaultValue": "ResourceGroupName"
}},
"variables": {
"ARMtemplateTestName": "[concat('ARMtemplateTest', uniqueString(resourceGroup().id))]"},
"resources": [
{
"name": "[variables('ARMtemplateTestName')]",
"type": "Microsoft.Web/sites",
"location": "southcentralus",
"apiVersion": "2015-08-01",
"dependsOn": [ ],
"tags": {
"[concat('hidden-related:', resourceId(parameters('serverFarmResourceGroup'), 'Microsoft.Web/serverFarms', parameters('serverFarmName')))]": "Resource",
"displayName": "ARMtemplateTest"
},
"properties": {
"name": "[variables('ARMtemplateTestName')]",
"serverFarmId": "[resourceId(parameters('serverFarmResourceGroup'), 'Microsoft.Web/serverFarms', parameters('serverFarmName'))]"
},
"resources": [
{
"name": "web",
"type": "config",
"apiVersion": "2015-08-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('ARMtemplateTestName'))]"
],
"tags": {
"displayName": "enableWebSocket"
},
"properties": {
"webSocketsEnabled": true,
"alwaysOn": true
}
},
{
"apiVersion": "2015-08-01",
"name": "connectionstrings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', variables('ARMtemplateTestName'))]"
],
"properties": {
"ConnString1": {
"value": "My custom connection string",
"type": "custom"
},
"ConnString2": {
"value": "My SQL connection string",
"type": "SQLAzure"
}
}
},
{
"name": "appsettings",
"type": "config",
"apiVersion": "2015-08-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('ARMtemplateTestName'))]"
],
"tags": {
"displayName": "Appsetting"
},
"properties": {
"key1": "value1",
"key2": "value2"
}
}
]
}],
"outputs": {}
}
Test Result:
All the above solution should work.
My initial snippet worked as well ... as soon as I removed alwaysOn.
Indeed, I was using a free tiers App Service Plan for which alwaysOn is not available. While there was no errors or anything else indicating something wrong, I could not set webSocketEnabled and alwaysOn at the same time in that case.

Resources