# Ansible Playbook — NFS Client Role (Iron Legion) **Status:** Canonical | **Last updated:** 2026-06-04 ## 1. Purpose Standardized NFS client mounting for fleet Debian nodes. Mounts the TrueNAS `Repo` dataset (`/mnt/Ice/Repo`) to `/home/jarvis/repo` on all non-PVE, non-igor nodes. --- ## 2. Files | File | Purpose | |------|---------| | `roles/nfs_client/tasks/main.yml` | Role tasks: install package, create dirs, create repogroup, mount NFS, fix permissions | | `inventory.yml` | Host definitions + `nfs_shares` variable | | `main.yml` | Playbook entry point: target selection | --- ## 3. Role Task Breakdown ### 3.1 Install nfs-common ```yaml - name: Install nfs-common ansible.builtin.apt: name: nfs-common state: present become: true when: ansible_os_family == "Debian" ``` - Guard: only runs on Debian family (excludes ZimaOS/igor). ### 3.2 Create mount directory ```yaml - name: Ensure NFS mount directories exists ansible.builtin.file: path: "{{ item.path }}" state: directory mode: '0755' owner: jarvis group: jarvis become: true loop: "{{ nfs_shares }}" ``` - Owner set to `jarvis` (NOT root) because user jarvis needs to access files after mount. ### 3.3 Create local `repogroup` (GID 568) ```yaml - name: Create local repogroup matching TrueNAS GID 568 ansible.builtin.group: name: repogroup gid: 568 state: present become: true ``` - TrueNAS `apps` group uses GID 568. Creating a local group with the same GID maps jarvis's supplementary group across the NFSv4 identity boundary. ### 3.4 Add jarvis to repogroup ```yaml - name: Add jarvis to repogroup ansible.builtin.user: name: jarvis groups: - repogroup append: true become: true ``` - After relogin (or `sg repogroup`), jarvis inherits group 568 write access. ### 3.5 Mount NFS (root required) ```yaml - name: Mount an NFS volume (root, because kernel mount) ansible.posix.mount: src: "{{ item.src }}" path: "{{ item.path }}" opts: "vers=4.2,proto=tcp,_netdev" state: mounted fstype: nfs become: true loop: "{{ nfs_shares }}" ``` - Kernel mount requires root. `vers=4.2` required because TrueNAS SCALE 25.10.2 exports NFSv4.2 only; `defaults` fails silently. ### 3.6 Fix mount permissions ```yaml - name: Set mount permissions so jarvis (repogroup member) can write ansible.builtin.file: path: "{{ item.path }}" mode: '0770' owner: root group: repogroup become: true loop: "{{ nfs_shares }}" ``` - Mountpoint inherits remote permissions from TrueNAS, but the underlying local permission layer is `770` with group `repogroup`. --- ## 4. Inventory Host Targeting ```yaml - name: Install NFS client hosts: fleet_nodes:!pve_hosts:!igor become: false roles: - nfs_client ``` **Rationale:** - PVE nodes (`mk33`, `mk34`, `mk39`) already have TrueNAS mounts via Proxmox integration. Don't double-mount. - `igor` is ZimaOS (non-Debian) and can't run `apt`. - Group exclusion syntax: `fleet_nodes:!pve_hosts:!igor` --- ## 5. TrueNAS Server-Side Companion ### Dataset: `/mnt/Ice/Repo` | Setting | Value | |---------|-------| | NFS version | 4.2 | | Maproot user | `pveuser` (UID 3003) | | Dataset owner | `root` (UID 0) | | Dataset group | `apps` (GID 568) | | Dataset permissions | `775` | **Why 775 on TrueNAS:** - Without 775, jarvis (who is `other` in the NFS identity mapping) sees `drwxrwx---` and gets permission denied on listing. - With 775 (`drwxrwxr-x`), jarvis gains `read + execute` through the "other" bit. - Through the supplementary group path, jarvis gets `read + write` via group 568 after repogroup is applied. --- ## 6. Tested Behavior | Action | Result | |--------|--------| | `sudo mount` | OK — root mounts, `mountpoint` returns true | | `ls -la /home/jarvis/repo` | OK — all TrueNAS files visible | | `touch` without relogin | FAIL — Permission denied (jarvis hasn't picked up new group in current shell) | | `sg repogroup -c "touch ..."` | OK — works immediately | | `touch` after relogin | OK — jarvis has repogroup in new shell | --- ## 7. Caveats 1. **NFSv4 identity mapping** requires supplemental groups. They are NOT transmitted across NFSv4 by default in Linux. The local `repogroup` creation is the workaround. 2. **TrueNAS 775** is the non-Negotiable server-side change. Without it, jarvis gets no access. 3. **Reboot or relogin** required on client after first `repogroup` addition. The group change doesn't apply retroactively to existing sessions. 4. **Kernel mount must be root** — don't try user-space NFS (FUSE). It fails for non-root users without `fusermount3` and proper `/etc/fuse.conf`. --- ## 8. Changelog | Date | Change | Author | |------|--------|--------| | 2026-06-03 | Initial playbook + inventory validation | Artemis | | 2026-06-04 | Added repogroup + permission fix after TrueNAS 775 | Artemis |