TAP 1.5 – Azure DevOps Is Now Supported


Back in December 2022, While working on designing a TAP implementation for a customer of mine, I came to learn that they use Azure DevOps as their Git server.

Immediately i decided to take a look at how it would work with TAP, and ran into a bunch of issues.

Azure DevOps is not a standard Git server, and many limitations and differences are present that make the integration difficult.

I ended up diving deep into the weeds, and was able to make the integration work, through some custom overlays.

This solved my issue, but was not an officially supported configuration, and as such I shared with people on the TAP team my findings, and my implementation of a POC on building in such an integration. I also wrote a blog post detailing the steps needed to get this working.

TAP 1.5 – Official Support for Azure DevOps

Now in TAP 1.5, VMware have built in support for Azure DevOps out of the box which is amazing!

Many enterprise customers use Azure DevOps, and integrating with it out of the box, makes the barrier of entry to TAP much lower for many customers.

What you need to configure to work with Azure DevOps

As mentioned above, Azure DevOps is not a standard Git implementation and has some hard restrictions as well as some quirks.

The main 2 differences are:

  1. Azure DevOps requires Multi Ack authentication from the git client
  2. Azure DevOps has non standard paths for repositories as compared to other git providers

In order to handle these cases, we need to make a few changes in our TAP Values, as well as some changes in our Workload and Deliverable YAML files.

TAP Values level changes

We have 2 main integrations with Git that need configuration in our supply chain.

The first type of integration, is how the platform pulls down source code from git, which is handled by our supply chains.

The second type of integration, is the GitOps flow, in which we push the generated kubernetes manifests into a git repository either via a direct commit to a specified branch or via opening a pull request.

Configuring the supply chain to pull from Azure DevOps

In our TAP values file we need to set the git_implementation key to libgit2 instead of the default which is go-git. This is because of the requirment for multi ack support, which is not provided by go-git.

This key is a parameter of the supply chain specific settings in your TAP values, so depending on the out of the box supply chain you choose to use, it will like like one of the following:

  git_implementation: libgit2
  git_implementation: libgit2
  git_implementation: libgit2

While doing this setting globally is the better UX, and will prevent many issues, this could also be set on a workload by workload basis. This may be beneficial if you have multiple teams using the platform and some use Azure DevOps, and others use a different Git provider such as Github. This can be easily configured on a workload by adding the parameter "gitImplementation" like bellow:

apiVersion: carto.run/v1alpha1
kind: Workload
    - name: gitImplementation
      value: libgit2

Configuring the supply chain to push to an Azure DevOps GitOps repository

When we configure the GitOps flow, we add under our top level key of the relevant supply chain a gitops section with the needed values which differ depending on if you want to use the direct commit approach or the PR approach, however in either case, the Azure DevOps related changes are the same.

under the gitops key, we first have 3 important keys:

  1. server_address – this is the URL to your Git server
  2. repository_owner – this is typically the github/gitlab organization or user
  3. repository_name – the name of the repo we want to push the config to.

While the hierarchy of most Git Providers is <ORG NAME>/<REPONAME>, in Azure DevOps, we have a middle level object called a project.

This means that when a typical Gtihub URL to a repo would look like:


In Azure DevOps it will look a bit different. A project in Azure DevOps does not only contain a git repo but also many other functionalities and as such the URLs are built in the following format:


For example:


If you notice in the example above, the project name and repo name are the same. This is typically the case, however you can actually have multiple repositories under a single project.

Due to this structure of the URL, we need to fill out the values mentioned above in a specific manner:

  1. server_address – this is the same as other providers (eg https://dev.azure.com)
  2. repository_owner – this must be <ORG>/<PROJECT> (eg vrabbi/vrabbi-gitops)
  3. repository_name – this is the same as other providers (eg tap-gitops)

The final setting we must configure, whether using the PR flow or the direct commit flow is, gitops.pull_request.server_kind which must be set to the value "azure".

In the end a sample configuration with the commit flow would look like:

    server_address: https://dev.azure.com
    repository_owner: vrabbi/tap-gitops
    repository_name: tap-gitops
      server-kind: azure

And a sample with the PR flow would look like:

    server_address: https://dev.azure.com
    repository_owner: vrabbi/tap-gitops
    repository_name: tap-gitops
    commit_strategy: pull_request
    branch: main
      server-kind: azure
      commit_branch: ""
      pull_request_title: ready for review
      pull_request_body: generated by supply chain

Changes to our workload and deliverable manifests

The only real change here, is to pay attention to the Git URL and make sure you use the correct Azure DevOps format which is as mentioned above:


While this seems trivial, it is important to not add the ".git" suffix to the name of the repo, as this is unsupported by Azure DevOps, and will cause your supply chains to fail to pull the source code.


It is great to see that VMware have now added official support for Azure DevOps to TAP. The integration is extremely easy to setup, and the changes mentioned above should be quite well known for those that deal with Azure DevOps.

The ability to support so many different customer setups is an amazing part of TAP, due to its extreme flexibility, and the ease of customization of the platform, and having another key Git providers implementation officially supported is a great proof of this.

Leave a Reply

%d bloggers like this: