-
-
Save palmerandy/22909c79de6d1f483a727116e5a1bfd4 to your computer and use it in GitHub Desktop.
{ | |
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", | |
"contentVersion": "1.0.0.0", | |
"parameters": { | |
"azureSubscriptionId": { | |
"type": "string", | |
"metadata": { | |
"description": "The azure subscription Id. Something like 12345678-abcd-abcd-abcd-1234567890ab." | |
} | |
}, | |
"appName": { | |
"type": "string", | |
"metadata": { | |
"description": "The name of the Function app to be created / modified" | |
} | |
}, | |
"appServicePlanName": { | |
"type": "string", | |
"metadata": { | |
"description": "The name of the App Service plan that will host the Function app - this must exist already." | |
} | |
}, | |
"functionsStorageAccountName": { | |
"type": "string", | |
"metadata": { | |
"description": "The name of the storage account to be created / modified that will be used to power the new Function app. More details in the comment of the resource." | |
} | |
}, | |
"websiteStorageAccountName": { | |
"type": "string", | |
"metadata": { | |
"description": "The name of the existing storage account that the website uses as it's primary storage account (e.g. for queues and table storage)." | |
} | |
}, | |
"applicationInsightsName": { | |
"type": "string", | |
"metadata": { | |
"description": "The name of the existing application insight to log information." | |
} | |
}, | |
"applicationInsightsLocation": { | |
"type": "string", | |
"metadata": { | |
"description": "The name of the existing application insight to log information." | |
} | |
} | |
}, | |
"variables": { | |
"functionsStorageAccountid": "[concat('/subscriptions/', parameters('subscriptionId'), '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Storage/storageAccounts/', parameters('functionsStorageAccountName'))]", | |
"websiteStorageAccountid": "[concat('/subscriptions/', parameters('subscriptionId'), '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Storage/storageAccounts/', parameters('websiteStorageAccountName'))]", | |
"slotName": "[concat(parameters('appName'), '/staging')]" | |
}, | |
"resources": [ | |
{ | |
"type": "Microsoft.Storage/storageAccounts", | |
"name": "[parameters('functionsStorageAccountName')]", | |
"apiVersion": "2016-12-01", | |
"location": "[resourceGroup().location]", | |
"kind": "Storage", | |
"sku": { | |
"name": "Standard_LRS" | |
}, | |
"properties": { | |
"supportsHttpsTrafficOnly": false, | |
"encryption": { | |
"keySource": "Microsoft.Storage", | |
"services": { | |
"blob": { | |
"enabled": true | |
}, | |
"file": { | |
"enabled": true | |
} | |
} | |
}, | |
"dependsOn": [], | |
"comments": "This storage account is used to log to Azure Table storage and power the Monitor tab in the portal. We explicity use a seperate account, in case we want to change the SKU of websiteStorageAcccount parameter." | |
} | |
}, | |
{ | |
"name": "[parameters('applicationInsightsName')]", | |
"apiVersion": "2014-04-01", | |
"type": "Microsoft.Insights/components", | |
"kind": "other", | |
"location": "[parameters('applicationInsightsLocation')]", | |
"properties": { "applicationId": "[parameters('applicationInsightsName')]" } | |
}, | |
{ | |
"name": "[parameters('appName')]", | |
"apiVersion": "2015-08-01", | |
"type": "Microsoft.Web/sites", | |
"kind": "functionapp", | |
"location": "[resourceGroup().location]", | |
"identity": { | |
"type": "SystemAssigned" | |
}, | |
"properties": { | |
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]", | |
"siteConfig": { | |
"phpVersion": "off", | |
"use32BitWorkerProcess": "false", | |
"alwaysOn": "true", | |
"remoteDebuggingEnabled": "false", | |
"remoteDebuggingVersion": "", | |
"webSocketsEnabled": true, | |
"http20Enabled": true, | |
"ftpsState": "Disabled", | |
"appSettings": [ | |
{ | |
"name": "FUNCTIONS_EXTENSION_VERSION", | |
"value": "~1" | |
}, | |
{ | |
"name": "Project", | |
"value": "src" | |
} | |
] | |
}, | |
"dependsOn": [ | |
"[resourceId('Microsoft.Web/Sites', parameters('appName'))]", | |
"[resourceId('Microsoft.Storage/storageAccounts', parameters('functionsStorageAccountName'))]", | |
"[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]" | |
], | |
"comments": "This Function App will host all Azure functions." | |
}, | |
"resources": [ | |
{ | |
"name": "slotConfigNames", | |
"type": "config", | |
"apiVersion": "2015-08-01", | |
"dependsOn": [ | |
"[resourceId('Microsoft.Web/Sites', parameters('appName'))]" | |
], | |
"tags": { | |
"displayName": "slotConfigNames" | |
}, | |
"properties": { | |
"appSettingNames": [ | |
"DisableAllFunctions" | |
] | |
} | |
}, | |
{ | |
"apiVersion": "2015-08-01", | |
"name": "appsettings", | |
"type": "config", | |
"dependsOn": [ | |
"[resourceId('Microsoft.Web/Sites', parameters('appName'))]", | |
"[resourceId('Microsoft.Storage/storageAccounts', parameters('functionsStorageAccountName'))]" | |
], | |
"properties": { | |
//Important: when adding new App Setting, you need to add them to the staging slot | |
"DisableAllFunctions": "false", //note this setting is slot specific | |
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('websiteStorageAccountName'), ';AccountKey=', listKeys(variables('websiteStorageAccountid'),'2015-05-01-preview').key1)]", | |
"AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('functionsStorageAccountName'), ';AccountKey=', listKeys(variables('functionsStorageAccountid'),'2015-05-01-preview').key1)]", | |
"FUNCTIONS_EXTENSION_VERSION": "~1", | |
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2014-04-01').InstrumentationKey]" | |
} | |
} | |
] | |
}, | |
{ | |
"apiVersion": "2016-08-01", | |
"dependsOn": [ | |
"[resourceId('Microsoft.Web/sites', parameters('appName'))]" | |
], | |
"kind": "functionapp", | |
"location": "[resourceGroup().location]", | |
"name": "[variables('slotName')]", | |
"properties": { | |
"enabled": true, | |
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]" | |
}, | |
"type": "Microsoft.Web/sites/slots", | |
"resources": [ | |
{ | |
"name": "appsettings", | |
"type": "config", | |
"apiVersion": "2015-08-01", | |
"dependsOn": [ | |
"[resourceId('Microsoft.Web/sites/slots', variables('slotName'))]" | |
], | |
"tags": { | |
"displayName": "AppSettings" | |
}, | |
"properties": { | |
//Important: when adding new App Setting, you need to add them to the production slot | |
"DisableAllFunctions": "true", //note this setting is slot specifc | |
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('websiteStorageAccountName'), ';AccountKey=', listKeys(variables('websiteStorageAccountid'),'2015-05-01-preview').key1)]", | |
"AzureWebJobsDashboard": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('functionsStorageAccountName'), ';AccountKey=', listKeys(variables('functionsStorageAccountid'),'2015-05-01-preview').key1)]", | |
"FUNCTIONS_EXTENSION_VERSION": "~1", | |
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2014-04-01').InstrumentationKey]" | |
} | |
} | |
] | |
} | |
] | |
} |
Thanks @delta25 - I appreciate it. I have fixed this up.
I would like to ask you a few things, so I'm going to reference a lines as groups here.
From line 89-161 it appears that you're deploying a function app with two resources. One of those resource has the type "config" and name "slotConfigNames", on lines 127-142. Lines 143-159 appear to already configure the properties. What is the purpose of this resource being defined?
Lines 162-196 deploy the staging slot for the function app. This resource deployment doesn't have the same resource defined like in the production slot on lines 127-142.
Another question...couldn't you just embed the resource defined on lines 162-196 under the existing "resources" array in the production app? According to the schema documentation for the Sites template, you can provide a "slot" resource in the Microsoft.Web/sites object.
From line 89-161 it appears that you're deploying a function app with two resources. One of those resource has the type "config" and name "slotConfigNames", on lines 127-142. Lines 143-159 appear to already configure the properties. What is the purpose of this resource being defined?
I'm not sure if I fully understand your question, but here is what each each groups of line objective:
Line 89-96 is the Function App (a type of App Service).
Line 97-118 are the Function App's properties
Lines 128-142 is the Function Apps slot configuration
Lines 143-159 is the Function App's app settings
Lines 162-196 deploy the staging slot for the function app. This resource deployment doesn't have the same resource defined like in the production slot on lines 127-142.
Yes - the point is to keep the production slot online.. This is explained in my related blog post https://andypalmer.dev/posts/automated-deployment-of-azure-functions-arm-templates/
Another question...couldn't you just embed the resource defined on lines 162-196 under the existing "resources" array in the production app? According to the schema documentation for the Sites template, you can provide a "slot" resource in the Microsoft.Web/sites object.
This sounds like it could work.
Thanks for this. Just want to point out that you have a tiny error in line 181. You're hardcoding the name 'staging' but throughout the rest of the template you're making use of a variable.