Is setting FUNCTIONS_EXTENSION_VERSION sufficient when updating Azure Function App with ARM template? - azure-resource-manager

When deploying the resources for my Function App with an ARM template like this
{
"type": "Microsoft.Web/sites",
"kind": "functionapp",
"name": "[parameters('appNameFunctions')]",
"apiVersion": "2015-08-01",
"location": "West Europe",
"tags": {},
"properties": {
"name": "[parameters('appNameFunctions')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('aspNameFunctions'))]"
},
"resources": [
{
"name": "appsettings",
"type": "config",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('appNameFunctions'))]"
],
"tags": {
"displayName": "fnAppSettings"
},
"properties": {
"AzureWebJobsStorage":"[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountNameFunctions'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountNameFunctions')), '2015-05-01-preview').key1)]",
"AzureWebJobsDashboard":"[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountNameFunctions'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountNameFunctions')), '2015-05-01-preview').key1)]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING":"[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountNameFunctions'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountNameFunctions')), '2015-05-01-preview').key1)]",
"WEBSITE_CONTENTSHARE":"[parameters('appNameFunctions')]",
"FUNCTIONS_EXTENSION_VERSION":"~0.8",
"AZUREJOBS_EXTENSION_VERSION":"beta",
"WEBSITE_NODE_DEFAULT_VERSION":"6.5.0"
}
}
],
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('aspNameFunctions'))]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountNameFunctions'))]"
]
}
is it sufficient to just set FUNCTIONS_EXTENSION_VERSION to the desired version and App Service automatically adjusts / loads the correct runtime or is there something else that needs to be adjusted or executed?

Yes, it is sufficient, and is exactly what the Portal does when you click the button to upgrade your app.
Another option is to set it to "latest", which means it will always use the very latest. Though the risk in doing that is to be affected by breaking changes.

Related

I was trying to deploy a Storage Account using ARM template. However, an error has been thrown. Can someone help me on this issue

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "North Europe"
},
"storageaccountname": {
"defaultValue": "storageforarm1910",
"type": "string"
},
"storageaccounttype": {
"type": "string",
"defaultValue": "Standard_GRS"
}
},
"functions": [],
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-01-01",
"location": "[parameters('location')]",
"name": "[parameters('storageaccountname')]",
"kind": "FileStorage",
"sku": "[parameters('storageaccounttype')]",
"properties": {}
}
],
"outputs": {}
}
Error:
{"code":"InvalidTemplate","message":"Deployment template parse failed: 'Error converting value \"Standard_GRS\" to type 'Microsoft.WindowsAzure.ResourceStack.Common.Core.Definitions.Resources.ResourceSku'. Path ''.'."}
If we want to create Azure FileStorage account, the sku must be Premium_LRS or Premium_ZRS. For more details, please refer to the official document.
Besides,please note that if we use Premium_ZRS, we just can create the storage account in some regions. Regarding the region, please refer to here.

Does Azure portal using undocumented ARM features to deploy App Services?

I'm looking at template generated for adding Web App which is generated by Azure portal. I chose .NET core as runtime and it's passed to metadata field in generated ARM template below with a value of dotnetcore. The end result is resource created in Azure with all the stuff you expect from web app. I don't see this field being documented and or explanation how it's being used. Is it some internal know-how or how this process works?
"resources": [
{
"apiVersion": "2018-11-01",
"name": "[parameters('name')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('location')]",
"tags": {},
"dependsOn": [],
"properties": {
"name": "[parameters('name')]",
"siteConfig": {
"appSettings": [
{
"name": "ANCM_ADDITIONAL_ERROR_PAGE_LINK",
"value": "[parameters('errorLink')]"
}
],
"metadata": [
{
"name": "CURRENT_STACK",
"value": "[parameters('currentStack')]"
}
],
"phpVersion": "[parameters('phpVersion')]",
"alwaysOn": "[parameters('alwaysOn')]"
},
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"hostingEnvironment": "[parameters('hostingEnvironment')]",
"clientAffinityEnabled": true
}
}
]

Function MSDeploy and Event Grid Subscription Race Condition in ARM Template

I am deploying a function using MSDeploy extensions and then deploying event grid subscription with this function as endpoint. Event grid deployment fails with message -
"details": [
{
"code": "Endpoint validation",
"message": "The attempt to validate the provided azure endpoint resource:/subscriptions/XXXXX/resourceGroups/ResourceGroupName/providers/Microsoft.Web/sites/FunctionAppName/functions/EndpointName failed."
}
]
I believe this is because event grid subscription tried to get created before the function endpoint deployed with MSDeploy is up and running.
How can i avoid this race condition?
Note: Deploying the same template again creates the event grid fine.
Template being used-
//function app
{
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites",
"name": "[parameters('functionAppName')]",
"location": "[resourceGroup().location]",
"kind": "functionapp",
"dependsOn": [
"[variables('azureFunction_serverFarmResourceId')]"
],
"properties": {
"serverFarmId": "[variables('azureFunction_serverFarmResourceId')]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),variables('storageAccountApiVersion')).keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),variables('storageAccountApiVersion')).keys[0].value)]"//"[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~10"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', parameters('functionApp_applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
}
]
}
},
"resources": [
{
"apiVersion": "2018-11-01",
"name": "MSDeploy",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('functionAppName'))]"
],
"properties": {
"packageUri": "[parameters('functionAppDeployPackageUri')]"
},
"type": "extensions"
}
]
},
//event grid
{
"type": "Microsoft.Storage/storageAccounts/providers/eventSubscriptions",
"name": "[concat(parameters('storageAccountName'), '/Microsoft.EventGrid/', parameters('blobcreate_eventsubscription_name'))]",
"apiVersion": "2020-04-01-preview",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('functionAppName'), '/extensions/MSDeploy')]",
"[resourceId('Microsoft.Web/sites', parameters('functionAppName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
],
"properties": {
"destination": {
"endpointType": "AzureFunction",
"properties": {
"resourceId": "[concat(resourceId('Microsoft.Web/sites', parameters('functionAppName')), '/functions/', variables('egressDataProcessorFunctionName'))]"
}
},
"filter": {
"subjectBeginsWith": "[concat('/blobServices/default/containers/', parameters('storageAccounts_mainblob_name'))]",
"subjectEndsWith": ".xml",
"includedEventTypes": [
"Microsoft.Storage.BlobCreated"
],
"advancedFilters": []
},
"retryPolicy": {
"maxDeliveryAttempts": "[parameters('eventgrid_maxDeliveryAttemps')]",
"eventTimeToLiveInMinutes": "[parameters('eventgrid_eventTimeToLiveInMinutes')]"
},
"deadLetterDestination": {
"endpointType": "StorageBlob",
"properties": {
"resourceId": "[variables('storageAccountResourceId')]",
"blobContainerName": "[parameters('storageAccounts_deadletterblob_name')]"
}
}
}
}
One way is to deploy your function app as a linked template, and then have your root template:
Deploy the function app template with the function url as an output.
Deploy an Event Grid subscription that depends on the function app deployment and references its output.
Another possibility is to spit appsettings into a childresource, and have that depend on your MSDeploy resource, then the Event Grid depend on appsettings.

Internal server error when deploying ARM Template

I am deploying an arm template that contains the following resources
Microsoft.Storage/storageAccount
Microsoft.Sql/servers
Microsoft.Sql/servers/auditPolicies
Now everything worked until I started changing the values for the auditPolicies object. Here are the steps I took until the InternalServerError occurred.
Added the auditState property and set its value to Disabled. Deployment Successful.
Changed the auditState property to Enabled. Deployment failed. Error states that the storageAccountName is required.
Added storageAccountName and set its value to the name of the storage account. Deployment failed. Error states that storageAccountKey.
Added storageAccountKey and set its value to key1 of the storage account's keys object. Deployment failed. Internal Server Error - "An Error has occurred while saving Auditing settings, please try again later". Additionally, the errors cause the deployment to run indefinitely. Though I am not concerned about that aspect.
The following is the complete template.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"app-name-prefix": {
"type": "string",
"minLength": 1
},
"app-locations": {
"type": "array",
"minLength": 1
},
"app-friendly-names": {
"type": "array",
"minLength": 1
},
"db-user-admin-username": {
"type": "securestring"
},
"db-user-admin-password": {
"type": "securestring"
},
"database-audit-enabled": {
"defaultValue": "Enabled",
"allowedValues": [
"Enabled",
"Disabled"
],
"type": "string"
},
"storage-kind": {
"defaultValue": "BlobStorage",
"allowedValues": [
"StorageV2",
"BlobStorage"
],
"type": "string"
},
"storage-sku": {
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_ZRS",
"Standard_GRS",
"Standard_RAGRS",
"Premium_LRS"
],
"type": "string"
}
},
"variables": {
"db-service-name": "[concat(parameters('app-name-prefix'), '-database-service-')]",
"storage-name": "[concat(toLower(parameters('app-name-prefix')), 'auditstorage')]"
},
"resources": [
{
"name": "[concat(variables('storage-name'), parameters('app-friendly-names')[copyIndex()])]",
"type": "Microsoft.Storage/storageAccounts",
"sku": {
"name": "[parameters('storage-sku')]"
},
"kind": "[parameters('storage-kind')]",
"apiVersion": "2018-02-01",
"location": "[parameters('app-locations')[copyIndex()]]",
"copy": {
"count": "[length(parameters('app-locations'))]",
"name": "storageCopy"
},
"properties": {
"supportsHttpsTrafficOnly": true,
"accessTier": "Hot",
"encryption": {
"services": {
"blob": {
"enabled": true
},
"file": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
}
}
},
{
"type": "Microsoft.Sql/servers",
"name": "[concat(variables('db-service-name'), parameters('app-friendly-names')[copyIndex()])]",
"apiVersion": "2014-04-01",
"location": "[parameters('app-locations')[copyIndex()]]",
"copy": {
"name": "databaseServiceCopy",
"count": "[length(parameters('app-locations'))]"
},
"properties": {
"administratorLogin": "[parameters('db-user-admin-username')]",
"administratorLoginPassword": "[parameters('db-user-admin-password')]",
"version": "12.0"
},
"resources": [
{
"type": "auditingPolicies",
"name": "Default",
"apiVersion": "2014-04-01",
"location": "[parameters('app-locations')[copyIndex()]]",
"properties": {
"auditingState": "[parameters('database-audit-enabled')]",
"storageAccountName": "[concat(variables('storage-name'), parameters('app-friendly-names')[copyIndex()])]",
"storageAccountKey": "[listKeys(concat(variables('storage-name'), parameters('app-friendly-names')[copyIndex()]), '2018-02-01').keys[0].value]"
},
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', concat(variables('db-service-name'), parameters('app-friendly-names')[copyIndex()]))]",
"storageCopy"
]
}
]
}
]
}
What am I missing that will help resolve this issue? What do I need to do to stop this internal server error?
I have added the complete template as was requested by #Pete
I have found the answer after connecting with Azure Support.
The resource type: Microsoft.Sql/servers/auditingPolicies is no longer supported and in the next few weeks Azure Resource Manager will no longer support this completely.
This resource type refers directly to table auditing, which has been reported as being deprecated for blob auditing. Though the documentation at this time does not directly report it. The docs will be updated in the coming days after this post, by the owners.
To enable the auditing you need to use the Microsoft.Sql/servers/auditingSettings object. The documentation on this is coming and until it does you will be directed to documentation for the database version of this resource type Microsoft.Sql/servers/databases/auditingSettings.
Auditing settings work much like the Auto-Tuning advisors. You can set either server or database level settings. The server settings will be inherited by the database if the database has not been configured directly.
This is a sample of the auditingSettings object that I use instead of the auditingPolicies object above. It is nested just the same.
{
"apiVersion": "2017-03-01-preview",
"type": "auditingSettings",
"name": "DefaultAuditingSettings",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', concat(variables('db-service-name'), parameters('app-friendly-names')[copyIndex()]))]",
"storageCopy"
],
"properties": {
"state": "Enabled",
"storageEndpoint": "[reference(concat('Microsoft.Storage/storageAccounts', '/', variables('storage-name'), parameters('app-friendly-names')[copyIndex()]), '2018-02-01').primaryEndpoints.blob]",
"storageAccountAccessKey": "[listKeys(concat(variables('storage-name'), parameters('app-friendly-names')[copyIndex()]), '2018-02-01').keys[0].value]",
"storageAccountSubscriptionId": "[subscription().subscriptionId]",
"isStorageSecondaryKeyInUse": false,
"retentionDays": "30"
}
}

