Files
computer-playbook/plugins
kevinveenbirkenbachandClaude Opus 5.5 91f29d332e perf(spot): carry the rendered users next to the applications
Ansible forks a fresh worker per task, so every lookup('users') in a forked worker re-rendered the whole user catalogue (298 users, 0.3 to 0.5 s locally and about 1 s on the runner, 1 s locally once a users password is vaulted): _MERGED_USERS_CACHE lives in the process and had no carrier fact.

applications_carrier now also parks lookup('users', carrier=True) in _INFINITO_USERS_RENDERED at the same park points, and clear drops both facts. get_merged_users serves the fact to templated reads when its key matches: the applications carrier key (roles dir, applications, users, DOMAIN_PRIMARY, SYSTEM_EMAIL_DOMAIN, group_names, token store digest) plus inventory_hostname, so a carrier a run_once park broadcasts never answers another host with its become password. A park whose users carrier still matches leaves it in place instead of returning 119 KB again, so parks cost what they cost before.

Real ansible-playbook harness on 2.20.6 and 2.21.5 with the real roles tree: users renders per users-reading task after a park 1 -> 0, task 0.56 -> 0.08 s (vaulted 1.21 -> 0.17 s); a rotated token, a rotated inventory password, a cleared carrier and another host's carrier all re-render; 32 of 32 probe digests equal HEAD's. Removing the carrier check fails three unit tests. The stalwart swarm roundtrip pass 1 and its DR drill ran green with it on all nodes, with no 401 from JMAP, msmtp or LDAP.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-29 15:53:34 +01:00
..
…

Ansible Plugins (plugins/) 🧩

This document is the central reference for plugin types and plugin placement in Infinito.Nexus.

Not to be confused with application addons. This plugins/ directory holds Ansible plugins (action / filter / lookup) that extend the automation engine itself. Some applications also call their own extensions "plugins" (e.g. Nextcloud, WordPress). Those application-level extensions, whatever the app calls them natively, are declared through the unified meta/addons/ contract, documented in Unified Addons. An app "plugin" is an addon; an Ansible plugin lives here.

Current Project Layout 🗂️

plugins/
├── action/   # custom action plugins
├── filter/   # custom Jinja2 filters
└── lookup/   # custom lookup plugins

Configured plugin paths in this repository are defined in ansible.cfg:

  • action_plugins = ./plugins/action
  • filter_plugins = ./plugins/filter
  • lookup_plugins = ./plugins/lookup

All Common Ansible Plugin Types 📚

The table below summarizes common Ansible plugin types and their conventional directory names.

Emoji Plugin Type Conventional Directory Purpose
⚙️ action action_plugins/ or plugins/action/ Wrap/extend module execution behavior at task runtime.
🔐 become become_plugins/ Implement privilege escalation methods.
💾 cache cache_plugins/ Persist gathered facts and cached data between runs.
📣 callback callback_plugins/ React to play/task events (logging, reporting, notifications).
🖧 cliconf cliconf_plugins/ Define CLI command transport behavior (mainly network platforms).
🔌 connection connection_plugins/ Control how Ansible connects to targets (ssh, local, etc.).
🔍 filter filter_plugins/ or plugins/filter/ Add Jinja2 filters for data transformation.
🌐 httpapi httpapi_plugins/ API transport layer over HTTP(S), mainly for network devices.
🧭 inventory inventory_plugins/ Build dynamic inventories from APIs, services, or files.
👉 lookup lookup_plugins/ or plugins/lookup/ Resolve dynamic values during playbook processing.
🛰️ netconf netconf_plugins/ NETCONF transport integration for network automation.
🐚 shell shell_plugins/ Adjust shell command wrapping/execution behavior.
🧠 strategy strategy_plugins/ Customize task scheduling/execution strategy.
✅ test test_plugins/ Add Jinja2 tests used in conditions and templates.
📦 vars vars_plugins/ Load variables from custom sources.

Which Plugin Type to Use 🧭

action ⚙️

Use when task execution behavior itself must be changed or wrapped.

Examples:

  • centralized retry logic (uri_retry.py),
  • argument normalization before module dispatch,
  • pre/post task orchestration.

filter 🔍

Use for pure data transformation in Jinja2 expressions.

Examples:

  • mapping/normalizing dictionaries,
  • deriving computed fields for templates,
  • deterministic formatting helpers.

lookup 👉

Use when a value must be dynamically resolved at runtime.

Examples:

  • computing IDs from role metadata,
  • resolving paths/version data,
  • reading structured project data for templates/tasks.

callback 📣

Use to hook into execution events and shape output/reporting.

inventory 🧭

Use when host/group data should come from a dynamic source.

strategy 🧠

Use to alter how tasks are scheduled/executed across hosts.

vars 📦

Use to load variables from custom backends.

connection, become, shell 🔌🔐🐚

Use to customize low-level execution and privilege mechanics.

cache 💾

Use to persist facts/results across runs for performance and consistency.

cliconf, httpapi, netconf 🖧🌐🛰️

Use in network automation contexts requiring protocol-specific transport behavior.

test ✅

Use to add custom Jinja2 test operators for conditional logic.

Best Practices 🧪

  • Keep plugin interfaces explicit and stable.
  • Keep plugin logic focused; move shared logic to utils/.
  • Add unit tests for plugin behavior and integration tests for end-to-end flows.
  • Prefer deterministic outputs and avoid hidden global state.
  • Document any plugin-specific task arguments in the plugin docstring and README.

References 🔗