Summary

 

DevOps has become more and more ingrained into our Power Platform project lifecycle. Work item tracking and feedback tools for teamwork. Continuous integration and delivery for code changes and solution deployments. Automated testing for assurance, compliance and governance considerations. Microsoft's tool, Azure DevOps provides native capabilities to plan, work, collaborate and deliver. Each step along the way in our Power Platform DevOps journey can be tracked and monitored which will be the primary objective of this article.

This article will focus on reviewing the current setup of our Azure DevOps implementation using APIs. We will work with environments and builds that can help to control and coordinate. From there, we will deep dive into build runs to capture work items and change information to help with annotation. We will explore build timelines and logs, helping us determine where things may have gone wrong or could be tuned. Finally, I'll provide references to useful REST API calls and PowerShell samples.

Sources

 

Sources of Azure DevOps events that impact our delivery can come from virtually any area of the platform including work items, pipelines, source control, testing and artifact delivery. As mentioned, this article will focus on using the Azure DevOps REST API to expose these sources externally.

AUTHOR NOTE: Click each image to enlarge for detail.

Azure DevOps REST API

 

Choosing between the SDK and invoking the endpoint directly

 

To connect to the Azure DevOps REST API an administrator can use HTTP requests directly or the client library (SDK). The SDK will help simplify your code and works across multiple frameworks include .NET, Node.js and Python. A reference to the Azure DevOps Dot Net Sample code can be found on GitHub.

If you choose to not take on the dependency of the SDK the REST API can still be used and invoked. The decision here is how you plan to utilize your solution. If you are working within an Azure Function for instance, consider using the SDK. For workloads, such as Power Automate or PowerShell, I would recommend the REST API.

Authenticating with a Personal Access Token or SSH

 

Personal Access Tokens are alternative passwords that allow Azure DevOps administrators to issue temporary access to trusted applications that wish to work with the REST API. To setup a PAT, please review this article.

For a detailed description of how to choose the right authentication mechanism, please go here. If you are working with a Linux container or environment continue using the SSH Keys.

Components of a REST Request

 

The URL and API Versions

 

VERB https://dev.azure.com/{organization}/_apis[/{area}]/{resource}?api-version={version}

You should leverage API versioning when working with Azure DevOps REST APIs to avoid breaking changes. Azure DevOps REST API offers backwards compatibility with this approach. The API versioning reference is located here. Its key to the subsequent calls below so be sure to make a point to review the reference regularly.

NOTE: In the PowerShell examples provided below, I'll be providing a parameter approach for supplying the API version which is helpful to quickly update to a newer version.

Sample Request and Response

 

Below is an example using a HTTP request to list projects in the contoso organization:

Request:

GET https://dev.azure.com/contoso/_apis/projects?api-version=5.0 HTTP/1.1
authorization: Basic ***sanitizied***
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.18362.145
Content-Type: application/json
Host: dev.azure.com

Response:

{
  "count": 1,
  "value": [
    {
      "id": "<project guid>",
      "name": "<project name>",
      "url": "https://dev.azure.com/contoso/_apis/projects/{project guid}",
      "state": "wellFormed",
      "revision": 19,
      "visibility": "public",
      "lastUpdateTime": "2019-11-04T15:38:16.723Z"
    }
  ]
}

Common Operations

 

The Azure DevOps APIs and SDK provide many different operations from project and user membership, to work items, source control, automation, testing and governance. Common operations of interest for monitoring include identifying the status of builds and deployments and capturing logs from pipelines and tasks which will be detailed below.

Build Environments

 

Environments

 

Environments in Azure DevOps allow for targeted deployment of artifacts to a collection of resources. In the case of the Power Platform, this can be thought of a release to an Power Platform environment. The use of pipeline environments is optional, that is unless you begin work using Release pipelines which do require environments. Two of the main advantages of environments are deployment history and security and permissions. Using the Azure DevOps REST API for Environments we can evaluate both...mostly.

Using the following PowerShell script we can extract information regarding an environment.

$environmentsUrl = "$($devopsBaseUrl)$($projectId)/_apis/distributedtask/environments?name=$($environmentNameEncoded)&$($apiVersion)"
$environments = Invoke-RestMethod -Uri $environmentsUrl -Method Get -ContentType "application/json" -Headers $header

The output for each environment includes the identifier, name, description and creation properties.

Environment Deployment History

 

Environments allow Azure DevOps administrators the ability to review and manage each deployment. With this control also comes auditing of previous deployments allowing insight into trends and potential vulnerabilities.

Each attempted deployment to an environment includes an execution record that can expose stage (orchestrations and divisions of labor) and job (sequential tasks) details. Below is an example of a PowerShell script to request deployment records on a specific environment using the Environment Deployment Records REST API.

$environmentDeploymentRecordsUrl = "$($devopsBaseUrl)$($projectId)/_apis/distributedtask/environments/$($envirommentId)/environmentdeploymentrecords?$($apiVersion)"
$environmentDeploymentRecords = Invoke-RestMethod -Uri $environmentDeploymentRecordsUrl -Method Get -ContentType "application/json" -Headers $header

For each deployment record we can find out a wealth of information. Build definitions, plans, stages, jobs are all shown. The start and finish timings and statuses are also shown, helping engineers determine where things may have gone wrong.

Here is an example showing usage of the Environment and Environment Deployment Record REST API calls. Also included are calls to the Build REST API calls detailed below.

Quick Note on Security Checks

 

Each deployment, that meets security checks, will be included within the Execution Record REST API result list. If the deployment is not found, most likely it is awaiting or failed a specific conditional check.

