hosts.yml repeated the same authentication block for 13 LXC hosts and
carried 13 byte-identical copies of the ru-vps ProxyCommand. Describe the
transport once in ansible/ssh_config instead: jump host, per-host users,
keys, and the fact that pbs and ovpn-mini are reached directly rather
than through ru-vps.
Ansible loads that file through ansible_ssh_common_args in
group_vars/all/main.yml, where the path is derived from inventory_dir so
it depends on neither the current directory nor the clone location.
The same file makes `ssh gitea` work from a plain terminal once
~/.ssh/config includes it.
hosts.yml drops from 209 to 137 lines and now holds only addresses and
per-host facts. Verified equivalent: ansible-inventory --list before and
after differ only by the removed ansible_ssh_common_args, with group
membership and ordering byte-identical.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
Configure yamllint and ansible-lint, plus a workflow running yamllint,
ansible-lint and ansible-playbook --syntax-check over every playbook.
ansible-lint uses the moderate profile: on the current code it reports
exactly the same violations as basic, so it costs nothing today while
holding a higher bar for new code. skip_list is empty; noisy legacy
rules go to warn_list with a comment on why and when to restore them.
Correctness and safety rules stay fatal.
Two constraints are encoded in the workflow: syntax-check must run from
ansible/ because roles_path is relative, and ansible-lint needs absolute
ANSIBLE_ROLES_PATH/ANSIBLE_COLLECTIONS_PATH when run from the root.
The runner is not registered yet; registration notes are in the workflow.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
Replace the Python venv with a Nix devshell pinning ansible-core 2.21.3,
ansible-lint, yamllint and a Python with proxmoxer/requests. The Python
dependencies share the interpreter that runs ansible, so pve-*.yml plays
on implicit localhost can import proxmoxer without inventory changes.
The shellHook exports absolute ANSIBLE_CONFIG, ANSIBLE_INVENTORY,
ANSIBLE_ROLES_PATH and ANSIBLE_COLLECTIONS_PATH, so commands work from
the repository root as well as from ansible/.
Also un-ignore .envrc, which the global gitignore hides, and ignore the
stray .ansible/ runtime directory.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
Commit the accumulated infrastructure work that was living only in the
working tree: monitoring stack, emergency access/bot, gyro allocator,
grimmory, adguard, backup audit and the OpenCode agent definitions.
Also ignore Python bytecode, local archives and Nix/direnv artifacts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71