ARA Records Ansible — Ansible Playbook Reporting & Visualization¶
Scope: ARA (ARA Records Ansible) — an open-source Ansible callback plugin and Django-based reporting server that records every
ansibleandansible-playbookrun, exposes results via CLI, REST API, and a self-hosted web UI, and integrates with CI/CD, Prometheus, and LLMs via an MCP server.Version covered: 1.8.0 (July 2026) License: GPLv3 Repository: codeberg.org/ansible-community/ara (mirrors: GitHub) Website: https://ara.recordsansible.org
Executive Summary¶
ARA (Another Recursive Acronym) Records Ansible and makes it easier to understand and troubleshoot playbook runs. It is an Ansible callback plugin that captures every playbook execution — tasks, hosts, results, facts, files, and metadata — and stores them in a database (SQLite, MySQL, or PostgreSQL). The recorded data is accessible through:
- CLI (
ara playbook list,ara host show, etc.) for scripting and terminal workflows - REST API for programmatic access and integrations
- Web UI (self-hosted Django app) for visual browsing, filtering, and debugging
- Prometheus exporter for metric scraping and alerting
- MCP Server for LLM-driven analysis and troubleshooting
ARA is non-invasive: it works with existing Ansible setups, CI/CD pipelines (Jenkins, Rundeck, Zuul), git forges (GitHub, GitLab, Gitea, Forgejo), and tools like AWX, Ansible Runner, Ansible Navigator, Molecule, and Semaphore.
Architecture & How It Works¶
The ara_default callback plugin is the core component. It hooks into Ansible's notification system and collects data as the playbook runs:
- Tasks — name, action (module), status, duration
- Hosts — inventory name, facts (OS, kernel, Python, etc.)
- Results — stdout, stderr, return code, diff, error messages
- Files — playbook content, roles, tasks, templates, variables
- Metadata — user, controller, Ansible version, Python version, CLI arguments, labels
This data is sent to the ARA API (either directly via Python in-process with the offline client, or over HTTP to a remote server).
Core Features¶
| Feature | Description |
|---|---|
| Zero-config recording | Install the package, set one env var, and every playbook is automatically recorded |
| Offline-first | No server needed — records to local SQLite by default; spin up the UI any time with ara-manage runserver |
| Multiple database backends | SQLite (default), MySQL/MariaDB, PostgreSQL |
| Distributed SQLite | Serve multiple per-job databases from a single API instance — ideal for CI artifacts |
| Rich CLI | List, show, delete, and get metrics for playbooks, plays, tasks, hosts, results, and records |
| REST API | Full CRUD with filtering, pagination, ordering — browsable built-in interface at /api/v1/ |
| Web UI | Self-hosted Django reporting interface with playbook overviews, task drill-downs, host summaries, file diffs |
| Labels & naming | Tag playbooks with custom labels and names for easy search and filtering |
| Authentication | Optional read/write login, external auth (proxy headers), CORS configuration |
| Prometheus exporter | Expose playbook/task/host metrics at /metrics for scraping and alerting |
| MCP Server | Model Context Protocol server for LLM-driven troubleshooting and analysis |
| ara_record plugin | Attach arbitrary key/value metadata to playbook reports (git SHA, URLs, JSON, logs) |
| ara_playbook plugin | Look up playbook data from within Ansible plays (e.g., get the current playbook ID for a link) |
| ara_api lookup plugin | Free-form API queries from Ansible playbooks |
| Privacy controls | Ignore facts, files, arguments; disable recording of user/controller hostname |
| Container images | Ready-to-run images on DockerHub and quay.io |
Recording Workflow¶
Installation Guide¶
Prerequisites¶
- Python >= 3.10
- Ansible (or ansible-core) installed for the same Python interpreter as ARA
- Linux or macOS
Option 1: Local Recording (No Server) — Quick Start¶
This is the simplest mode. ARA records to a local SQLite database and you can launch a lightweight web UI on demand.
# 1. Install Ansible and ARA (with server dependencies for the web UI)
python3 -m pip install --user ansible "ara[server]"
# 2. Enable the ARA callback plugin
export ANSIBLE_CALLBACK_PLUGINS="$(python3 -m ara.setup.callback_plugins)"
# 3. Run a playbook as usual
ansible-playbook playbook.yml
# 4. List recorded playbooks via CLI
ara playbook list
# 5. Launch the web UI (serves at http://127.0.0.1:8000)
ara-manage runserver
Option 2: Persistent API Server (Docker)¶
For team dashboards, CI/CD aggregation, or long-term storage, run the ARA API server in a container:
# Create a data directory for settings and SQLite database
mkdir -p ~/.ara/server
# Start the API server (Docker)
docker run --name api-server --detach --tty \\
--volume ~/.ara/server:/opt/ara -p 8000:8000 \\
docker.io/recordsansible/ara-api:latest
# Or with Podman
podman run --name api-server --detach --tty \\
--volume ~/.ara/server:/opt/ara -p 8000:8000 \\
quay.io/recordsansible/ara-api:latest
Then configure clients to send data to it:
# Install only ARA (no server dependencies needed on the client)
python3 -m pip install --user ansible ara
# Configure the callback
export ANSIBLE_CALLBACK_PLUGINS="$(python3 -m ara.setup.callback_plugins)"
# Point to the API server
export ARA_API_CLIENT="http"
export ARA_API_SERVER="http://127.0.0.1:8000"
# Run a playbook
ansible-playbook playbook.yml
# Query remotely
ara playbook list
Option 3: Persistent API Server (Manual Install)¶
# Install with server dependencies
python3 -m pip install --user "ara[server]"
# Create a settings directory
mkdir -p ~/.ara/server
# Run database migrations
ara-manage migrate
# Create a superuser for the web UI
ara-manage createsuperuser
# Start the server (production: use gunicorn/uwsgi behind nginx)
ara-manage runserver 0.0.0.0:8000
Option 4: Database Backends (MySQL / PostgreSQL)¶
Set environment variables before starting the API server:
export ARA_DATABASE_ENGINE=mysql # or postgresql
export ARA_DATABASE_NAME=ara
export ARA_DATABASE_USER=ara
export ARA_DATABASE_PASSWORD=secret
export ARA_DATABASE_HOST=db.example.com
export ARA_DATABASE_PORT=3306
# Then migrate and run as usual
ara-manage migrate
ara-manage runserver
Distribution Packages¶
| Distribution | Package | Version |
|---|---|---|
| Fedora | ara (official RPM) |
Up-to-date |
| Debian Bookworm | ara-client, ara-server |
1.5.8 (outdated) |
| Ubuntu 22.04/24.04 | ara-client, ara-server |
1.5.8 (outdated) |
| Arch Linux (AUR) | python-ara |
1.7.0 (outdated) |
| PyPI | ara (official) |
1.8.0 (latest) |
Best practice: For production, use PyPI or the official container images. Distribution packages may lag behind. [1][6]
Configuration¶
Environment Variables¶
ARA is configured primarily through environment variables:
| Variable | Default | Description |
|---|---|---|
ANSIBLE_CALLBACK_PLUGINS |
(none) | Must point to $(python3 -m ara.setup.callback_plugins) to enable ARA |
ARA_API_CLIENT |
offline |
Client mode: offline (local SQLite) or http (remote API server) |
ARA_API_SERVER |
http://127.0.0.1:8000 |
API server URL (HTTP client mode) |
ARA_API_USERNAME |
(none) | API auth username |
ARA_API_PASSWORD |
(none) | API auth password |
ARA_API_TIMEOUT |
30 |
HTTP request timeout in seconds |
ARA_CALLBACK_THREADS |
0 |
Thread pool size (0=no threads, recommended 4 for MySQL/PostgreSQL) |
ARA_DEFAULT_LABELS |
(none) | Comma-separated labels applied to all playbooks |
ARA_ARGUMENT_LABELS |
remote_user,check,tags,skip_tags,subset |
CLI arguments auto-applied as labels |
ARA_IGNORED_FACTS |
ansible_env |
Facts not saved (all to skip all) |
ARA_IGNORED_FILES |
.ansible/tmp |
File path patterns not saved (supports regex: prefix) |
ARA_IGNORED_ARGUMENTS |
extra_vars |
Ansible arguments not saved |
ARA_RECORD_CONTROLLER |
true |
Record the controller hostname |
ARA_RECORD_USER |
true |
Record the OS user |
ARA_RECORD_TASK_CONTENT |
true |
Record task source content |
ARA_LOCALHOST_AS_HOSTNAME |
false |
Use hostname instead of localhost in results |
ansible.cfg¶
Equivalent settings can be placed in ansible.cfg:
[ara]
api_client = http
api_server = https://ara.example.com
api_username = user
api_password = password
callback_threads = 4
default_labels = prod,deploy
ignored_facts = all
localhost_as_hostname = true
Server Configuration¶
For the API server itself (set before starting ara-manage):
| Variable | Default | Description |
|---|---|---|
ARA_SECRET_KEY |
(auto-generated) | Django secret key — set a fixed value in production |
ARA_ALLOWED_HOSTS |
127.0.0.1,localhost |
Allowed hostnames for the server |
ARA_READ_LOGIN_REQUIRED |
false |
Require authentication to browse reports |
ARA_WRITE_LOGIN_REQUIRED |
false |
Require authentication to record data |
ARA_CORS_ORIGIN_WHITELIST |
(none) | CORS allowed origins |
ARA_DEBUG |
false |
Django debug mode |
CLI Usage & Examples¶
Playbooks¶
# List recent playbooks
ara playbook list
# Filter by status
ara playbook list --status failed
# Filter by name or label
ara playbook list --name "deploy prod"
ara playbook list --label prod
# Show detailed info
ara playbook show 42
# Get playbook metrics
ara playbook metrics
# Delete old playbooks (older than 30 days)
ara playbook prune --days 30 --confirm
# Output as JSON
ara playbook list -f json
Tasks & Results¶
# List tasks for a playbook
ara task list --playbook 42
# Show task detail with source code
ara task show 1234
# List failed results
ara result list --status failed
# Show full result (stdout, stderr, return code)
ara result show 5678
Hosts¶
# List hosts
ara host list
# Show host facts
ara host show hostname.example.com
# Host metrics
ara host metrics
Records (Custom Metadata)¶
# List all records attached to playbooks
ara record list
# Show a specific record
ara record show 99
Data Lifecycle¶
# Expire playbooks stuck in "running" state for >24 hours
ara expire --hours 24 --confirm
Ansible Plugins & Use Cases¶
ara_record — Attach Metadata to Reports¶
Attach arbitrary data to playbook reports from within your playbooks:
- name: Record git version
ara_record:
key: "git_version"
value: "{{ lookup('pipe', 'git rev-parse HEAD') }}"
type: "text" # text, url, json, list, dict
Types control how the data is rendered in the web UI:
- name: Record different data types
ara_record:
key: "{{ item.key }}"
value: "{{ item.value }}"
type: "{{ item.type }}"
loop:
- { key: "log", value: "Deployment complete", type: "text" }
- { key: "ci_link", value: "https://ci.example.com/build/42", type: "url" }
- { key: "artifacts", value: '{"version": "2.1.0"}', type: "json" }
Attach data after a playbook completes by specifying its ID:
ansible localhost -m ara_record \\
-a "playbook=14 key=logs value={{ lookup('file', '/var/log/deploy.log') }}"
ara_playbook — Query Playbook Info from Ansible¶
- name: Get current playbook info
ara_playbook:
register: query
- name: Print link to this playbook's report
debug:
msg: "https://ara.example.com/playbooks/{{ query.playbook.id }}.html"
ara_api — Free-Form API Queries¶
- name: Count failed hosts across all playbooks
ara_api:
path: /api/v1/hosts?status=failed&limit=1
register: result
Prometheus Exporter (New in 1.8.0)¶
ARA 1.8.0 (July 2026) introduces a built-in Prometheus exporter [5]:
# Start the exporter on :8001/metrics
ara prometheus --bind 0.0.0.0:8001
Exposed metrics include playbook counts by status, task durations, host result counts, and scrape health indicators. Includes example Prometheus rules and Grafana dashboard guidance in the documentation.
MCP Server — LLM-Driven Troubleshooting¶
ARA ships an optional Model Context Protocol (MCP) server that gives LLMs read-only access to recorded playbook data [3][4]. Models can analyze failures, compare runs, detect performance regressions, and identify secret leaks — all without dumping 60K+ tokens of terminal output into the context.
# Clone the repo and set up a virtualenv
git clone https://codeberg.org/ansible-community/ara ~/.ara/git/ara
cd ~/.ara/git/ara
python3 -m venv .venv
.venv/bin/pip install httpx mcp
Configure in your MCP client (Claude Code, VS Code, Cursor, Ollama, etc.):
{
"mcpServers": {
"ara": {
"command": "/home/user/.ara/git/ara/.venv/bin/python",
"args": ["/home/user/.ara/git/ara/contrib/mcp/ara_mcp.py"],
"env": {
"ARA_API_SERVER": "http://127.0.0.1:8000"
}
}
}
}
The server exposes 13 tools across two categories [4]:
Foundation tools (direct API-to-text): get/list playbooks, tasks, hosts, results, files.
Wrapper tools (aggregated analysis):
- troubleshoot_playbook — aggregates failures, code context, host facts, and a summary for debugging
- troubleshoot_host — host-centric failure view
- analyze_performance — cross-run timing analysis, slowest tasks, variance detection
Works with any MCP-compatible client and any model that supports tool use — including open-weight models like Qwen3, Devstral, GLM, and GPT-OSS.
Distributed SQLite Backend¶
For CI/CD environments where many jobs run concurrently, ARA supports a distributed SQLite mode. Instead of fighting SQLite's write concurrency limits, each CI job records to its own database. The ARA API server dynamically loads the correct database based on the URL path.
/var/www/logs/
├── job-1/ara-report/ansible.sqlite
├── job-2/some/path/ara-report/ansible.sqlite
└── job-3/dev/ara-report/ansible.sqlite
Configure with:
export ARA_DISTRIBUTED_SQLITE=true
export ARA_DISTRIBUTED_SQLITE_ROOT=/var/www/logs
The server then serves:
- http://example.org/job-1/ara-report
- http://example.org/job-2/some/path/ara-report
This approach is ideal for CI systems (Zuul, Jenkins) where each job produces its own artifact.
Web UI¶
The ARA web reporting interface is a self-hosted Django application that provides:
- Dashboard — overview of recent playbooks with status indicators
- Playbook view — detailed breakdown of plays, tasks, results per host
- Host view — facts and result history per host
- File browser — view recorded playbook/task/role source files with line-level context for results
- Search & filter — by name, label, status, user, controller, date range
- Static generation —
ara-manage generate /path/to/outputfor offline archives
A live demo is available at https://demo.recordsansible.org.
Live Demo¶
Explore a live instance of ARA populated with real playbook data:
- URL: https://demo.recordsansible.org
- API: https://demo.recordsansible.org/api/v1/
- Pre-loaded with playbooks from the ARA project's own CI
Tip: Use the API browser at
https://demo.recordsansible.org/api/v1/to explore the data model interactively — playbooks, tasks, hosts, results, and files are all linked by RESTful relationships.
Community & Project Status¶
| Metric | Value |
|---|---|
| GitHub Stars | ~2,000 |
| Forks | 181 |
| Contributors | 45 |
| Commits | 1,083+ |
| Release | 1.8.0 (July 2026) |
| License | GPLv3 |
| Used by | 640+ dependent repositories |
| Primary maintainer | David Moreau-Simard (rfc2549) |
The project is part of the ansible-community organization on GitHub, with primary development on Codeberg.
Community resources: - Blog: https://ara.recordsansible.org/blog/ - Documentation: https://ara.readthedocs.io/ - Ko-fi (support): https://ko-fi.com/rfc2549
References¶
| # | Source | Type | Key Finding |
|---|---|---|---|
| [1] | ARA Project, Official Website, 2026. https://ara.recordsansible.org | Project site | ARA records Ansible playbooks and provides CLI, REST API, and web reporting |
| [2] | ARA Project, Read the Docs — v1.8.0, 2026. https://ara.readthedocs.io/en/latest/ | Official docs | Complete documentation for install, config, API, CLI, plugins, and MCP server |
| [3] | ARA Project, GitHub Repository, 2026. https://github.com/ansible-community/ara | Source code | ~2K stars, 181 forks, 45 contributors, GPLv3 |
| [4] | ARA Project, MCP Server Documentation, 2026. https://ara.readthedocs.io/en/latest/mcp-server.html | Feature docs | 13 MCP tools for LLM access to playbook data, including troubleshoot and performance analysis wrappers |
| [5] | ARA Project, Prometheus Exporter, 2026. https://ara.readthedocs.io/en/latest/prometheus-exporter.html | Feature docs | Built-in Prometheus metrics exporter added in 1.8.0 |
| [6] | ARA Project, Distribution Packages, 2026. https://ara.readthedocs.io/en/latest/distribution-packages.html | Reference | Official packages on PyPI, Fedora, Debian, Ubuntu, Arch (AUR) |
Last updated: 2026-07-30