> ## Documentation Index
> Fetch the complete documentation index at: https://hoopdev-docs-improve-idp-sso-pages.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Runbooks

> Create reusable, parameterized templates for common operations

<Frame>
  <img src="https://mintcdn.com/hoopdev-docs-improve-idp-sso-pages/mOi9paMdj4zBZvQ5/images/learn/features/runbooks.png?fit=max&auto=format&n=mOi9paMdj4zBZvQ5&q=85&s=24a02c37759ca48442405a56d86ab9e3" alt="Runbooks" width="1408" height="768" data-path="images/learn/features/runbooks.png" />
</Frame>

## What You'll Accomplish

Runbooks let you create reusable templates for common operations. Instead of typing the same queries or commands repeatedly, you can:

* Create parameterized templates stored in Git
* Share approved procedures across your team
* Enforce input validation and safe defaults
* Maintain an audit trail of every execution

***

## How It Works

<Steps>
  <Step title="Create Template">
    Write a runbook template with placeholders for parameters
  </Step>

  <Step title="Store in Git">
    Commit the template to your Git repository
  </Step>

  <Step title="Configure Hoop">
    Point Hoop to your repository
  </Step>

  <Step title="Execute">
    Users select the runbook, fill in parameters, and run
  </Step>
</Steps>

### Example Workflow

1. **DBA creates** a runbook for looking up customer data
2. **Template stored** in `runbooks/customer-lookup.runbook.sql`
3. **Support team** selects the runbook, enters customer ID
4. **Query executes** with proper validation and audit logging

***

## Quick Start

## Prerequisites

To get the most out of this guide, you will need to:

