Files
documentation/procedures/ansible-playbook/ADDITIONAL_NOTES.md
F.R.I.D.A.Y. ba84a78268 procedures/ansible-playbook: Add NFS client role documentation
- Full README.md with task breakdown, inventory targeting, TrueNAS requirements
- ADDITIONAL_NOTES.md with per-node key nuances, repogroup mapping, mount opts evolution
- Included canonical copies of: inventory.yml, main.yml, roles/nfs_client/tasks/main.yml
- Covers TrueNAS maproot/ACL interaction and jarvis write access patterns
2026-06-04 09:28:50 -04:00

3.5 KiB

Additional Notes — Ansible NFS Playbook (Iron Legion)

Date: 2026-06-04 | Author: Artemis (AI Foreman)


Nuance 1: ansible_ssh_private_key_file per node

Most fleet nodes use the standard id_ed25519 key (auto-discovered). Mark44 requires vscode_ed25519 — the code-server key. Because it's a special case, mark44's inventory block sets:

mark44:
  ansible_host: 192.168.5.214
  ansible_user: jarvis
  ansible_ssh_private_key_file: /root/.ssh/vscode_ed25519

Don't change this to id_ed25519 — mark44's authorized_keys only contains:

  1. The Termius key (artemis_key)
  2. The vscode_ed25519 key

The artemis_key is NOT auto-discovered by Ansible because the filename is non-standard. Keep the explicit ansible_ssh_private_key_file for mark44.


Nuance 2: What the repogroup actually is

repogroup is a local alias for TrueNAS's apps group (GID 568). The mapping works like this:

System Group Name GID
TrueNAS apps 568
Client repogroup 568

NFSv4 identity mapping sees the numeric GID only, not the symbolic name. So "jarvis in group 568" on the client maps to "jarvis in group apps" on TrueNAS.

No TrueNAS-side user creation is needed on clients. We only need the local group with the matching GID.


Nuance 3: NFS mount opts evolution

Stage Mount opts Result
Old (broken) defaults,_netdev Mount failed — TrueNAS rejects unversioned (v3) negotiation
Current vers=4.2,proto=tcp,_netdev Mount succeeds; root can RWX

The proto=tcp is required because UDP negotiation can silently fall back and fail on large packets.


Nuance 4: Why ansible.posix.mount instead of mount module

The native Ansible ansible.posix.mount module handles idempotency correctly:

  • If already mounted at the same src + path + opts, reports ok
  • If opts don't match, reports changed and remounts
  • If state: mounted, ensures /etc/fstab entry is added

Manual shell: mount ... would create duplicate fstab entries.


Nuance 5: TrueNAS server-side chmod 775 on /mnt/Ice/Repo

This was applied as an emergency fix during debugging. The correct long-term approach would be to add a proper NFS4 ACL entry for jarvis (UID 1000) via TrueNAS WebUI or midclt API, but the chmod 775 workaround is sufficient for production.

Command used (for record):

ssh -i ~/.ssh/artemis_key jarvis@192.168.16.254 'sudo chmod 775 /mnt/Ice/Repo'

Nuance 6: Host targeting syntax edge cases

Ansible supports two exclusion syntaxes:

  1. Union + subtraction: hosts: fleet_nodes:!pve_hosts:!igor Working
  2. Direct group list: hosts: physical_agents:core_services:infrastructure Broken — nfs_shares variable is scoped under fleet_nodes, not these child groups

The inventory variable nfs_shares is defined at fleet_nodes level. Exclusion from fleet_nodes is the only way to get the variable AND exclude specific children.


Nuance 7: Container vs bare-metal execution

When running Ansible inside the Docker container (docker exec -it ansible ...):

  • SSH keys mount to /root/.ssh inside container
  • ansible.cfg lives in /ansible (container working dir)

When running Ansible on the host (Artemis bare metal):

  • SSH keys at /home/jarvis/.ssh
  • ansible.cfg may be in /home/jarvis/.ansible-repo or current dir

The playbooks are identical but paths may differ. Always run from the project root where ansible.cfg and inventory files exist.