Zuul 3, a modern solution for CI/CD

Continuous Progress


The last of the crucial Zuul 3 components to be explained is Nodepool, a service that keeps the configuration of hosts where jobs are being executed. Apart from static nodes, you can define providers that launch instances in a chosen cluster as needed. Available drives are for OpenStack, Kubernetes, OpenShift, and Amazon Web Services (AWS), but in addition to the official drives, a few exist off the record (e.g., for oVirt or Proxmox).


The entire Zuul configuration is written as YAML files. A job (Listing 1) is a group of strictly related tasks to perform to decide whether a change is valid or not. The main job elements are:

  • name – A unique project identifier.
  • parent – A job's configuration can be inherited; therefore, all common elements should be kept in one job, and only needed elements should be overwritten. List elements are inherited additively (e.g., pre-run and post-run lists are added to those in the base job), whereas others are inherited (e.g., a timeout value).
  • pre-run/post run – These lists are playbooks that are always executed. Pre-runs prepare the environment, and post-runs usually collect artifacts.
  • run – This element comprises a list of playbooks that perform the verification and are executed until the first failure or all in the list have been run.
  • nodeset – The nodes where the job should be run.

Listing 1


- job:
  name: compilation
  parent: base
  pre-run: playbooks/base/pre.yaml
    - playbooks/compilation.yaml
    - playbooks/base/post-ssh.yaml
    - playbooks/base/post-logs.yaml
  timeout: 1800
      - name: main
        label: compilation_hosts

Other elements can be defined in a job that modifies its behavior, like a timeout in seconds or ignore_error, which returns success, regardless of the job's real result.


The pipeline entity (Listing 2) describes conditions, jobs, and the results of a change. The main pipeline elements are:

  • name – A unique name for the Zuul tenant.
  • manager – The relation to other ongoing changes for a given project (e.g., independent means that this pipeline will run independent of any other change). This config is useful for the initial verification of each patchset. Another value here informs Zuul that it takes into consideration the output of another pipeline.
  • trigger – In this example, the trigger defines the factors that start execution of the pipeline for Gerrit. In this case, it waits for a new patchset (or new review) or comment by a reviewer with the text RECHECK .
  • success/failure – These configs determine what Zuul should do, depending on the result. In Listing 2, a Verified vote of +1 or -1 is reported to the MySQL database.
  • require – The pipeline will not run if these additional conditions are not fulfilled (e.g., here, I do not want to check already closed reviews).

Listing 2


01 - pipeline:
02   name: verification
03   manager: independent
04   description: |
05     This pipeline is only to learn how Zuul works
06   trigger:
07     gerrit:
08       - event: patchset-created
09       - event: comment-added
10         comment: (?i)^(Patch Set [0-9]+:)?( [\w\\+-]*)*(\n\n)?\s*RECHECK
11   success:
12     gerrit:
13       # return to Gerrit Verified+1
14       Verified: 1
15     # return data to MySQL (empty key here 'mysql:')
16     mysql:
17   failure:
18     gerrit:
19       Verified: -1
20       mysql:
21   require:
22     gerrit:
23     # prevents waste runs on %submit usage
24       open: true

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>


		<div class=