Ansible callback plugins

Callback plugins control what the terminal shows while Ansible runs — and can integrate runs with other tools or marshall events to storage. They are the CLI-experience layer of Ansible: same playbook, same results, radically different readability. The two built-ins worth knowing first: yaml output (readable results) and profile_tasks/profile_roles (timing).

The yaml output story (the config that changed)

Geerling’s 2018 post (captured) popularized the YAML callback: default JSON-in-one-line results → human-readable YAML, no custom plugin to install (Ansible 2.5+). The configuration has since changed twice — this is the part that bites:

  • Then (pre-2.13): stdout_callback = yaml + bin_ansible_callbacks = True (the post’s original recipe)
  • Now (ansible-core 2.13+): the standalone yaml callback was deprecated and removed in community.general 12; the built-in default callback grew a result_format knob. The current correct config:
[defaults]
stdout_callback = ansible.builtin.default
 
[callback_default]
result_format = yaml

KRZ household state (verified in ~/projects/ansible-roles-rewrite/ansible.cfg): exactly this — stdout_callback = ansible.builtin.default with [callback_default] result_format = yaml, and a comment recording the removal rationale (“yaml stdout callback was removed in community.general 12”). The same repo’s scripts/ap.sh wrapper adds profile_tasks/profile_roles callbacks + timer, teeing output to _scratch/profile/ (spec 0057) — the profiling lane this note’s family rides on.

The catalog

rndmh3ro’s callback-plugin demo site (captured, 274 KB — every built-in and community callback rendered against the same demo playbook): the comparison gold standard. Same playbook, same output, per-plugin — makes the choice visual instead of documented. Highlights from the wall of outputs:

  • Readability lane: default (with result_format=yaml), unixy (dense one-line-per-task), dense (compact), debug (raw JSON-ish)
  • Timing lane: profile_tasks, profile_roles — per-task/per-role seconds, the “what is slow” answer; timer (playbook wall-clock); cgroup_perf_recap/cgroup_memory_recap (resource accounting via cgroups)
  • Integration lane: mail, jabber,hipchat/slack-class chat, loganalytics/logdna/logentries shipping, say, splunk, sumologic — marshall events to a backend
  • Aggregation lane: journal (host→task rollup), tree (per-host result files)

Why it matters (the two theses this note sits on)

  1. CLI readability is a real interface — the yaml callback is Ansible’s chapter of the readable-diagnostics genre (rustc-style errors, this vault’s zizmor/jactionlint lane): output designed for the human scanning it, not the machine emitting it. result_format=yaml is the single highest-value line in any ansible.cfg.
  2. Callbacks are the observability seam of Ansible — everything from “show me seconds per task” to “ship every event to a log backend” is the same plugin interface. The COT rewrite project already runs the profiling pair (ap.sh); the integration lane is how agent-era tooling (run summaries, LLM-friendly output formats) would plug in without touching playbooks.

Related: Ansible · Self-hosted CI-CD (the readable-output genre) · the ansible-roles-rewrite project’s ap.sh profiling wrapper