ARM Incremental deployment mode

Viewed 40

Consider I have an Azure Function App with some app settings and some functions created via the following YAML task:

 - task: AzureResourceManagerTemplateDeployment@3
  displayName: 'deploy resources'
  inputs:
    azureResourceManagerConnection: azureResourceManagerConnection
    subscriptionId:subscriptionId
    resourceGroupName: rg
    location:location
    csmFile: template.bicep
    csmParametersFile:parameters.json              
    deploymentMode: 'Incremental'

Let’s say I modified app settings.

If I run the above YAML task in Incremental deployment mode, does that recreate the Azure Function App with the modified app settings and functions or does it just update the app settings - Function app and existing functions stay the same?

Here is how my template.bicep looks like:

var appSettings = [
  {
    name: 'WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG'
    value: 1
  }
  {
    name: 'WEBSITE_ENABLE_SYNC_UPDATE_SITE'
    value: 1
  }
  {
    name: 'SCM_TOUCH_WEBCONFIG_AFTER_DEPLOYMENT'
    value: 0
  }
  {
    name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
    value: reference(resourceId(appInsightsResourceGroup, 'microsoft.insights/components/', appInsightsName), '2015-05-01').InstrumentationKey
  }
  {
    name: 'AzureWebJobsStorage'
    value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${listKeys(resourceId(storageAccountResourceGroup, 'Microsoft.Storage/storageAccounts', storageAccountName), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value}'
  }
  {
    name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
    value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${listKeys(resourceId(storageAccountResourceGroup, 'Microsoft.Storage/storageAccounts', storageAccountName), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value}'
  }
  {
    name: 'FUNCTIONS_WORKER_RUNTIME'
    value: 'dotnet'
  }
  {
    name: 'FUNCTIONS_EXTENSION_VERSION'
    value: '~4'
  }
  {
    name: 'WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT'
    value: maximumElasticWorkerCount
  }
  {
    name: 'appConfigurationEndpoint'
    value: appConfigurationEndpoint
  }
  {
    name: 'membershipStorageAccountName'
    value: '@Microsoft.KeyVault(SecretUri=${reference(membershipStorageAccountName, '2019-09-01').secretUriWithVersion})'
  }
  {
    name: 'membershipContainerName'
    value: '@Microsoft.KeyVault(SecretUri=${reference(membershipContainerName, '2019-09-01').secretUriWithVersion})'
  }
]

var stagingSettings = [
  {
    name: 'WEBSITE_CONTENTSHARE'
    value: toLower('functionApp-staging')
  }
  {
    name: 'AzureFunctionsJobHost__extensions__durableTask__hubName'
    value: '${solutionAbbreviation}compute${environmentAbbreviationStaging}'
  }
  {
    name: 'AzureWebJobs.StarterFunction.Disabled'
    value: 1
  }
]

var productionSettings = [
  {
    name: 'WEBSITE_CONTENTSHARE'
    value: toLower('functionApp')
  }
  {
    name: 'AzureFunctionsJobHost__extensions__durableTask__hubName'
    value: '${solutionAbbreviation}compute${environmentAbbreviation}'
  }
  {
    name: 'AzureWebJobs.StarterFunction.Disabled'
    value: 0
  }
]

module functionAppTemplate 'functionApp.bicep' = {
  name: 'functionAppTemplater'
  params: {
    name: '${functionAppName}'
    kind: functionAppKind
    location: location
    servicePlanName: servicePlanName
    dataKeyVaultName: dataKeyVaultName
    dataKeyVaultResourceGroup: dataKeyVaultResourceGroup
    secretSettings: union(appSettings, productionSettings)
  }
  dependsOn: [
    servicePlanTemplate
  ]
}

module functionAppSlotTemplate 'functionAppSlot.bicep' = {
  name: 'functionAppSlotTemplate'
  params: {
    name: '${functionAppName}/staging'
    kind: functionAppKind
    location: location
    servicePlanName: servicePlanName
    dataKeyVaultName: dataKeyVaultName
    dataKeyVaultResourceGroup: dataKeyVaultResourceGroup
    secretSettings: union(appSettings, stagingSettings)
  }
  dependsOn: [
    functionAppTemplate
  ]
}
functionapp.bicep

resource functionApp 'Microsoft.Web/sites@2018-02-01' = {
  name: name
  location: location
  kind: kind
  properties: {
    serverFarmId: resourceId('Microsoft.Web/serverfarms', servicePlanName)
    clientAffinityEnabled: false
    httpsOnly: true
    siteConfig: {
      use32BitWorkerProcess : false
      appSettings: secretSettings
    }
  }
  identity: {
    type: 'SystemAssigned'
  }
}
functionAppSlot.bicep

resource functionAppSlot 'Microsoft.Web/sites/slots@2018-11-01' = {
  name: name
  kind: kind
  location: location
  properties: {
    clientAffinityEnabled: true
    enabled: true
    httpsOnly: true
    serverFarmId: resourceId('Microsoft.Web/serverfarms', servicePlanName)
    siteConfig: {
      use32BitWorkerProcess : false
      appSettings: secretSettings
    }
  }
  identity: {
    type: 'SystemAssigned'
  }
}
1 Answers

Your Function App will not be recreated. Only the state or values which does not match the desired state are changed.

This means, if you change a setting e.g. FUNCTIONS_EXTENSION_VERSION in the bicep file, it will be changed in the Function App settings.

https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/overview

Repeatable results: Repeatedly deploy your infrastructure throughout the development lifecycle and have confidence your resources are deployed in a consistent manner. Templates are idempotent, which means you can deploy the same template many times and get the same resource types in the same state. You can develop one template that represents the desired state, rather than developing lots of separate templates to represent updates.

Related