# Share an Ansible Playbook Report — ARA Output at a URL

Canonical: https://commareports.com/share-ansible-report
Published: 2026-09-14

> ARA records every Ansible task and generates a static HTML report. Publish it to Comma for a link per run: hosts, tasks, failures and durations, with comments where they matter.

# Share an Ansible playbook report

An Ansible run is a scrollback buffer. It is also, quite often, the only record
that a change was made to sixty servers — which host was skipped, which task
was `changed`, why one box failed at the ninth play and the operator moved on.

The default callback is designed to be watched live, not read later. So the
question "what exactly did that deploy do on `web-07`?" is answered by
scrolling a terminal, or not at all.

## ARA turns the run into a record

```bash
pip install ara
export ANSIBLE_CALLBACK_PLUGINS="$(python -m ara.setup.callback_plugins)"

ansible-playbook -i inventory/prod site.yml

ara-manage generate ./ara-static
```

```
ara-static/
├── index.html      # playbook runs, status, duration
├── playbooks/  hosts/  results/
└── static/
```

Every task result, per host, with the duration and the returned data. The
per-host view is the one that answers real questions: what ran on `web-07`, in
what order, and what it changed.

## Publish the folder

Drag `ara-static/` (or a zip of it) into [Comma](https://commareports.com/):

- `index.html` becomes the **report body**.
- Playbook, host and result pages upload alongside it, with relative references
  rewritten to the uploaded copies, so the drill-down works.
- Scripts run inside a sandboxed iframe (`allow-scripts`, no
  `allow-same-origin`).

From CI or a bastion:

```bash
ara-manage generate ./ara-static

curl -fsS -X POST "https://commareports.com/api/v1/reports" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html ara-static/index.html \
        --arg t "Deploy — prod — $(date -u +%FT%TZ)" '{title: $t, html: $html}')"
```

Supporting pages go up through `POST /api/v1/reports/$REPORT_ID/assets` as
base64 — see the [API reference](/docs/api) and
[publishing from CI](/docs/ci).

## The one-file version

If ARA is more than the situation needs:

```bash
ANSIBLE_FORCE_COLOR=1 ANSIBLE_STDOUT_CALLBACK=yaml \
  ansible-playbook -i inventory/prod site.yml 2>&1 | ansi2html > run.html
```

One HTML file, colour preserved, readable by anyone with the link. Good enough
for "here is what the migration did", which is most of the demand.

## Why a link beats a paste

Ansible runs get discussed by people who were not watching them: the service
owner asking whether the config landed, the on-call engineer correlating a
restart with an alert, the auditor asking for evidence of a change window.

A published run gives all of them the same artifact. Anchored comments keep the
explanation on the task — "web-07 failed because it was still draining; re-ran
at 21:40" — instead of in a channel that scrolls. See
[commenting on HTML](/comment-on-html).

## Redact and restrict

Task results include returned data, which can include command output and, if a
task is careless, secrets. Use `no_log: true` on tasks that handle credentials
— that applies before ARA records anything — and set report access to private
or team. See [sharing & access control](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, **250 MB and 500 files total**.
  A run across hundreds of hosts generates a lot of result pages — export per
  playbook, or publish the index plus the hosts that failed.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision
history.

**[Publish a run report →](https://commareports.com/)**

### Related

- [Share a Terraform plan](/share-terraform-plan) · [Share a CDK diff](/share-cdk-diff)
- [Share a Pulumi preview](/share-pulumi-preview) · [Share an InSpec report](/share-inspec-report)
- [Share a pgBadger report](/share-pgbadger-report) · [Publishing from CI](/docs/ci)
