A runbook is the YAML configuration file that controls every aspect of a LISA test run: which tests to execute, on which platform, with which OS image, how many parallel environments, and where to report results.
- Runbook structure overview
- Top-level fields
- variable — defining variables
- platform — target environment
- testcase — selecting tests
- notifier — reporting results
- transformer — environment setup
- combinator — grid testing
- extension — custom code
- include — composing runbooks
- Variable substitution
- Running a runbook from the CLI
- Complete annotated example
- Building runbooks with the MCP server
- Common runbook patterns
# Metadata
name: My Test Run
test_project: Linux Image Quality
test_pass: T1 BVT
concurrency: 2
exit_on_first_failure: false
import_builtin_tests: true
# Variables and secrets
variable:
- name: location
value: westus3
- name: subscription_id
value: $(subscription_id)
# Platform (where tests run)
platform:
- type: azure
azure:
subscription_id: $(subscription_id)
marketplace: ubuntu focal 20.04-lts latest
# Test selection
testcase:
- criteria:
priority: [0, 1]
# Output
notifier:
- type: console
- type: html
path: ./report.html
- type: junit
path: ./results.xml| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Human-readable name for this run |
test_project |
string | "" |
Project label (used in reports) |
test_pass |
string | "" |
Test pass label (e.g. "T1 BVT") |
concurrency |
integer | 1 |
Number of test environments to run in parallel |
exit_on_first_failure |
boolean | false |
Stop run immediately on first test failure |
import_builtin_tests |
boolean | true |
Include LISA's built-in test suites |
log_agent |
boolean | false |
Enable AI-powered failure analysis via Azure OpenAI |
concurrency: 1 # Serial (safest, cheapest)
concurrency: 2 # Two parallel environments (2x faster, standard T1/T2 runs)
concurrency: 4 # Four parallel (fast, but more cloud cost and quota)
concurrency: 10 # High parallelism (for large-scale image testing)Each concurrent "slot" can run a different test (or the same test on a different OS if using a combinator).
Variables are referenced as $(variable_name) anywhere in the runbook.
variable:
# Simple name/value pair
- name: location
value: westus3
# Value that must be passed on CLI (empty default)
- name: subscription_id
value: $(subscription_id)
# Load variables from an external file (e.g. secrets)
- file: ./secrets.yml
# Boolean variable
- name: use_prod
value: falseNever commit credentials to your runbook. Use a separate file:
# secrets.yml (add to .gitignore)
variable:
- name: subscription_id
value: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- name: admin_private_key_file
value: /home/user/.ssh/lisa_id_rsaReference it from your main runbook:
variable:
- file: ./secrets.ymlAny variable can be overridden at run time:
lisa -r my_runbook.yml -v location:eastus2 -v subscription_id:my-idplatform:
- type: azure
admin_private_key_file: $(admin_private_key_file) # SSH key for VM access
azure:
subscription_id: $(subscription_id)
# OS image — one of these forms:
marketplace: ubuntu focal 20.04-lts latest # Ubuntu 20.04
marketplace: ubuntu jammy 22.04-lts latest # Ubuntu 22.04
marketplace: redhat rhel 8_5 8.5.2022012415 # RHEL 8.5
marketplace: debian debian-11 11 latest # Debian 11
marketplace: microsoftcblmariner cbl-mariner 1-gen2 latest # CBL-Mariner
# VM size (optional, LISA picks appropriate default)
vm_size: Standard_D4s_v3
# Location (can also be set via variable)
location: westus3
# Use shared image gallery instead of marketplace
# shared_gallery: /subscriptions/.../images/myImage/versions/1.0.0platform:
- type: hyperv
hyperv:
vhd: \\server\share\images\ubuntu-22.04.vhd
vm_generation: 2platform:
- type: ready
environment:
environments:
- name: existing_vm
nodes:
- type: remote
address: 10.0.0.100
username: azureuser
private_key_file: ~/.ssh/id_rsaplatform:
- type: qemu
qemu:
image_path: /var/lib/lisa/images/ubuntu-22.04.qcow2The testcase section is a list of criteria blocks. LISA evaluates them in order.
testcase:
- criteria:
<filter fields>
select_action: include # default
retry: 0 # retry count on failure
times: 1 # how many times to run
timeout: 3600 # override test timeoutcriteria:
name: smoke_test # match test method name (substring)
area: network # match area name
priority: [0, 1] # match priority (list or single value)
tags: [sriov, performance] # match any tagAll specified criteria must match (AND logic). Multiple testcase entries are
evaluated in order (OR logic).
| Value | Behaviour |
|---|---|
include (default) |
Add to test list |
exclude |
Remove from test list |
force-include |
Include regardless of prior exclude rules |
force-exclude |
Exclude regardless of prior include rules |
testcase:
- criteria:
priority: [0, 1]testcase:
- criteria:
name: smoke_testtestcase:
- criteria:
area: networktestcase:
- criteria:
priority: [0, 1, 2] # T2 = P0-P2
- criteria:
area: stress
select_action: excludetestcase:
- criteria:
name: nvme_io_test
times: 10 # run 10 iterations
retry: 2 # retry up to 2 times on failuretestcase:
- criteria:
priority: [0, 1]
retry: 3 # retry up to 3 times on failurenotifier:
# Console output (always recommended)
- type: console
log_level: INFO # DEBUG | INFO | WARNING | ERROR
# HTML report (human-readable)
- type: html
path: ./reports/results.html
auto_open: true # open in browser when done (local runs only)
# JUnit XML (CI/CD integration)
- type: junit
path: ./reports/results.xml| Level | Shows |
|---|---|
DEBUG |
Everything including node command output |
INFO |
Test pass/fail + key events |
WARNING |
Warnings and above |
ERROR |
Errors and failures only |
Transformers prepare environments before tests run. The most common use is building/deploying custom VMs.
transformer:
# Deploy an Azure VM from a VHD
- type: azure_deploy
requirement:
azure:
vhd: https://mystorage.blob.core.windows.net/vhds/myimage.vhd
vm_size: Standard_D4s_v3
# Build a VM from source (custom kernel, etc.)
- type: azure_build_vhd
requirement:
azure:
location: westus3Test the same suite against multiple OS images or configurations automatically.
combinator:
type: grid
items:
- name: marketplace
value:
- "ubuntu focal 20.04-lts latest"
- "ubuntu jammy 22.04-lts latest"
- "redhat rhel 8_5 latest"
- "debian debian-11 11 latest"
testcase:
- criteria:
priority: [0, 1]This creates one test run per image in the list. With concurrency: 4, up to 4
images are tested in parallel.
Load custom test suites or tools from outside the main LISA repo:
extension:
- name: my_custom_tests
path: /home/user/my-lisa-extensionsAll test suites found in the extension path are loaded alongside built-in ones.
Split large runbooks into reusable pieces:
# azure_t1.yml
include:
- path: ./common_variables.yml
- path: ./azure_platform.yml
testcase:
- criteria:
priority: [0, 1]# common_variables.yml
variable:
- name: location
value: westus3
- name: concurrency
value: 2value: $(variable_name)- CLI
-v name:valueoverrides (highest priority) variable:blocks defined in the runbook- Variables loaded from
file:blocks - Environment variables (if configured)
To use a literal $(...) string without substitution:
value: "$$(not_a_variable)" # produces: $(not_a_variable)# Basic run
lisa -r my_runbook.yml
# With variable overrides
lisa -r my_runbook.yml \
-v subscription_id:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
-v admin_private_key_file:~/.ssh/lisa_id_rsa \
-v location:eastus
# Debug mode (verbose output)
lisa -r my_runbook.yml -d
# Run a specific test by name override
lisa -r my_runbook.yml -v "name:smoke_test"
# Run a specific tier
lisa -r my_runbook.yml -v tier:T0| Flag | Description |
|---|---|
-r <path> |
Runbook file path (required) |
-v name:value |
Override a variable |
-d |
Debug mode (very verbose) |
--log-path <dir> |
Directory for log files |
# ============================================================
# azure_t2_rhel9.yml
# T2 test run for RHEL 9 on Azure, East US
# ============================================================
name: RHEL 9 T2 Validation
test_project: RHEL Certification
test_pass: T2 Weekly Regression
concurrency: 2
exit_on_first_failure: false
import_builtin_tests: true
# --- Variables ---
variable:
# These must be passed via -v on the CLI or set in secrets.yml
- name: subscription_id
value: $(subscription_id)
- name: admin_private_key_file
value: $(admin_private_key_file)
# These have defaults you can override
- name: location
value: eastus
- name: vm_size
value: Standard_D4s_v3
# --- Platform ---
platform:
- type: azure
admin_private_key_file: $(admin_private_key_file)
azure:
subscription_id: $(subscription_id)
location: $(location)
vm_size: $(vm_size)
# RHEL 9 latest from Red Hat
marketplace: redhat rhel 9_0 9.0.2022053014
# --- Test selection (T2 = P0 + P1 + P2) ---
testcase:
# Include all P0–P2 tests
- criteria:
priority: [0, 1, 2]
# Exclude known-flaky network stress test
- criteria:
name: network_flood_test
select_action: exclude
# Always include smoke test (even if excluded by other rules)
- criteria:
name: smoke_test
select_action: force-include
# --- Reporting ---
notifier:
- type: console
log_level: INFO
- type: html
path: ./reports/rhel9_t2_results.html
auto_open: false
- type: junit
path: ./reports/rhel9_t2_results.xmlRun it:
lisa -r azure_t2_rhel9.yml \
-v subscription_id:$SUBSCRIPTION_ID \
-v admin_private_key_file:~/.ssh/lisa_id_rsaBuild a T2 Azure runbook for RHEL 9 in East US with:
- 2 concurrent environments
- JUnit and HTML output
- Exclude any stress tests
Save it to ~/runbooks/rhel9_t2.yml
The AI calls build_runbook(...) with all the right parameters.
from lisa_mcp.tools.test_generator import generate_runbook_yaml
from lisa_mcp.tools.runbook_builder import write_runbook
yaml_str = generate_runbook_yaml(
name="RHEL 9 T2 Validation",
platform_type="azure",
tier="T2",
excluded_names=["network_flood_test"],
image="redhat rhel 9_0 9.0.2022053014",
location="eastus",
concurrency=2,
notifiers=["html", "junit"],
)
write_runbook(yaml_str, "~/runbooks/rhel9_t2.yml")Validate ~/runbooks/rhel9_t2.yml before I run it
The AI calls validate_runbook_file(runbook_path="~/runbooks/rhel9_t2.yml").
name: Pre-Merge T0 Gate
concurrency: 1
exit_on_first_failure: true # fail fast
testcase:
- criteria:
priority: [0] # P0 onlyname: Nightly T1
concurrency: 2
testcase:
- criteria:
priority: [0, 1]
notifier:
- type: junit
path: /ci/artifacts/results.xmlname: Multi-Distro T1
concurrency: 4
combinator:
type: grid
items:
- name: marketplace
value:
- "ubuntu focal 20.04-lts latest"
- "ubuntu jammy 22.04-lts latest"
- "redhat rhel 8_5 latest"
testcase:
- criteria:
priority: [0, 1]name: NVMe Feature Validation
concurrency: 1
testcase:
- criteria:
area: nvmename: Storage Performance
concurrency: 1
testcase:
- criteria:
area: perf_storage
times: 3 # run 3 times for stable averages
retry: 1