Skip to content

Zuul

← Back to all decks

25 cards — 🟢 4 easy | 🟡 4 medium | 🔴 2 hard

🟢 Easy (4)

1. What is Nodepool and how is it related to Zuul?

Show answer Nodepool is a system for managing test node resources. It supports launching single-use test nodes from cloud providers as well as managing access to pre-defined pre-existing nodes."

"Zuul uses a separate component called Nodepool to provide the resources to run jobs. Nodepool works with several cloud providers as well as statically defined nodes (again, simultaneously).

Remember: "Zuul = project gating CI system." Created by OpenStack, it tests changes BEFORE merging to prevent broken main branches.

Name origin: Nodepool manages a "pool" of test nodes created on-demand and destroyed after use — like an auto-scaling pool of CI workers.

2. What is a Pipeline in Zuul?

Show answer A pipeline in Zuul is a workflow. This workflow can be executed based on different events - when a change is submitted to a project, when it's merged, etc.
The pipeline itself can be applied on one or more different projects (= repositories in hosted or private source control)

Example: Common pipelines: "check" (run on every patch), "gate" (run before merge), "post" (run after merge), "periodic" (cron-like).

3. Describe shortly what is Zuul

Show answer From [Zuul’s docs](https://zuul-ci.org/docs/zuul/about.html): "Zuul is a Project Gating System. That’s like a CI or CD system, but the focus is on testing the future state of code repositories...

Zuul itself is a service which listens to events from various code review systems, executes jobs based on those events, and reports the results back to the code review system."

4. What is Zuul’s speculative merge (gating) model and how does it differ from traditional CI?

Show answer In traditional CI, each change is tested independently against the current state of the repository. Zuul’s speculative merge model instead tests each change as if all changes ahead of it in the gate queue have already merged. This means Zuul predicts the future state of the repo and tests against that, catching integration conflicts before they land. If a change in the middle of the queue fails, Zuul automatically re-enqueues the changes behind it against the corrected predicted state.

Analogy: Imagine a highway merge lane — Zuul tests each car (change) as if all cars ahead have already merged, predicting the future state of traffic.

🟡 Medium (4)

1. How does Zuul handle cross-project dependency testing?

Show answer Zuul can natively test changes that span multiple projects (repositories) together. When a change in project A declares a dependency on an unmerged change in project B (via a Depends-On header in the commit message), Zuul will check out and test both changes simultaneously. This is critical for organizations with microservices or shared libraries, because it ensures that a breaking API change in a library is caught before either the library or its consumer merges.

Remember: "Depends-On: " in the commit message creates the cross-project dependency link.

2. What are the main Zuul configuration files and what does each one define?

Show answer Zuul uses several YAML configuration files: .zuul.yaml (or zuul.yaml / zuul.d/ directory) — lives in each project repo and defines the jobs, project-pipeline bindings, and project templates for that repo. main.yaml — the tenant configuration file on the Zuul server that defines tenants, their source connections, and which projects are included. Within .zuul.yaml you define objects such as: job (a unit of work with a playbook, nodeset, and optional parent), project (maps pipelines to jobs for this repo), project-template (reusable

Remember: ".zuul.yaml = per-repo config, main.yaml = server-wide tenant config." Tenants isolate projects from each other.

3. What is the difference between a trusted and untrusted project in Zuul?

Show answer Trusted (config) projects contain Zuul’s pipeline definitions, base jobs, and tenant configuration. Changes to trusted projects are tested but only take effect after they merge. Untrusted projects are application repos that consume pipelines and jobs defined by trusted projects. The key security distinction: jobs running on behalf of untrusted project changes cannot access secrets by default and run in a restricted Ansible environment. This prevents a malicious contributor from submitting a patch that exfiltrates credentials or modifies pipeline behavior.

Gotcha: A PR to an untrusted project cannot modify pipeline definitions or access secrets by default — preventing credential exfiltration.

4. What are Zuul’s Ansible-based jobs and how do they differ from shell-script-based CI jobs?

Show answer Zuul jobs are defined as Ansible playbooks rather than shell scripts. Each job specifies a playbook to run, a nodeset (target nodes), and optional parent jobs for inheritance. Pre-run and post-run playbooks handle setup and teardown. Benefits over shell-based CI: Ansible provides idempotent task execution, built-in error handling, structured output, and multi-node orchestration. A single Zuul job can coordinate work across multiple test nodes (e.g., deploy a database on one node and an application on another).

Under the hood: Zuul jobs are Ansible playbooks with pre-run, run, and post-run phases. This gives idempotent setup/teardown and structured error handling.

🔴 Hard (2)

1. How does Zuul’s secrets management work, and why is it more secure than typical CI secret injection?

Show answer Zuul encrypts secrets using per-project RSA keypairs. Each project has a unique public key, and secrets are encrypted with that key and stored directly in the project’s .zuul.yaml file. Only the Zuul executor with the corresponding private key can decrypt them at runtime. Key security properties: 1. Secrets are scoped to a single project — a secret encrypted for project A cannot be decrypted in the context of project B. 2.

Under the hood: Secrets are RSA-encrypted per-project. Even Zuul admins cannot decrypt a secret meant for another project without its private key.

2. What happens in Zuul’s gate pipeline when a change in the middle of the queue fails?

Show answer When a change fails in the middle of the gate queue, Zuul dequeues that change and all changes behind it. It then re-enqueues the changes that were behind the failed change, but now they are tested against the predicted state of the repo without the failed change. For example, if changes A, B, C are queued: B is tested as if A merged, C is tested as if A+B merged. If B fails, Zuul removes B, dequeues C, and re-enqueues C to be tested as if only A merged.