6 tips you should know before implementing AzureDevOps Pipelines

Marc Gardent
Esker-Labs
Published in
4 min readOct 3, 2019

I used Jenkins intensively, and I implemented two main projects in AzureDevOps this year: Terraform and Chef. Allow me to share tricks about AzureDevOps.

One repository, multi-project

You should add several (tiny) projects in the same repository organized with subfolders.

root
|
+- ProjectA
|
+- ProjectB
|
+- ProjectC

Therefore you add/declare several build definitions. But if you set the triggering on every commit, it's not going to be cool! Every build runs even if there is no change in the project's subfolder. For a smart trigger, you can define subfolder in your build definition :

trigger:
branches:
include:
- master
paths:
include:
- ProjectA

The trigger is fired only if commits concern the sub-folder. It's a basic feature in CI/CD platforms but it's structuring.

Queuing strategies of releases

When your releases are triggered automatically and you add an approval in the pipeline, you can be overwhelmed by pending approvals. You have to cancel or accept each release in order. Sometimes, this does not make sense.
You should change the queuing strategy in your release definition, as you can see below.

Your old releases in the pending approval state are automatically cancelled!

Create AzureDevops Teams (even if you have AAD groups)

You may add some people to approve releases. But if you add several user/group in the same rule, the default behaviour is: each user/group has to approve. For instance, two approvals are expected, as shown below:

You should then set Approval order to "Any one user". Or even better, create built-in teams, which should be more resilient to change if you have a lot of pipelines.

Share your scripts with step and job templates

You can create step or job templates and call them in your build definition. For instance with a step template :

# file templates/my-template.yml
parameters:
my_param: "default value"
steps:
- script: |
echo "${{parameters.my_param}}"
displayName: 'task! Hello world'

the call from the same repository:

# file: azure-pipelines.yml
(...)
steps:
- template: templates/my-template.yml
parameters:
my_param: 'Hello world'

the call from another repository:

(...)
resources:
repositories:
- repository: mycommon
type: git
name: common-ci
steps:
- template: my-template.yml@mycommon
parameters:
my_param: 'Hello world'

more details: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

Share your scripts with a task group

And for your release definition, you can use a task group! For example, you can convert an existing step as a task group, like in this example below:

click right on a step > Create task group

Share your scripts with multiple Checkout repositories in a single Build/Release

You can create a repository with your sharable scripts. And after you can check out both the common and the project repository! You can use this strategy in your builds and releases definitions.

  • In the release definition, you can add repositories as artifacts :
  • In the build definition (Oups!), the design/documentation is ready but the feature is not released :

but it may look like below:

trigger:
- master
pool:
vmImage: 'ubuntu-latest'
resources:
repositories:
- repository: myrepositoryid
type: git
name: common-ci
steps:
- checkout: self
- checkout: myrepositoryid
path: mysecondrepository-folder
- script: ls $(Build.SourcesDirectory)\mysecondrepository-folder
displayName: 'Run a one-line script'

Keep in touch

I will update the article when the “multi checkout” is released! And I will be delighted to read your tips and experiences in the comments.

--

--

Marc Gardent
Esker-Labs

IT Consultant, and Indie Creator: join @ludopant on Instagram: video games, board games, graphics, artworks, comics, animations.