Runbook Structure
File format
Section titled “File format”A runbook lives in its own folder and must contain a file named runbook.mdx. The file is MDX (Markdown plus JSX), so it mixes standard markdown (headers, paragraphs, lists, code blocks, images, links) with blocks such as <Check>, <Command>, <Inputs>, and <Template>.
Common structure
Section titled “Common structure”You can organize runbook.mdx however you like. A common pattern:
# Runbook title
Introduction paragraph explaining what this runbook does.
## Pre-flight checks
Make sure the user is set up for success.
<Check id="pre-flight-checks" command="tool --version" title="Check if required tool is installed" successMessage="Tool is installed!" failMessage="Please install the tool first"/>
## Execute actions
Run commands on behalf of the user to complete the runbook.
<Command id="do-something" command="echo {{ .inputs.ProjectName }}" inputsId="config" title="Execute action" successMessage="Done!"/>
## Generate code
Generate code the user needs to accomplish their task.
<Template id="infra-code" path="templates/infra"/>
## Post-flight checks
Verify everything worked.
<Check id="post-flight-checks" command="curl https://some-endpoint.com" title="Check if deployment is successful" successMessage="Deployment successful" failMessage="Something went wrong"/>Folder organization
Section titled “Folder organization”Blocks reference scripts and templates by path. You can store them anywhere, but this layout is the convention:
Directorymy-runbook/
- runbook.mdx Main runbook file
Directoryassets/ Images and other assets
- diagram.png
Directorychecks/ Shell scripts for
<Check>blocks- prereq1.sh
- prereq2.sh
Directoryscripts/ Shell scripts for
<Command>blocks- deploy.sh
- cleanup.sh
Directorytemplates/ Boilerplate templates for
<Template>blocksDirectorymy-template/
- boilerplate.yml
- main.tf
- variables.tf
Folder purposes
Section titled “Folder purposes”| Folder | Purpose | Used by |
|---|---|---|
assets/ |
Images, diagrams, videos, and other static files | Markdown image syntax and <img>, <video>, <audio> tags |
checks/ |
Shell scripts that validate prerequisites | <Check> blocks |
scripts/ |
Shell scripts that execute actions | <Command> blocks |
templates/ |
Boilerplate template directories | <Template> blocks |
Relative paths
Section titled “Relative paths”Reference files relative to the runbook’s folder:
<Check path="checks/prereq.sh" ... /><Template path="templates/my-template" ... /><img src="./assets/diagram.png" width="400" /><video src="./assets/demo.mp4" poster="./assets/demo-poster.png" controls /><Iframe src="./assets/dashboard/index.html" />Asset paths must start with ./assets/. Runbooks loads them from the runbook’s assets/ folder when they appear in markdown image syntax, including in a block prop that supports inline markdown such as title or description, or in one of these tag attributes:
| Tag | Attributes |
|---|---|
<img> |
src, srcSet |
<video> |
src, poster |
<audio> |
src |
<source> |
src (inside <video> or <audio>), srcSet (inside <picture>) |
<track> |
src |
In a srcSet, each candidate’s path is rewritten and its descriptor (2x, 480w) is kept. Write the path as a plain string: src={"./assets/demo.mp4"} is left as written and won’t load.
Video and audio are read from the file as they play, and you can seek anywhere in them.
assets/ must be a real folder, not a symlink. If assets is a symlink, Runbooks serves nothing from it and every asset fails to load, even when the symlink points inside the runbook’s folder. Otherwise assets -> . would serve runbook.mdx, scripts and generated files to any page the runbook embeds. Symlinks inside assets/ work when they point to files inside assets/.
The <Iframe> block’s src also takes a ./assets/ path.