Home Passing Complex Objects To Job Matrix
Post
Cancel

Passing Complex Objects To Job Matrix

Introduction

Using a job matrix in YAML pipelines is a really powerful tool to enable you to run parallel deploys with different variable values. Use cases include:

  • Running MSBuild in parallel against multiple configurations with no extra code
  • Running Deploys against multiple different environments
  • Running Deploys against different regions in Azure
  • Restarting VMs in Azure in parallel

Matrix Basics

MSDN has a good starter document to go through the basic syntax and how to use a matrix

https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/jobs-job-strategy?view=azure-pipelines

The basic and most common declaration is within a job and can be done as below.

1
2
3
4
jobs:
- job: Build
  strategy:
    matrix:

A matrix can be defined in a very similar way to a complex object. So lets use MSBuild as an example, with MSBuild usually you will have a debug and a release configuration. Debug for testing and release for production. You could set you matrix as below

1
2
3
4
5
6
7
8
jobs:
- job: Build
  strategy:
    matrix:
      debug:
        Configuration: debug
      release:
        Configuration: Release

You set the matrix with 2 properties debug and release. Within those properties you can set variables to be used. We set configuration to be debug and release in each. So lets try and visualize it now within the pipeline. The below pipeline code will show a basic matrix in action.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
trigger: none

pool:
  vmImage: ubuntu-latest

jobs:
  - job: Build 
    strategy:
     matrix: 
       debug:
         Configuration: debug
       release:
         Configuration: release
    steps:
    - script: echo 'Building $(Configuration) Configuration.'
      displayName: Building $(Configuration) Configuration

As you can see in the below screenshot with this simple yaml code we have now been able to create 2 parallel jobs to run.

MatrixExample

Passing Complex Objects to matrix

As well as defining a matrix as above, in some cases pipelines can get complicated and we may need to repeat certain matrixes across lots of jobs. Instead of repeating matrix code across multiple jobs we can actually define it as a parameter and then pass it into the matrix dynamically this allows code reuse and neatens up yaml code a hell of a lot. The best thing is, its super easy. Take a look below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
trigger: none

pool:
  vmImage: ubuntu-latest

parameters:
  - name: matrix
    type: object
    default:
        debug:
          Configuration: debug
        release:
          Configuration: release

jobs:
  - job: Build 
    strategy:
     matrix: ${{ parameters.matrix }}
    steps:
    - script: echo 'Building $(Configuration) Configuration.'
      displayName: Building $(Configuration) Configuration

Changing the maximum number of parallel executions

Another key feature of a matrix is being able to set the number of max parallel threads that occur at once. This can be really useful in scenarios such as restarting VMs where you only want a certain number off at a time or other scenarios where you want to control the number of executions. We have changed our example to be a restarting server example as below, with a max parallel of 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
trigger: none

pool:
  vmImage: ubuntu-latest

parameters:
  - name: matrix
    type: object
    default:
        local:
          servername: local01
        staging:
          servername: staging01
        development:
          servername: development01
        production:
          servername: production01

jobs:
  - job: RestartServer 
    strategy:
     matrix: ${{ parameters.matrix }}
     maxParallel: 1
    steps:
    - script: echo 'Restarting $(servername).'
      displayName: Restarting $(servername)

As you can see from the below screenshots each job executes and waits until the previous job has completed to continue. This allows you to only have 1 server off at a time but still use a matrix to really promote code reuse.

MatrixExample1 MatrixExample2

This post is licensed under CC BY 4.0 by the author.