How can we add new host key in Function App using ARM-template - arm-template

what app setting property needs to be added so that new host key will be generated using ARM Template
"appSettings": [
{
"name": "AzureWebJobsDashboard",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~1"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "6.5.0"
},
{
"name": "ConfigurationStorageAccount",
"value": "[variables('storageAccountName')]"
},
{
"name": "ConfigurationStorageAccountKey",
"value": "[listKeys(variables('storageAccountid'),'2015-05-01-preview').key2]"
}
]

Currently it's not possible to create keys directly from the template. But you can create keys using Powershell / .NET whatever way you are using to deploy the template. Since the KEY MANAGEMENT API is just REST.
you can call the below API in your Powershell script to add a new key:
PUT api/sites/{name}[/slots/{slot}]/host/default/{functionkeys|systemkeys}/{keyName}
{
"properties": {
"name":"<keyName>",
"value":<keyValue>"
}
}
More Docs - Github

Related

Azure resources created using custom provider not showing on azure portal

I created an Azure custom provider by following the documentation in the link below:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/custom-providers/
I am able to successfully create resources for the types defined in the custom provider using ARM templates. However, I do not see those resources on the azure portal under the specific resource group.
Is this behavior expected?
I have deployed the custom provider in azure portal using ARM template by following below steps
Open azure portal and search for custom deployment as below
Taken reference from Microsoft Doc
After opening custom deployment, i have used the below code and then click on save
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"funcName": {
"type": "string",
"defaultValue": "[uniqueString(resourceGroup().id)]",
"metadata": {
"description": "The unique name of the function application"
}
},
"storageName": {
"type": "string",
"defaultValue": "[concat('store', uniquestring(resourceGroup().id))]",
"metadata": {
"description": "The unique name of the storage account."
}
},
"location": {
"type": "string",
"defaultValue": "eastus",
"metadata": {
"description": "The location for the resources."
}
},
"zipFileBlobUri": {
"type": "string",
"defaultValue": "https://github.com/Azure/azure-docs-json-samples/blob/master/custom-providers/_artifacts/functionpackage.zip?raw=true",
"metadata": {
"description": "The URI to the uploaded function zip file"
}
}
},
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-03-01",
"name": "[parameters('funcName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"identity": {
"type": "SystemAssigned"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]"
],
"properties": {
"name": "[parameters('funcName')]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsDashboard",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2022-05-01').keys[0].value)]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2022-05-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2022-05-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('funcName'))]"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "6.5.0"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "[parameters('zipFileBlobUri')]"
}
]
},
"clientAffinityEnabled": false,
"reserved": false
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2022-05-01",
"name": "[parameters('storageName')]",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "Standard_LRS"
}
},
{
"type": "Microsoft.CustomProviders/resourceProviders",
"apiVersion": "2018-09-01-preview",
"name": "[parameters('funcName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Web/sites/',parameters('funcName'))]"
],
"properties": {
"actions": [
{
"name": "ping",
"routingType": "Proxy",
"endpoint": "[concat('https://', parameters('funcName'), '.azurewebsites.net/api/{requestPath}')]"
}
],
"resourceTypes": [
{
"name": "users",
"routingType": "Proxy,Cache",
"endpoint": "[concat('https://', parameters('funcName'), '.azurewebsites.net/api/{requestPath}')]"
}
]
}
},
{
"type": "Microsoft.CustomProviders/resourceProviders/users",
"apiVersion": "2018-09-01-preview",
"name": "[concat(parameters('funcName'), '/ana')]",
"location": "parameters('location')",
"dependsOn": [
"[concat('Microsoft.CustomProviders/resourceProviders/',parameters('funcName'))]"
],
"properties": {
"FullName": "Ana Bowman",
"Location": "Moon"
}
}
],
"outputs": {
"principalId": {
"type": "string",
"value": "[reference(concat('Microsoft.Web/sites/', parameters('funcName')), '2022-03-01', 'Full').identity.principalId]"
}
}
}
Fill the following details like Subscription id, resource group, location and click on review+create
After deploying into the azure portal, we will get below
After deploying it to azure poral Goto azure portal and click on your resource group and click on the check box you will find as below

Upload Key Vault Certificate and access it in App Service through ARM Template

