Azure App Service deploy task option to remove files in container upon deployment

Viewed 5372

I am deploying a python web app using Web App on Linux service and using a DevOps release pipeline. The pipeline task that I am using is called AzureRmWebAppDeployment@4.

Between deployments, the files in the container are not being removed and this is causing issues.

I noticed if I am using a different type of app service (i.e. Web App on Windows) and if the deployment method is set to Web Deploy the option for Remove additional files at destination exists (see screenshot). However we are using a Zip Deploy method and prefer to be using a linux service. without that combination of app service and deployment method, this option is not available to me.

enter image description here

Can anybody suggest an alternate method for deleting the container contents upon deployment? Also, any insight as to why this option is not available through the pipeline task when using Zip Deploy and Linux?

Thanks in advance for any help provided.

2 Answers

You can use kudu command api to clean the wwwroot folder on your webapp server. The kudu command rest api will execute the command in the specified directory on the server.

{
    command = "find . -mindepth 1 -delete"  
    dir = "/home/site/wwwroot
} 

Add an Azure powershell task before Azure app service deploy task, and run below inline scripts.

$ResGroupName = ""
$WebAppName = ""

# Get publishing profile for web application
$WebApp = Get-AzWebApp -Name $WebAppName -ResourceGroupName $ResGroupName
[xml]$publishingProfile = Get-AzWebAppPublishingProfile -WebApp $WebApp

# Create Base64 authorization header
$username = $publishingProfile.publishData.publishProfile[0].userName
$password = $publishingProfile.publishData.publishProfile[0].userPWD
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))

$bodyToPOST = @{  
                  command = "find . -mindepth 1 -delete"  
                  dir = "/home/site/wwwroot"  
}  
# Splat all parameters together in $param  
$param = @{  
            # command REST API url  
            Uri = "https://$WebAppName.scm.azurewebsites.net/api/command"  
            Headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}  
            Method = "POST"  
            Body = (ConvertTo-Json $bodyToPOST)  
            ContentType = "application/json"  
}  
# Invoke REST call  
Invoke-RestMethod @param  

Above scripts will empty the folder /home/site/wwwroot before each deployment.

If you need to delete specific files on the app server, you can use kudu delete rest api:

DELETE /api/vfs/{path}
Delete the file at path.

For more examples you can check here.

This is a slight modification to Levi Lu-MSFT's answer that will work for production or slots:

$ResGroupName = ""
$WebAppName = ""
$SlotName = ""

# Get publishing profile for web application
if([string]::IsNullOrEmpty($SlotName)) {
  $WebApp = Get-AzWebApp -Name $WebAppName -ResourceGroupName $ResGroupName
  [xml]$publishingProfile = Get-AzWebAppPublishingProfile -WebApp $WebApp
  $Uri = "https://$WebAppName.scm.azurewebsites.net/api/command"
} else {
  $WebApp = Get-AzWebAppSlot -Name $WebAppName -ResourceGroupName $ResGroupName -Slot $SlotName    
  [xml]$publishingProfile = Get-AzWebAppSlotPublishingProfile -WebApp $WebApp  
  $Uri = "https://$WebAppName-$SlotName.scm.azurewebsites.net/api/command"
}

# Create Base64 authorization header
$username = $publishingProfile.publishData.publishProfile[0].userName
$password = $publishingProfile.publishData.publishProfile[0].userPWD
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))

$bodyToPOST = @{  
                  command = "find . -mindepth 1 -delete"  
                  dir = "/home/site/wwwroot"  
}  
# Splat all parameters together in $param  
$param = @{  
            # command REST API url  
            Uri = $Uri  
            Headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}  
            Method = "POST"  
            Body = (ConvertTo-Json $bodyToPOST)  
            ContentType = "application/json"  
}  
# Invoke REST call  
Invoke-RestMethod @param   
Related