Automating Azure DevOps Updates With Azure Functions
RSS feed
Date: May 21, 2021
Tags: azure devops
Share: Share on Twitter
When companies decide they want to get on the Azure DevOps Express, it’s usually an all or nothing experience. Sure, it might take them a little while to transition everything (and everyone) to it, but eventually, their whole business is on-board. Because every company is different, how they leverage Azure DevOps varies greatly, which means Azure DevOps sometimes needs a little configuring to handle things. I frequently get asked about automation in Azure DevOps and the best way to implement it, especially around work items and statuses. In this article, I’m going to show you how to leverage Azure DevOps Service Hooks, an Azure Function, and Azure Key Vault to sync parent work item states when its children are updated.

Azure DevOps continues to amaze me as one of the most capable and configurable Azure services. Whether it’s for code repositories, pipelines, project management, or some sweet Wiki action, Azure DevOps can provide a complete DevOps tooling solution. And what it can’t do out-of-the-box, integration with your favorite external system can be much easier than you think.

Let’s take a recent (and very common) scenario I had with a client:


“We are using Azure DevOps for our Agile process. When we update child work item to 'In Progress', why doesn’t the parent status update, as well?”


It’s a valid question. Logically, you would think that any Project Management solution would do this, because it’s such a natural thing to occur. When it comes to software, though, things are never so simple. Azure DevOps and similar tools often don’t implement this because the variables could be all over the place for each organization. What work items should be updated? What state should they be updated to? What states should NOT be updated? Where are my car keys?

As you can see, the question leads to a lot of unknowns. Covering every single scenario would be a huge undertaking, and even then, something wouldn’t be covered. The solution? Service Hooks and Azure Functions. Don’t worry, it’s not as complex as it sounds. Let me show you…

Prerequisites

Generate an Azure DevOps Personal Access Token (PAT)

To access Azure DevOps from another system. I need to generate a PAT. This token will be used to validate my integration with Azure DevOps and should be treated as very sensitive information. In my Azure DevOps User Settings, I create a new Personal Access Token. I set an appropriate expiration date and give Read, Write, & Manage permissions to Work Items.

Authenticate with personal access tokens - Azure DevOps | Microsoft Docs



Because that magic code is obfuscated once I leave the screen, I copy for use later in the process.


Create a Key Vault Secret

In my Azure Key Vault, I create a secret for the Azure DevOps PAT.
 


On the secret details, I copy the URL for the current secret version.
 


Update App Settings

In the demo Azure Function project, there are four (4) settings that need to be configured.

  • DevOpsOrgName: [Your Azure DevOps Org Name]
  • DevOpsDefaultState: [Your Azure DevOps state for work items. Typically this value is ‘New’]
  • DevOpsUpdateState: “[Your Azure DevOps state for work items to be updated to. Typically this value is “In Progress”]
  • DevOpsPAT: “[Your Azure Key Vault secret URL in the proper format. Example: @Microsoft.KeyVault(SecretUri=[Your Azure Key Vault Secrete URL])”


local.settings.json (Local development)

When developing/testing locattion, I update the localsettings.json file with my values.



Azure Function App Settings

When running in Azure, I add my App Settings to the Azure Function app.

Configure function app settings in Azure Functions | Microsoft Docs




Here is my App Settings configuration after adding 3 of the settings.



Here is the App Settings configuration after adding the Key Vault reference.



NOTE

To confirm the Azure Function is able to access the Azure Key Vault, I click on the app setting and confirm it displays a Resolved status.
 


Create a Service Hook in Azure DevOps

With the Azure Function and Key Vault configured, I am ready to add my Azure DevOps Service Hook. Service Hooks enable the execution of code when an event occurs within Azure DevOps. Create a new service hook to call the Azure Function when a work item state is updated.

Integrate with service hooks - Azure DevOps | Microsoft Docs

In my Azure DevOps project, I select Project Settings and then Service hooks.




I select Web hooks for the Service type.



I select the Work item updated trigger.


NOTE

There are several types of triggers for Azure DevOps service hooks. Be sure to review the available options and select the appropriate option for your needs.


I select the State field.



NOTE
In my example, I need to update the parent work item’s State when a child work item is updated. I select the State field to ensure the service hook is only executed when that field is updated.


Remember the Function URL? I get that value from the Azure Portal (Azure Function>Functions>Overview>Get Function Url) to use for the next step.



I enter the Azure Function Url in the Action>URL field.


Testing

With all the components deployed, I am ready to test the functionality.

To test the integration, I will update a work item within my Azure DevOps demo project and monitor the services.

I open the Azure Function Log (Azure Function>Functions>[Function Name]>Monitor>Logs). Live streaming messages will be displayed here when the function executes.



In Azure DevOps, I open the Service Hook and ensure it is enabled.



In Azure DevOps, I open my project and view a Backlog to view a hierarchy of work items. I select child work item to edit.


I update the State to any value other than the DevOpsDefaultState (New) in my configuration.


NOTE
In the demo Azure Function project, I only update the parent work item if the status of the child work is different than the DevOpsDefaultState setting. This may differ for your DevOps project and Agile processes.

I refresh the Backlog and ensure the parent work items are properly updated to the DevOpsUpdateState in my configuration (In Progress).


NOTE
This may take up to a minute to update as the Azure Function executes. The Azure Function will be executed recursively for the tree.

In the Azure Function Log, I confirm the function was executed.


Lastly, in the Azure DevOps Service Hook page, I confirm the service hook executed successfully.

 

NOTE
There are 3 executions of the service hook, 1 for each level of the hierarchy. Because the Azure Function updates the Azure DevOps parent work item via the SDK, it causes the service hook to fire for that item, as well. This will recursively “climb” up the tree for all parent work items.

I click the History link to view details on each service hook execution. This can be especially helpful in determining what the service hook request contains and the response Azure DevOps receives from the Azure Function.



Wrapping Up

By leveraging Azure DevOps service hooks and Azure Functions, you can easily modify any aspect of your Azure DevOps project. Service Hooks offer a wide range of triggers, allowing you to customize the automation to fit your needs. By using Azure Key Vault, you ensure that your sensitive data is kept secure.

In searching for a solution to my client’s question, I didn’t find a lot of articles on this topic. I hope this article provides you a great starting point for your Azure DevOps. Be sure to check out the Helpful Links below for several reference sites. Good luck!


Helpful Links