Skip to content

Write Your First Runbook

Let’s create a simple runbook from scratch!

  1. Create a new folder called my-first-runbook.
  2. Inside that folder, create a file called runbook.mdx.
  3. Create subfolders called scripts and templates/project.
  4. Copy/paste the following content into each file:

You can also download the complete example as a zip file.

runbook.mdx

# My First Runbook
Welcome to your first runbook! Let's walk through the key features of Runbooks.
## Full markdown support
The first thing to point out is that you have access to the _full set_ ~~of~~ **markdown capabilities** ❤️. Here are some commonly used elements, though almost all of [GitHub-Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) is supported:
| Element | Syntax | Description |
|---------|--------|-------------|
| Headings | `# H1` `## H2` `### H3` | Create section titles and hierarchy |
| Bold | `**text**` | Emphasize important text |
| Italic | `*text*` or `_text_` | Add subtle emphasis |
| Links | `[text](url)` | Create clickable hyperlinks |
| Images | `![alt](url)` | Embed images in your document |
### Admonitions
In addition to full markdown support, you can also include an [Admonition block](https://runbooks.gruntwork.io/authoring/blocks/admonition/) like this:
<Admonition type="info" title="Before You Begin" description="This is an Admonition block. Notice that it even supports _inline markdown_!" />
## Checks
When users are consuming a runbook, It can be helpful to "check" that they are prepared to succeed, or after using a runbook, that they did in fact succeed. This is the function of [Check blocks](https://runbooks.gruntwork.io/authoring/blocks/check/).
In this example, we're going to verify that git is installed:
<Check
id="check-git"
command="git --version"
title="Check if Git is installed"
description="We need Git for version control"
successMessage="Git is installed!"
failMessage="Git is not installed. Please install it from https://git-scm.com/"
/>
That was a pretty simple check, so now let's load our check from a script, and allow users to _customize_ that script on the fly.
<Check id="check-git-version" path="checks/check-git-version.sh" title="Check Git Version" description="Verify that you're running a specific version of git" failMessage="Hmm, your git version seems off. Try again." successMessage="Success! Well now, look who's got the expected git version.">
<Inputs id="git-version-inputs">
```yaml
variables:
- name: GitVersion
type: string
description: "The exact git version you expect to have installed (e.g., 2.39.0)"
validations:
- required
default: "2.39.0"
```
</Inputs>
</Check>
If you look at the source code for this runbook, you'll see that we declare the inputs (or variables) we want, and Runbooks renders a web form automatically:
```yaml
variables:
- name: GitVersion
type: string
description: "The exact git version you expect to have installed (e.g., 2.39.0)"
validations:
- required
default: "2.39.0"
```
We declare the variables using [Gruntwork Boilerplate syntax](#), and we have significant control over how the webform renders based on what the [Inputs block](https://runbooks.gruntwork.io/authoring/blocks/inputs/) supports.
## Generate files
Now let's generate some files. We're going to specify a Gruntwork Boilerplate template, that includes a declaration of the variables in that template, and the template files themselves.
Runbooks will then render a web form automatically and generate the files for us!
<Template id="project" path="templates/project" />
<Admonition type="info" title="Templates update in real time" description="Try updating the author name and programming language, and notice how the rendered template changes in real time." />
On your local machine, all the newly generated files are available in a subfolder named `generated` folder, relative to where you ran `runbooks` from. You can customize where these files get generated by using the `runbooks --output-path` flag.
## Run commands
Runbooks also gives you the [Command block](https://runbooks.gruntwork.io/authoring/blocks/command/), which allows you to run arbitrary scripts.
You can even parameterize the scripts with a custom set of inputs, or any of the inputs we collected above.
<Command
id="run-setup"
path="scripts/setup.sh"
inputsId="project"
title="Run Project Setup"
description="Creates your project structure"
successMessage="Project setup complete!"
failMessage="Setup failed. Check the logs for details."
/>
Commands are useful when you need to do things like:
- Make an API call
- Install tools locally
- Run commands locally
Whereas Checks blocks are focused on _reading_ the current state of the world, Command blocks are focused on _mutating_ the state of the world.
## Congratulations!
<Command
id="final-message"
command="echo '🎉 Congratulations! You finished using your first runbook!'"
title="Show Success Message"
/>
**Great job!**
Everything above was built in nothing more than a text editor. I typed in some markdown and blocks (e.g. `<Check>` or `<Template>`), refreshed my browser, and verified that things looked the way I wanted. In fact, if you'd rather the browser auto-refresh, Runbooks offers `runbooks watch` to give authors instant feedback loops.
You can also use AI to write Runbooks! Give your favorite LLM the [Runbooks LLM instructions](#), along with what you want, and you get a fast starting point.
TODO: Fill in this link.
If you'd like to learn more about Runbooks, head back to the [Runbooks docs](https://runbooks.gruntwork.io).

scripts/setup.sh

#!/bin/bash
echo "🚀 Setting up project: {{ .ProjectName }}"
echo ""
echo "👋 Welcome, {{ .Author }}!"
echo "📦 Primary language: {{ .Language }}"
echo ""
echo "✅ Project setup complete!"

Make the script executable:

Terminal window
chmod +x my-first-runbook/scripts/setup.sh

templates/project/boilerplate.yml

variables:
- name: ProjectName
type: string
description: What would you like to call your project?
default: my-awesome-project
validations:
- required
- name: Author
type: string
description: What's your first name?
- name: Language
type: enum
description: What's your favorite programming language?
options:
- Go
- Python
- JavaScript
- TypeScript
- Rust
default: Go

templates/project/README.md

# {{ .inputs.ProjectName }}
Created by **{{ .inputs.Author }}**
## About
This project is built with {{ .inputs.Language }}.
{{ if eq .inputs.Language "Go" -}}
Go excels at cross-platform compilation and building fast, reliable CLI tools and APIs.
{{- else if eq .inputs.Language "Python" -}}
Python's readability and vast ecosystem make it ideal for data science and rapid prototyping.
{{- else if eq .inputs.Language "JavaScript" -}}
JavaScript powers the web and runs everywhere from browsers to servers to mobile apps.
{{- else if eq .inputs.Language "TypeScript" -}}
TypeScript adds static typing to JavaScript, catching bugs at compile time.
{{- else if eq .inputs.Language "Rust" -}}
Rust delivers C-level performance with memory safety guaranteed at compile time.
{{- end }}
## Getting Started
1. Clone this repository
2. Install dependencies
3. Start building!

templates/project/.gitignore

# Build outputs
dist/
build/
*.exe

Save the files and open the runbook:

Terminal window
runbooks open my-first-runbook/

Your browser will open showing the runbook interface. Follow the steps to execute each block!

This Runbook generates some files. Let’s learn more about the files workspace — where generated files and cloned repositories show up in the Runbooks UI.