We need to have a Function App created for accessing Office 365 instance. The access is using Certificate authentication. Hence we are uploading the certificate into Azure Key Vault and need to import the Certificate from Key Vault.
We are using ARM Templates for the Azure Resource Deployment. We are trying to create Azure Key Vault Certificate as mentioned in the link
https://erwinstaal.nl/posts/using-an-arm-template-to-deploy-your-ssl-certificate-stored-in-keyvault-on-an-web-app/
upload .pfx certificate through azure devops pipeline
As mentioned in the above pages, we are able to create new secrets in Key Vault. But, we do not see the imported certificate in the list of Certificates (when checked in the Azure Portal UI) and also, we are not able to Import the Certificates in the Function App. Is this not supported in the current ARM Template Key Vault commandlet? How can this be fixed?
As mentioned in the above pages, we are able to create new secrets in
Key Vault. But, we do not see the imported certificate in the list of
Certificates (when checked in the Azure Portal UI)
This is because ARM Template doesn't have a property to upload a certificate so instead it stores a base64 encoded value of the PFX certificate in the Secret in a application/x-pkcs12 like below :
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVault": {
"type": "string",
"defaultValue" :"funccertimporttestkv"
},
"TestCedential_1": {
"type": "secureString",
"defaultValue":"MIIKYAIBAzCCChwXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXhp4XPejOrOIgc9/6dkfBBSgxY73wtbf+G3N7KTYP1LKKHS0YwICB9A="
},
"TestCedentialName_1": {
"type": "string",
"defaultValue": "funcAppValidationCert"
}
},
"variables": {
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('keyVault'), '/', parameters('TestCedentialName_1'))]",
"apiVersion": "2015-06-01",
"properties": {
"contentType": "application/x-pkcs12",
"value": "[parameters('TestCedential_1')]"
}
}
],
"outputs": {}
}
we are not able to Import the Certificates in the Function App. Is
this not supported in the current ARM Template Key Vault commandlet?
How can this be fixed?
If you are using a template like below :
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"envName": {
"defaultValue": "qa",
"type": "String"
},
"certificateName": {
"type": "string",
"defaultValue": "funcAppValidationCert"
},
"domainName": {
"type": "string",
"defaultValue": "localhost"
},
"keyvaultName": {
"type": "string",
"defaultValue": "funccertimporttestkv"
},
"password": {
"type": "string",
"defaultValue": "Password#1234"
}
},
"variables":{
"functionStorageAccountName" :"[concat('storaccfn',parameters('envName'),resourceGroup().location)]",
"appServicePlanName" :"[concat('plan-myapp-',parameters('envName'),resourceGroup().location)]",
"sitesFunctionAppName" :"[concat('func-ans-',parameters('envName'),resourceGroup().location)]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[variables('functionStorageAccountName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "Storage",
"properties": {
"supportsHttpsTrafficOnly": true
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('appServicePlanName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "S1",
"tier": "Standard",
"size": "S1",
"family": "S",
"capacity": 1
},
"kind": "app",
"properties": {
"perSiteScaling": false,
"maximumElasticWorkerCount": 1,
"isSpot": false,
"reserved": false,
"isXenon": false,
"hyperV": false,
"targetWorkerCount": 0,
"targetWorkerSizeId": 0
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('sitesFunctionAppName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('functionStorageAccountName'))]"
],
"kind": "functionapp",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"enabled": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
"httpsOnly": true,
"siteConfig": {
"appSettings":[
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('functionStorageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionStorageAccountName')),'2017-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('functionStorageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionStorageAccountName')),'2017-06-01').keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('sitesFunctionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "1"
},
{
"name": "WEBSITE_TIME_ZONE",
"value": "UTC"
}
]
}
}
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2016-08-01",
"name": "[concat(variables('sitesFunctionAppName'), '/', parameters('domainName'))]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/certificates', parameters('certificateName'))]",
"[resourceId('Microsoft.Web/sites', variables('sitesFunctionAppName'))]"
],
"properties": {
"siteName": "[variables('sitesFunctionAppName')]",
"hostNameType": "Verified",
"sslState": "SniEnabled",
"thumbprint": "[reference(resourceId('Microsoft.Web/certificates', parameters('certificateName'))).Thumbprint]"
}
},
{
"type": "Microsoft.Web/certificates",
"name": "[parameters('certificateName')]",
"apiVersion": "2016-03-01",
"location": "[resourceGroup().location]",
"properties": {
"keyVaultId": "[resourceId('Microsoft.KeyVault/vaults', parameters('keyvaultName'))]",
"keyVaultSecretName": "[parameters('certificateName')]",
"password": "[parameters('password')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
},
"dependsOn":[
"[resourceId('Microsoft.Web/sites', variables('sitesFunctionAppName'))]"
]
}
]
}
And facing a Problem of Bad Request which says not able to access the keyvault like below:
Then Add Microsoft.Azure.CertificateRegistration (i.e. ObjectId : ed47c2a1-bd23-4341-b39c-f4fd69138dd3) , Microsoft Azure App Service (Internal) (i.e. ObjectId : 505e3754-d8a9-4f8b-97b6-c3e48ac7a543) & Microsoft Azure App Service (i.e. ObjectId : f8daea97-62e7-4026-becf-13c2ea98e8b4) in access policy for keyvault.
And If you get the below after solving the above then please check if you have converted the certificate value to a proper base64 encoded value.
Then you can refer this SO thread to properly provide a base64 value of the certificate.
Output:
After successful deployment you can see this TLS/SSL settings :

