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

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:

  • 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:

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 and publishing from CI.

The one-file version

If ARA is more than the situation needs:

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.

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.

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 →

Related