* Either [create an account in our managed instance](https://use.hoop.dev) or [deploy your own hoop.dev instance](/setup/deployment/overview)
* You must be your account administrator to perform the following actions

- A Git repository for storing runbooks
- Git access credentials (SSH key or token)

### Step 1: Create a Runbook File

Create a file in your repository with the `.runbook.<ext>` extension:

**`runbooks/customer-lookup.runbook.sql`**

```sql theme={null}
SELECT customer_id, name, email, created_at
FROM customers
WHERE customer_id = {{ .customer_id
    | description "Customer ID to look up"
    | required "Customer ID is required"
    | type "number" }}
```

### Step 2: Configure Git Integration

In the Web App:

1. Go to **Manage > Runbooks**
2. Click **Configure Repository**
3. Enter your repository URL and credentials

Or via CLI:

```bash theme={null}
hoop admin create plugin runbooks \
  -c GIT_URL=git@github.com:your-org/runbooks.git \
  -c GIT_SSH_KEY=file://$HOME/.ssh/deploy_key
```

### Step 3: Run the Runbook

1. Go to **Runbooks** in the sidebar
2. Select `customer-lookup`
3. Enter the customer ID
4. Click **Execute**

***

## Template Syntax

Runbooks use Go's `text/template` syntax. Parameters are defined with `{{ .parameter_name }}`.

### Basic Parameter

```sql theme={null}
SELECT * FROM orders WHERE id = {{ .order_id }}
```

### Parameter with Validation

```sql theme={null}
SELECT * FROM users
WHERE email = {{ .email
    | description "User email address"
    | required "Email is required"
    | pattern "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" }}
```

### Parameter Functions

| Function      | Description                   | Example                             |
| ------------- | ----------------------------- | ----------------------------------- |
| `description` | Help text for the input       | `description "Customer ID"`         |
| `required`    | Error message if empty        | `required "This field is required"` |
| `default`     | Default value if not provided | `default "US"`                      |
| `type`        | Input type for UI             | `type "number"`                     |
| `pattern`     | Regex validation              | `pattern "^[0-9]+$"`                |
| `options`     | Dropdown options              | `options "active" "inactive"`       |
| `squote`      | Wrap value in single quotes   | `squote`                            |
| `dquote`      | Wrap value in double quotes   | `dquote`                            |

### Input Types

| Type     | UI Behavior                   |
| -------- | ----------------------------- |
| `text`   | Standard text input           |
| `number` | Numeric input                 |
| `email`  | Email validation              |
| `date`   | Date picker                   |
| `time`   | Time picker                   |
| `select` | Dropdown (use with `options`) |

***

## Example Runbooks

### SQL: Customer Lookup

```sql theme={null}
-- runbooks/sql/customer-lookup.runbook.sql
SELECT
    customer_id,
    name,
    email,
    status,
    created_at
FROM customers
WHERE customer_id = {{ .customer_id
    | description "Customer ID"
    | required "Customer ID is required"
    | type "number"
    | squote }}
```

### SQL: Update Order Status

```sql theme={null}
-- runbooks/sql/update-order-status.runbook.sql
UPDATE orders
SET
    status = {{ .new_status
        | description "New order status"
        | type "select"
        | options "pending" "processing" "shipped" "delivered"
        | required "Status is required"
        | squote }},
    updated_at = NOW()
WHERE order_id = {{ .order_id
    | description "Order ID to update"
    | required "Order ID is required"
    | type "number" }}
```

### Bash: Service Restart

```bash theme={null}
# runbooks/ops/restart-service.runbook.sh
#!/bin/bash
SERVICE_NAME={{ .service
    | description "Service to restart"
    | type "select"
    | options "nginx" "postgres" "redis" "myapp"
    | required "Service name is required" }}

echo "Restarting $SERVICE_NAME..."
sudo systemctl restart $SERVICE_NAME
sudo systemctl status $SERVICE_NAME
```

### Python: Data Export

```python theme={null}
# runbooks/data/export-report.runbook.py
# {{ .start_date | description "Start date (YYYY-MM-DD)" | required "Start date required" | asenv "START_DATE" }}
# {{ .end_date | description "End date (YYYY-MM-DD)" | required "End date required" | asenv "END_DATE" }}
# {{ .format | description "Export format" | type "select" | options "csv" "json" | default "csv" | asenv "FORMAT" }}

import os
import pandas as pd

start = os.environ['START_DATE']
end = os.environ['END_DATE']
fmt = os.environ['FORMAT']

# Your export logic here
print(f"Exporting data from {start} to {end} as {fmt}")
```

### Kubernetes: Scale Deployment

```bash theme={null}
# runbooks/k8s/scale-deployment.runbook.sh
# {{ .namespace | description "Kubernetes namespace" | default "default" | asenv "NAMESPACE" }}
# {{ .deployment | description "Deployment name" | required "Deployment required" | asenv "DEPLOYMENT" }}
# {{ .replicas | description "Number of replicas" | type "number" | required "Replicas required" | asenv "REPLICAS" }}

kubectl scale deployment/$DEPLOYMENT \
    --replicas=$REPLICAS \
    --namespace=$NAMESPACE

kubectl rollout status deployment/$DEPLOYMENT --namespace=$NAMESPACE
```

***

## Security Features

### Input Validation

Use `pattern` to prevent injection attacks:

```sql theme={null}
-- Safe: Only allows numeric IDs
WHERE id = {{ .id | pattern "^[0-9]+$" }}

-- Unsafe: Allows any input (SQL injection risk)
WHERE id = {{ .id }}
```

### Environment Variables

Use `asenv` to pass values as environment variables instead of inline:

```bash theme={null}
# {{ .password | asenv "DB_PASSWORD" }}
psql -h localhost -U admin -c "SELECT 1"
# Password passed via PGPASSWORD, not visible in command
```

### Quoting

Use `squote` or `dquote` to properly quote string values:

```sql theme={null}
WHERE name = {{ .name | squote }}
-- Produces: WHERE name = 'John'
```

***

## File Organization

Recommended repository structure:

```
runbooks/
├── sql/
│   ├── customer-lookup.runbook.sql
│   ├── order-update.runbook.sql
│   └── report-generation.runbook.sql
├── ops/
│   ├── restart-service.runbook.sh
│   ├── check-logs.runbook.sh
│   └── deploy.runbook.sh
├── k8s/
│   ├── scale-deployment.runbook.sh
│   └── rollback.runbook.sh
└── data/
    ├── export-report.runbook.py
    └── cleanup-old-data.runbook.sql
```

### Naming Convention

Files must end with `.runbook.<extension>`:

* `.runbook.sql` - SQL queries
* `.runbook.sh` - Bash scripts
* `.runbook.py` - Python scripts
* `.runbook.rb` - Ruby scripts

***

## Integration with Other Features

| Feature               | How It Works with Runbooks               |
| --------------------- | ---------------------------------------- |
| **Access Requests**   | Runbook execution can require approval   |
| **Guardrails**        | Rules apply to runbook-generated queries |
| **Live Data Masking** | Results are masked automatically         |
| **Session Recording** | All executions are recorded              |
| **Parallel Mode**     | Run runbooks across multiple connections |

***

## Troubleshooting

### Runbook Not Appearing

**Check:**

1. File ends with `.runbook.<ext>`
2. Git repository is configured correctly
3. Hoop can access the repository (check credentials)
4. Run `hoop admin get runbooks` to verify sync

### Template Parsing Error

**Check:**

1. All `{{ }}` brackets are balanced
2. Function names are spelled correctly
3. Pipes `|` are used correctly

**Test locally:**

```bash theme={null}
hoop runbooks lint path/to/your.runbook.sql
```

### Parameter Validation Failing

If a parameter fails validation:

1. Check the `pattern` regex is correct
2. Test the regex at [regex101.com](https://regex101.com)
3. Ensure `required` values are provided

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Validate Inputs" icon="shield-check">
    Always use `pattern` for user inputs to prevent injection
  </Card>

  <Card title="Add Descriptions" icon="comment">
    Every parameter should have a clear description
  </Card>

  <Card title="Set Defaults" icon="sliders">
    Provide sensible defaults where appropriate
  </Card>

  <Card title="Version Control" icon="code-branch">
    Store runbooks in Git for history and review
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Configuration Guide" icon="gear" href="/setup/configuration/runbooks-configuration">
    Detailed Git setup and template syntax
  </Card>

  <Card title="Parallel Mode" icon="layer-group" href="/learn/features/parallel-mode">
    Run runbooks across multiple connections
  </Card>

  <Card title="Access Requests" icon="clock" href="/learn/features/access-requests/jit">
    Require approval for runbook execution
  </Card>

  <Card title="Session Recording" icon="video" href="/learn/features/session-recording">
    Audit runbook executions
  </Card>
</CardGroup>
