We have a Azure DevOps pipeline that first deploys our resources using ARM-templates and then deploys our AppServices using zips. We've run the pipeline multiple times, and the application is correctly running.
Sometime after in another deployment attempt - the first deployment step (of the resources) fails. The changes in the deployment do not contain any changes to the AppService. And the failed part is not the AppService (but instead say our database), the AppService still becomes unavailable. And it looks like it has reset to the deafult hosting settings. It seems the previous deployments are still available in the "/data/SitePackages" folder, but the "/site/wwwroot" folder contains only the default "hostingstart.html" file.
My understanding from an incremental deployment is that if the AppService is unchanged it should keep all it's settings! (And thus it's previous deployment active.)
Is this default behaviour? Can we somehow keep the previous App running when part of the deployment fails? Do we need to choose another deployment strategy?
Our pipeline looks something like this;
jobs:
- deployment: 'Deploy'
environment: '${{ parameters.environment }}' # The environment to use in Azure Devops (controls the required approvals)
variables:
- template: '../variables/deploy-variables.yml'
parameters:
environment: '${{ parameters.environment }}'
strategy:
runOnce:
deploy:
steps:
- task: AzureResourceManagerTemplateDeployment@3
displayName: 'Azure - Deploy resources'
inputs:
deploymentScope: 'Resource Group'
azureResourceManagerConnection: '${{ parameters.azureServiceConnection }}'
subscriptionId: '$(azureSubscriptionId)'
action: 'Create Or Update Resource Group'
resourceGroupName: '$(resourceGroup)'
location: 'West Europe'
templateLocation: 'Linked artifact'
csmFile: '$(Pipeline.Workspace)/drop-resources/files/arm/resources/azuredeploy.json'
csmParametersFile: '$(Pipeline.Workspace)/drop-resources/files/arm/resources/azuredeploy.parameters.json'
deploymentMode: 'Incremental'
- task: AzureWebApp@1
displayName: 'Deploy Service'
inputs:
azureSubscription: '${{ parameters.azureServiceConnection }}'
appName: '$(serviceName)'
package: '$(Pipeline.Workspace)/drop-app/archives/Service.zip'
This is expected. Your pipeline is doing two things, deploying the app service, then deploying your app. If the first part succeeds it deploys an app service with default files, if your second step fails then it will be left in that state.
This should only happen on first deployment. If you run a subsequent deployment where the first step succeeds it will not overwrite the existing files in the web app, it will leave them as is. If your second step fails then the old files should still be there, unless your second step failed part way through and overwrote some of the files.
If you want to ensure you have an option to roll back to the previous version even if the files do get overwritten then you should look at using deployment slots.
I've solved the issue myself by adding the following app-settings to the resource (arm) deployment;
This keeps the current package as active, previously these app-settings we're removed while the package was still available.