This is an old one but I am catching up on my blog todo list and this little technique saved the day a while ago.  In an ideal world the deployment for an Azure Function using Azure DevOps is dead straight forward.  Get a Service Principal with the right permissions, configure the pipeline to use the Azure Function task and job done!

Unfortunately sometimes organisational challenges make it difficult to get things done.  You really need to get your automated build going but your currently blocked.  I had this scenario once and wanted to discuss my plan B to work around it so the project could progress until our optimal solution was possible.

In this case our plan was to setup an Azure Devops pipeline using the Kudu API and Powershell to deploy our function so we could continue testing it and then when we had the Service Principal we would modify the deployment pipeline to deploy the desired way.

Build Pipeline

First off we had a build pipeline which would create the drop we would deploy.  Pretty straight forward pipeline which just uses .net core tasks to build the project.

Release Pipeline

In the release pipeline however we had 1 single powershell task.  This task will take the build output and within it there will be the zip file containing the function we want to deploy.

The below powershell would take 3 variables from the pipeline:

  • The app service name
  • The username for deployment
  • The password for deployment

We got those details from the Azure App Service deployment section where you can setup an app or user credential.  This allows us to call the api zipdeploy operation to deploy the zip file and update the function.

Powershell Script

The below script shows how we did it and hopefully if you are in a similar position waiting for a Service Principal to do your deployment this will help you proceed in the meantime.

$webAppName = '$(AppServiceWebAppName)'
$username = '$(DeploymentUsername)'
$password = '$(DeploymentPassword)'
$apiUrl = 'https://' + $webAppName + ''
$folderPath = '$(System.DefaultWorkingDirectory)/Integration-Functions for .NET-CI/drop/'

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $password)))
$userAgent = "powershell/1.0"

Get-ChildItem $folderPath -Filter *.zip | 
Foreach-Object {
    $filePath = $_.FullName

    Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -UserAgent $userAgent -Method POST -InFile $filePath -ContentType "multipart/form-data"



Buy Me A Coffee