Files
computer-playbook/plugins
kevinveenbirkenbachandClaude Opus 5.5 437437aa7d perf(spot): keep carriers per host and reuse the mail provider's
The nested carrier in tasks/utils/load/app.yml inherited run_once from the apply of sys-stk-full's front-proxy include, so ansible-core wrote the stack host's carrier, keyed with its group_names, to every play host. Workers and the NFS server then missed their own key and re-rendered the whole applications SPOT on the next carrier and on every task that read it. run_once: false keeps each host's carrier.

The email lookup's onion check renders the provider host's group view, a key no carrier on a worker holds, so every lookup('email') there rendered the whole SPOT: 8-11 s per task, 17 tasks per swarm pass in the stalwart roundtrip. Hand the provider host's carrier, read untemplated via hostvars.raw_get, to that view; get_merged_applications still serves it only when its key matches and renders as before otherwise.

Each bug hid the other: fixing either alone only moves the misses. Together they remove about 142 s per swarm pass. With real ansible-playbook and HostVars the worker email task drops from 3.97 s to 0.77 s on ansible-core 2.20.6 and from 4.22 s to 0.70 s on 2.21.5 with the same result; the new tests fail with the reuse disabled.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-29 10:51:09 +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 🔗