DependsOn Failing in ARM Template

Im trying to connect our website to a Application Insights component via ARM but havning troubles in setting the Intstrumentation Key as an website application setting. This works sometimes and sometimes not.
My guess is that im having incorrect dependsOn settings. Can anyone have a look on my template and see if im doing something wrong? Have a look on the resource called "appSettings" of type "config" in the website resource. Here I am supposed to wait for completion of the Application Insight and then read the Instrumentation Key.
{
"name": "[variables('webAppNameFinal')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('appServicePlanLocation')]",
"apiVersion": "2015-04-01",
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', variables('appServicePlanNameFinal'))]"
],
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanNameFinal'))]": "Resource",
"displayName": "webApp"
},
"properties": {
"name": "[variables('webAppNameFinal')]",
"serverFarmId": "[variables('appServicePlanNameFinal')]"
},
"resources": [
{
"apiVersion": "2015-04-01",
"name": "connectionstrings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', variables('webAppNameFinal'))]",
"[resourceId('Microsoft.Sql/servers', variables('sqlServerNameFinal'))]"
],
"properties": {
"Watches": {
"value": "[concat('Server=tcp:', reference(concat('Microsoft.Sql/servers/', variables('sqlServerNameFinal'))).fullyQualifiedDomainName, ',1433;Database=', variables('sqlDatabaseNameFinal'), ';User ID=', parameters('sqlServerAdminLogin'), ';Password=', parameters('sqlServerAdminLoginPassword'), ';Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;')]",
"type": "SQLAzure"
}
}
},
{
"apiVersion": "2015-08-01",
"name": "appsettings",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', variables('webAppNameFinal'))]",
"[concat('Microsoft.Insights/components/', variables('applicationInsightsNameFinal'))]"
],
"properties": {
"Watches.Webjobs.VitecConnect.WatchersExport.Run": "false",
"ApplicationInsights.InstrumentationKey": "[reference(concat('Microsoft.Insights/components/', variables('applicationInsightsNameFinal'))).InstrumentationKey]"
}
},
{
"apiVersion": "2015-04-01",
"name": "web",
"type": "sourcecontrols",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', variables('webAppNameFinal'))]"
],
"properties": {
"RepoUrl": "[parameters('gitUrl')]",
"branch": "[parameters('gitBranch')]"
}
},
{
"apiVersion": "2015-08-01",
"name": "web",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', variables('webAppNameFinal'))]"
],
"properties": "[variables('siteProperties')]"
}
]
},
{
"name": "[variables('applicationInsightsNameFinal')]",
"type": "Microsoft.Insights/components",
"location": "Central US",
"apiVersion": "2014-04-01",
"dependsOn": [ ],
"tags": {
"displayName": "Application Insights"
},
"properties": {
"applicationId": "[variables('webAppNameFinal')]"
}
},
Best reagards
Niclas
Have you tried to place the dependsOn inside the insight resource declaration?
Have a look at the Quickstart template for a web+sql here: https://github.com/Azure/azure-quickstart-templates/blob/master/201-web-app-sql-database/azuredeploy.json
They placed the dependsOn on the Insight declaration and nothing on the website declaration. Would that work for you?
{
"apiVersion": "2015-05-01",
"name": "[concat('AppInsights', variables('webSiteName'))]",
"type": "Microsoft.Insights/components",
"location": "centralus",
"dependsOn": [
"[variables('webSiteName')]"
],
"tags": {
"[concat('hidden-link:', resourceId('Microsoft.Web/sites', variables('webSiteName')))]": "Resource",
"displayName": "AppInsightsComponent"
},
"properties": {
"ApplicationId": "[variables('webSiteName')]"
}
}

Resources