Azure Functions ARM Template deploy deletes Functions - azure

I've got an ARM template (included below) to deploy an Azure Function App. I deploy it with:
az group deployment create --resource-group my-group --template-file my-function-app.json
This works and I can then deploy my functions successfully using the VS Code plugin or Azure Functions Core Tools.
However, if I then re-deploy the ARM template (for example to update an application setting) then I lose my functions and need to re-deploy them again. Is this expected behaviour? It's not what I observe when deploying e.g. a Web App via an ARM template. Is there something specific I can do when deploying an ARM template for a Function App to preserve my deployed functions?
my-function-app.json:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
...
},
"variables": {
...
},
"resources": [
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
"name": "[variables('collectorFunctionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"siteConfig": {
"appSettings": [
{
...
}
]
}
}
}
],
"outputs": {}
}

Are you deploying your function as a package? If so, make sure you set this setting in your template, since it will be removed when you redeploy otherwise:
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "1"
}

You could try "--mode incremental" parameter although that should be the default when it is not provided.

Yes that should be the expected behavior.
ARM Template is a declarative deployment meaning anytime you deploy it will overwrite anything you have with new template information. The template should always include everything you need.

Related

Automatically create an Azure DevOps Organization with an ARM Template

Since it is not possible to create an organization with the DevOps Rest API and the SDK for organizations is still in preview and not functional, we currently try to programmatically create an organization with an ARM template.
In the Azure Portal, it is possible to create a new organization with an ARM template like this:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/Microsoft.Resources.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"organizationName": {
"type": "string",
"defaultValue": ""
},
"organizationIdentifier": {
"type": "string",
"defaultValue": ""
},
"administrator": {
"type": "string",
"defaultValue": ""
}
},
"resources": [
{
"name": "[parameters('organizationIdentifier')]",
"type": "microsoft.visualstudio/account",
"location": "West Europe",
"description": "[parameters('organizationName')]",
"apiVersion": "2014-02-26",
"properties": {
"operationType": "Create",
"accountName": "[parameters('organizationIdentifier')]",
"ownerUpn": "[parameters('administrator')]"
}
}
]
}
Unfortunately we couldn't find a solution to create this within a C# Azure Function programmatically, since the SDK would want a resource group, which doesn't make sense in this context. Is there a way to do this or is it simply not possible to create an organization automatically at this point?
Yes, as of now there is no ways to create an DevOps organization using REST API.
The way to create Azure DevOps Organization is Manual creation or using ARM Template.
Using ARM Template, you have to specify the Resource name as a parameter. That is also we need to mention the Organization Name before deploying the ARM Template.
As of now the REST API is available for some of the services.
References
-Automating organization and project creation in Azure DevOps Blog gives the clear view

Parallel deployment of Azure AppService using ARM template

I am trying to solve a use-case of deploying 20 to 30 Azure AppServices using ARM template based on Admin decision.
This is happening through c# webapi using Microsoft Fluent library(Microsoft.Azure.Management.Fluent & Microsoft.Azure.Management.ResourceManager.Fluent),
var creds = new AzureCredentialsFactory().FromServicePrincipal(clientId,
clientSecret,
tenantId,
AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);
var deployment = azure.Deployments.Define($"deployment-{userName}")
.WithExistingResourceGroup(resourceGroupName)
.WithTemplate(templateJson.ToString())
.WithParametersLink(templateParamsBlobURL, "1.0.0.0")
.WithMode(Microsoft.Azure.Management.ResourceManager.Fluent.Models.DeploymentMode.Incremental)
.Create();
Problem statement
When the admin decides to run 20 AppServices, then the above lines of code will execute and provision these AppServices, the decision is based on admin.
For me the Deployment is happening in sequential manner i.e., upon completing one AppService deployment then it triggers the next AppService deployment, which takes huge time to complete the entire operation. I am trying to achieve the deployment of 20 AppServices(decided by admin) in parallel so that the provisioning completes at the earliest
Kindly assist me on how to achieve the parallel deployment of AppServices using ARM template
Thanks for confirming #Guptha, posted the same as an answer to help other community members for the similar query , To iteration multiple resources at a time in ARM TEMPLATE .
Use your Azure Resource Manager template to create multiple instances
of a resource (ARM template). You can dynamically set the quantity of
resources to deploy by adding a copy loop to the resources section of
your template.
For example to create multiple storage accounts ;
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageCount": {
"type": "int",
"defaultValue": 3
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage",
"properties": {},
"copy": {
"name": "storagecopy",
"count": "[parameters('storageCount')]"
}
}
]
}
For complete setup please refer this MICROSOFT DOCUMENTATION|Resource iteration in ARM templates

How can I use slotted deployments in Azure DevOps for an Azure App Service?

I'm having some problems with slotted deployments in Azure DevOps. The problem is that my app goes down during deployment. But once the deployment finishes, it comes up again.
My app comes with an azuredeploy.json file: https://pastebin.com/CPVzE5hM.
While trying to access my web app once it is deploying, it seems to go down at the first step:
Azure Deployment: Create Or Update Resource Group acti...
There are usually no changes to the azuredeploy.json file, so I don't understand why it goes down at this step. There is nothing to create -- it exists before, and there is nothing to update either.
I have set up the slots manually in Azure Portal. The deployment mode is incremental.
How can I use slotted deployments in Azure DevOps for an Azure App Service?
According to your description, we need to create new deployment slot for an existing WebApp.
So, we need to check if we create or update for the new deployment slot instead of the Production:
{
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"siteName": {
"type": "string"
},
"slotName": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2015-04-01",
"type": "Microsoft.Web/Sites/Slots",
"name": "[concat(parameters('siteName'), '/', parameters('slotName'))]",
"location": "[resourceGroup().location]",
"properties": {},
"resources": []
}
]
}
The template on GitHub.
You could check the document this, this and the similar thread for some more details. If this not resolve this issue, please share your json file to use.