How to use .NET Core 3.x with Azure Function App Powershell Runtime?

I have created a new Function App using the below resource in my template:
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
"name": "[parameters('caAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"identity": {
"type": "SystemAssigned"
},
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('caAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~3"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~10"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "powershell"
},
]
}
}
I run the below code in the function app in the portal Write-Host "$([System.Security.Cryptography.X509Certificates.X509Certificate2].Assembly.Location)"
I get D:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.8\System.Security.Cryptography.X509Certificates.dll
But if I use the Function App console:
D:\Program Files\dotnet\shared\Microsoft.NETCore.App> ls
2.2.8
2.2.8.installed
3.0.3
3.0.3.installed
3.1.3
3.1.3.installed
So 3.1.3 is present, but the function is not executing with it.
I only even noticed because I tried to use System.Security.Cryptography.PbeParameters and the type is missing (along with some other AsymmetricAlgorithm stuff)
How do I resolve this?
The .NET Core version is determined by the Azure PowerShell worker, which depends on the PowerShell SDK. PowerShell 6 is the only version currently available in Azure Functions, and it depends on .NET Core 2.x, this is why your PowerShell Function is executed in this context. In order to use .NET Core 3.x, you have the following options:
recommended: wait for PowerShell 7 support in Azure Functions (expected to be deployed within the next 2-4 weeks);
spawn a separate executable from your PowerShell function.

Deploy Azure Function with ARM template

I am trying to deploy Azure Function with ARM template , but I am not able to create the function itself. Is it possible to create the actual function using ARM template?
I have zipped the source code for the function and placed it in a public location, I have added the MSBuild section to the template and although the deployment finished successfully - the App function was created but not the function itself
here is the template
{
"parameters": {
"name": {
"type": "string"
},
"storageName": {
"type": "string"
},
"location": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"storage_account_endpoint": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2016-03-01",
"name": "[parameters('name')]",
"type": "Microsoft.Web/sites",
"properties": {
"name": "[parameters('name')]",
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[concat(toLower(parameters('name')), 'bd58')]"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "8.11.1"
},
{
"name": "storage_account_connection",
"value": "[parameters('storage_account_endpoint')]"
}
]
},
"clientAffinityEnabled": false,
"reserved": false
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]"
],
"resources": [
{
"name": "MSDeploy",
"type": "Extensions",
"apiVersion": "2015-02-01",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('name'))]"
],
"properties": {
"packageUri": "<URL to zip>"
}
}
],
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned"
},
"kind": "functionapp"
},
{
"apiVersion": "2015-05-01-preview",
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageName')]",
"location": "[parameters('location')]",
"properties": {
"accountType": "Standard_LRS"
}
}
],
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0"
}
In short No - ARM can only create the infrastructure for you but not deploy the code (**see comment).
But as always there is a way. A while back MS release a new feature 'Run from ZIP' on web apps (including Function Apps). All you need is the actual project (code published as ZIP) to be in a location where the function app can access it.
We use VSTS (Azure Dev Ops) for CI/CD. So we build the solution add the ZIP to the artifact. Then in the Release we copy the ZIP to blob storage, create a SAS Token and pass the location of the blob Container with the SAS Token to ARM. In the ARM template we build the connection string to the ZIP, using input parameter. As soon as ARM is done then the Function is up and running.
Eg.
{
"parameters": {
"name": {
"type": "string"
},
"storageName": {
"type": "string"
},
"location": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"storage_account_endpoint": {
"type": "string"
},
"artifactsUri": {
"type": "string"
},
"artifactsBlobContainer": {
"type": "string"
},
"artifactsLocationSasToken": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2016-03-01",
"name": "[parameters('name')]",
"type": "Microsoft.Web/sites",
"properties": {
"name": "[parameters('name')]",
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[concat(toLower(parameters('name')), 'bd58')]"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "8.11.1"
},
{
"name": "storage_account_connection",
"value": "[parameters('storage_account_endpoint')]"
},
{
"name": "WEBSITE_RUN_FROM_ZIP",
"value": "[concat(parameters('artifactsUri'), '/', parameters('artifactsBlobContainer'),'/','blahbla.FA.zip',parameters('artifactsLocationSasToken'))]"
}
]
},
"clientAffinityEnabled": false,
"reserved": false
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]"
],
"resources": [
{
"name": "MSDeploy",
"type": "Extensions",
"apiVersion": "2015-02-01",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('name'))]"
],
"properties": {
"packageUri": "<URL to zip>"
}
}
],
"location": "[parameters('location')]",
"identity": {
"type": "SystemAssigned"
},
"kind": "functionapp"
},
{
"apiVersion": "2015-05-01-preview",
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageName')]",
"location": "[parameters('location')]",
"properties": {
"accountType": "Standard_LRS"
}
}
],
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0"
}
'Run from ZIP' is achieved with the 'WEBSITE_RUN_FROM_ZIP' app setting.
Hope this helps
I just use this FunctionWebDeploy.json template. I download the app content(zip file)from the existing function app and upload it to the public address. Finally I can deploy function app including code.
Go to Azure portal portal.azure.com, and create a new Azure Function.
2.Go to Resource Group.
3.Go to Export template.
4.You will see something like this.
This is the ARM Template for all resources/componets.

