Files
computer-playbook/docs/contributing/artefact/files/plugins/lookup/users.md
T
kevinveenbirkenbachandClaude Opus 4.7 256e027525 docs: drop stale requirement refs + reflow soft-wraps to one sentence per line
Removes 67 live references to docs/requirements/<NNN>-*.md files across
43 contributor docs, role READMEs, code comments, task files, and tests.
Requirement docs are initial-creation-only artefacts; live references
freeze a snapshot that rots once the per-feature SPOT (a contributor
doc, a code module, a lint test) takes over the live behaviour.

In the same pass, fixes documentation.md violations on the touched
files: drops em-dashes used as thought breaks, removes "SPOT for ..."
self-labels, strips historical phrasing ("the legacy", "previously",
"used to", "is no longer used", "matching the historical"), and
reflows soft-wrapped sentences so each sentence stays on one logical
line.

The `test_inventory_vars_file_spot.py` whitelist for the literal
inventory path drops the docs/requirements/003 entry and instead
skips docs/requirements/ entirely; future requirement docs that
mention the literal path are then ignored automatically.

Verified by tests/lint/repository/test_no_stale_requirement_refs.py
(green tree-wide).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 05:00:46 +02:00

3.9 KiB
Raw Blame History

users lookup 👥

Contributor-facing rules for the users.py lookup plugin. For general documentation rules such as links, writing style, RFC 2119 keywords, and Sphinx behavior, see documentation.md.

Access Pattern 🎯

The users lookup is the ONLY supported runtime entry point for merged user configuration.

  • Runtime consumers (roles, playbooks, templates, filter plugins, lookup plugins, tests) MUST read user data via lookup('users') or a wrapper that calls it.
  • Consumers MUST NOT materialize a top-level users fact via ansible.builtin.set_fact, combine, or any custom aggregation task.
  • Consumers MUST NOT reintroduce group_vars/all/04_users.yml or any equivalent generated dictionary file.

Lookup Forms 🧭

Form Returns
lookup('users') Full merged mapping keyed by the canonical user key.
lookup('users', '<canonical_user_key>') Merged entry for that user. Raises when missing.
lookup('users', '<canonical_user_key>', default_value) Merged entry, or default_value when the entry is missing.

Data Sources 📚

The lookup merges exactly two sources:

  1. Defaults discovered from every roles/*/meta/users.yml in the repository (file root IS the users map; no users: wrapper).
  2. Overrides supplied through the normal Ansible variable users in inventory, group vars, host vars, or role vars.

No intermediate merged users fact exists. No other source is consulted.

Canonical User Key 🔑

  • The canonical key is the mapping key used at the file root of roles/*/meta/users.yml.
  • The canonical key is NOT the rendered username field inside the value.
  • The canonical key is the same identifier that inventory, group vars, host vars, and role vars MUST use when overriding an entry.
  • You MUST NOT introduce a new keying scheme.

Adding a User Entry ➕

You MUST add new user defaults in the owning role:

  1. Create or edit roles/<role_id>/meta/users.yml.

  2. Add the user at the file root, keyed by its canonical key (no users: wrapper):

    # roles/<role_id>/meta/users.yml
    administrator:
      username: administrator
      roles:
        - admin
    
  3. Keep generated fields (UID, GID, email, description, password) unset when the shared aggregation logic SHOULD allocate or template them. Set them explicitly only when the role requires a specific value.

The lookup discovers the entry automatically on the next run. No generator step is required.

Overriding a User Entry 🛠️

You MUST override user values through the normal Ansible variable users:

# group_vars/<group>.yml or host_vars/<host>.yml
users:
  administrator:
    email: admin@example.org
  • Overrides MUST use the canonical user key.
  • Overrides merge recursively on top of role-local defaults.
  • Overrides MUST NOT be written back into roles/*/meta/users.yml; that file is for defaults only.

What Not To Do 🚫

  • You MUST NOT create group_vars/all/04_users.yml or any similar generated users dictionary.
  • You MUST NOT add a make target, script, or role task whose purpose is to generate, render, merge, or rewrite such a file.
  • You MUST NOT key user overrides by username; use the canonical key.
  • You MUST NOT reintroduce default_users or defaults_users references; they do not exist anymore.

Source Of Truth 📌

File Purpose
users.py Runtime entry point for the users lookup.
users.py (cache) Shared aggregation helper that builds and caches defaults, handles reserved users, UID/GID allocation, and uniqueness validation.
test_users.py Unit tests covering the full-dict, single-entry, override, strict missing, and non-strict missing cases.

For the related applications pattern see applications.md.