Handling dependencies in Azure Resource Manager Linked Templates

Azure Resource Manager (ARM) Templates have the ability to use Linked Templates. These linked templates can define additional resources to create during an ARM template deployment.
ARM templates support dependencies which ensure some resources are created before others are.
I would like to specify a dependency in a linked template for a resource created in the master template. If I include the dependency in the Linked Template, it looks like this:
"resources": [
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites/hostNameBindings",
"name": "[concat(parameters('siteName'),'/', parameters('fqdn'))]",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('siteName'))]"
],
"properties": {
"siteName": "[parameters('siteName')]"
}
}
]
While the dependsOn appears correct, the a resource is created at Microsoft.Web/sites/{siteNameParameter}, deploying the ARM template outputs the following error message:
InvalidTemplate : Deployment template validation failed: 'The resource 'Microsoft.Web/sites/blahblahblahblah' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.
I am currently defining this dependency in the master template when I define the linked template call. This seems brittle and easy to break. Is there a better way than defining dependencies in the master ARM template?
{
"apiVersion": "2015-01-01",
"name": "SomeName",
"type": "Microsoft.Resources/deployments",
"dependsOn": [
"[concat('Microsoft.Web/sites/', parameters('siteName'))]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "https://tempuri.org/supersecrettemplatepath/azuredeploy.json",
"contentVersion": "1.0.0.0"
},
"parameters":
{
"fqdn": {
"value": "www.tempuri.org"
},
"siteName": {
"value": "[parameters('siteName')]"
}
}
}
}
You can define the dependency either way - both are valid. Putting the dependency on the deployment resource (your second approach) will mean that the entire nested deployment is not started until the web site is provisioned. If you wanted to kick some things off in parallel, then you would put the dependency in the nested template (your first approach). That may or may not matter for your scenario, but that's a key difference.
dependsOn requires a resourceId - and as the error is trying to say, if the resource is not defined in the template you need more detail in the resourceId, in this case, you need the resourceGroup (maybe the subscription, but I doubt it). So for example you can use:
"dependsOn": [
"[resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('siteName'))]"
],
The dependsOn needs the name of the linked deployment, not one of the resources in it.
e.g.:
dependsOn: "Microsoft.Resources/deployments/myExternalTemplate"
"dependsOn": [
"[resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Web/sites', parameters('siteName'))]"
],

Azure ARM Templates to deploy WebJobs

Everyone,
Could anyone please help me on deploying WebJobs using ARM Templates ?
Thanks,
Rajaram.
A template shared by David Ebbo shows how to deploy Webjobs using Arm Templates.
In this template, a triggered webjob is linked to a website deployed by the same template. A webjob is a part of a jobCollection. This jobCollection is linked to it's parent website using the "dependsOn" node.
{
"apiVersion": "2014-08-01-preview",
"name": "[parameters('jobCollectionName')]",
"type": "Microsoft.Scheduler/jobCollections",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
],
"location": "[parameters('siteLocation')]",
"properties": {
"sku": {
"name": "standard"
},
"quota": {
"maxJobCount": "10",
"maxRecurrence": {
"Frequency": "minute",
"interval": "1"
}
}
},
"resources": [
{
"apiVersion": "2014-08-01-preview",
"name": "DavidJob",
"type": "jobs",
"dependsOn": [
"[resourceId('Microsoft.Scheduler/jobCollections', parameters('jobCollectionName'))]"
],
"properties": {
"startTime": "2015-02-10T00:08:00Z",
"action": {
"request": {
"uri": "[concat(list(resourceId('Microsoft.Web/sites/config', parameters('siteName'), 'publishingcredentials'), '2014-06-01').properties.scmUri, '/api/triggeredjobs/MyScheduledWebJob/run')]",
"method": "POST"
},
"type": "http",
"retryPolicy": {
"retryType": "Fixed",
"retryInterval": "PT1M",
"retryCount": 2
}
},
"state": "enabled",
"recurrence": {
"frequency": "minute",
"interval": 1
}
}
}
]
}
Regards,
The other answers cover the template aspect of getting the job created in Azure, but there's still the question of getting the webjob executable uploaded.
Assuming this deploy is part of a larger Azure website deploy, you simply need to include your webjob executable in the distribution of your website.
Per the kudu documentation the convention for placing your EXE is as follows:
To deploy a triggered job copy your binaries to: app_data\jobs\triggered\{job name}
To deploy a continuous job copy your binaries to: app_data\jobs\continuous\{job name}
Azure scheduler became obsolete on december 2019, after that, all Scheduler job collections and jobs stopped running, that is why Scheduler Job Collection in not usable anymore, Azure logic apps should be used instead.
-Migrate Azure WebJobs from Azure Scheduler to Azure Logic Apps.
Here's an Azure QuickStart Template that deploys an Azure Web App with a Schedule Job.
Additionally, have you looked at the Visual Studio 2015 Azure SDK support for the Azure Resource Manager project type? It contains UI for more easily authoring ARM Templates directly from within Visual Studio.

Resources