Azure function staging slot swap bug when deployed via ARM template

I have created an Azure function app(consumption plan) using ARM template.
After i deploy code and perform a swap operation(VSTS task) both the production and staging slot have the new code. But i expected the staging slot to have the old code after the swap operation, is this a known bug in Azure functions ? Or do i have to do anything extra
"resources": [
{
"name": "CampaignSyncJob",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2016-09-01",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('artifactsLocation'), '/', variables('linkedTemplateFolderName'), '/', variables('webAppTemplateFileName'), parameters('artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"appServicePlanName": {
"value": "[reference('ReleaseParams').outputs.webApp.value.appServicePlanName]"
},
"appServiceName": {
"value": "[reference('ReleaseParams').outputs.webApp.value.appServiceName]"
},
"artifactsLocation": {
"value": "[parameters('artifactsLocation')]"
},
"artifactsLocationSasToken": {
"value": "[parameters('artifactsLocationSasToken')]"
},
"packageFolder": {
"value": "CampaignSyncJob"
},
"packageFileName": {
"value": "package.zip"
},
"appSettings": {
"value": {
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]",
"WEBSITE_CONTENTSHARE": "[toLower(variables('appServiceName'))]",
"FUNCTIONS_EXTENSION_VERSION": "~2",
"WEBSITE_NODE_DEFAULT_VERSION": "6.5.0",
"MSDEPLOY_RENAME_LOCKED_FILES": "1",
"AppInsights_InstrumentationKey": "[variables('appInsightsInstrumentationKey')]",
"StickySetting": "StuckToProduction1"
}
},
"slotAppSettings": {
"value": {
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]",
"WEBSITE_CONTENTSHARE": "[toLower(variables('appServiceName'))]",
"FUNCTIONS_EXTENSION_VERSION": "~2",
"WEBSITE_NODE_DEFAULT_VERSION": "6.5.0",
"MSDEPLOY_RENAME_LOCKED_FILES": "1",
"AppInsights_InstrumentationKey": "[variables('appInsightsInstrumentationKey')]",
"StickySetting": "StuckToStaging1"
}
},
"slotName": {
"value": "[reference('ReleaseParams').outputs.webApp.value.appServiceSlotName]"
},
"appServiceLocation": {
"value": "[reference('ReleaseParams').outputs.common.value.location]"
},
"slotSpecificAppSettingKeys": {
"value": [
"StickySetting"
]
}
}
}
},
Linked template which deploys the function app
{
"condition": "[parameters('deployOnStagingSlot')]",
"apiVersion": "2015-08-01",
"name": "[concat(parameters('appServiceName'), '/', parameters('slotName'))]",
"type": "Microsoft.Web/sites/slots",
"location": "[parameters('appServiceLocation')]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
},
"dependsOn": [
],
"resources": [
{
"condition": "[parameters('deployOnStagingSlot')]",
"name": "appsettings",
"type": "config",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('appServiceName'), '/slots/', parameters('slotName'))]",
"[concat('Microsoft.Web/sites/', parameters('appServiceName'), '/slots/', parameters('slotName'), '/Extensions/MSdeploy')]"
],
"properties": "[parameters('slotAppSettings')]"
},
{
"condition": "[parameters('deployOnStagingSlot')]",
"name": "MSDeploy",
"type": "extensions",
"location": "[parameters('appServiceLocation')]",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('appServiceName'), '/slots/', parameters('slotName'))]"
],
"properties": {
"packageUri": "[concat(parameters('artifactsLocation'), '/', parameters('packageFolder'), '/', parameters('packageFileName'), parameters('artifactsLocationSasToken'))]",
"setParameters": {
"IIS Web Application Name": "[parameters('slotName')]"
}
}
}
]
}
Hmm, I know that for swapping slots within a functions app it is required to change app setting WEBSITE_CONTENTSHARE to a slot specific setting.
For this solution and other ARM issues regarding multiple slots, check out the blog of Gary Lumsden

Resources