Using Web Hooks, as discussed in the Web Hooks section of the article "Azure DevOps - Notifications and Service Hooks", we can see acknowledgement of a pending approval.

Build Pipelines

 

As we continue the journey within the Azure DevOps service towards continuous integration we will begin using Azure DevOps Build Pipelines more and more. Pipelines allow tight control and visibility into pretty much all aspects of the service. This includes work item and code changes that resulted in integration and deployment.

Each build can be drilled into using the Azure DevOps REST API to find out about all our builds. This allows us to request for each build, not only the logs and timings, but how the build compares to previous builds. From this we can conclude if our builds are trending in the right direction and if not, what can we do to course correct.

 

Using the following PowerShell command, we can review the status of any particular build of interest. For the below example, I had previously scanned the Build Definition REST API for builds.

$buildUrl = "$($devopsBaseUrl)$($projectId)/_apis/build/builds/$($buildId)?$($apiVersion)";
$build = Invoke-RestMethod -Uri $buildChangesUrl -Method Get -ContentType "application/json" -Headers $header

Here is the output:

In the above example, we can see that the build number, the status and result, the start and finish times are returned. Also included is information about the code changes and work items as well as logs that can be drilled into for each task.

Build Changes and Work Items

 

Each build most likely is associated with changes made by a team of developers or support engineers. During the typical DevOps process, branches are created, code is crafted and merged with Pull Requests. Below is an example of a sample commit and pull request triggering a build.

With the Azure DevOps REST API, we can review the location and identifiers to help monitor the code changes in each build.

$buildChangesUrl = "$($devopsBaseUrl)$($projectId)/_apis/build/builds/$($buildId)/changes?$($apiVersion)";
$buildChanges = Invoke-RestMethod -Uri $buildChangesUrl -Method Get -ContentType "application/json" -Headers $header

PowerShell example output:

This is essential to helping automate release notes that include references to each commit and approval. Post deployment, analysts can review and determine gaps in the current process. This feedback loop is important to internal teams to continuous improve and optimize the code delivery process.

Build Work Items

 

Each build also brings along information about each work item associated to it. This can include user stories and bugs associated within a Release Record for each release. By using Web Hooks and the REST API, we can review and provide automated release records to external stakeholders such as users of our platform.

Here is a sample PowerShell script requesting associated work item referenced in a build run.

$buildWorkItemsUrl = "$($devopsBaseUrl)$($projectId)/_apis/build/builds/$($buildId)/workitems?$($apiVersion)";
$buildWorkItems = Invoke-RestMethod -Uri $buildWorkItemsUrl -Method Get -ContentType "application/json" -Headers $header

Artifacts

 

Each build can contain artifacts that can be retained and used by other builds, included in documentation or packaged as part of a release using the Artifacts REST API call.

Here is sample PowerShell script showing how to request the published artifacts from a build run.

$buildArtifactsUrl = "$($devopsBaseUrl)$($projectId)/_apis/build/builds/$($buildId)/artifacts?$($apiVersion)";
$buildArtifacts = Invoke-RestMethod -Uri $buildArtifactsUrl -Method Get -ContentType "application/json" -Headers $header

Here's the output in PowerShell. Reference the "downloadUrl" to extract and store the published artifacts to external services such as Azure Blob Storage.

Logs

 

Gathering build logs are important, allowing administrators to track the status, the timings and the actions performed by a build. Within each build, logs are collected for every action, which can be extracted using the "logs.url" property within the Build REST API command. Using the Get Build Log REST API we can expand each and review or store in another log store such as Azure Application Insights.

Here is a sample PowerShell script that loops through each log URL in a build and prints the content.

$buildTaskLogs = Invoke-RestMethod -Uri $build.logs.url -Method Get -ContentType "application/json" -Headers $header
$buildTaskLogs.value | ForEach-Object{
    #get the log payload of each task log in a build
    $log = Invoke-RestMethod -Uri $_.url -Method Get -ContentType "application/json" -Headers $header
    Write-Host $log
}

Sample Code

 

The PowerShell code referenced in this article can be found here.

References

 

Below is a list of the Azure DevOps REST API operations for Builds I find useful:

API Definition Comments
Builds Helps gather build summaries to quickly identify anomalies.
Get Build Logs Helps capture logs for specific builds for troubleshooting and performance monitoring.
Get Build Changes Helps identify code changes within a specific build.
Get Changes Between Builds Helps identify code changes between builds.
Get Build Report Helps capture the generated build report in html or json formats.
Get Build Definitions Find builds related to a particular Pipeline. Helpful to isolate build runs.

Below is a list of the Azure DevOps REST API operations for Environments I find useful:

API Definition Comments
Get Environments Get environment identifiers and ownership.
Get Environment Deployment Records Gather previous and current deployment information.

Next Steps

 

In this article we have worked with Azure DevOps externally. Using the SDK or REST API, Azure DevOps can be explored in detail, allowing us to reimagine how we consume and work with the service.

Previously we looked at setting up notifications and web hooks to popular services. Continuing from here, we will look into more collaboration opportunities. We will review Chat Bots and integrations with Microsoft Teams. For deployment tracking, we will dive into build and release events and opportunities to analyze for greater insights into trends.

If you are interested in learning more about specialized guidance and training for monitoring or other areas of the Power Platform, which includes a monitoring workshop, please contact your Technical Account Manager or Microsoft representative for further details.

Your feedback is extremely valuable so please leave a comment below and I'll be happy to help where I can! Also, if you find any inconsistencies, omissions or have suggestions, please go here to submit a new issue.

Index

 

Monitoring the Power Platform: Introduction and Index