# Ansible Playbook — NFS Client Role PRD **Status:** Deployed | **Author:** Artemis | **Date:** 2026-06-04 > **Deployed:** Standardized NFS client mount for fleet Debian nodes. Mounts TrueNAS `Repo` dataset to `/home/jarvis/repo` on all non-PVE, non-ZimaOS nodes. Role tested and validated against MK7 and Swarm workers. --- ## 1. Purpose Standardized NFS client mounting for fleet Debian nodes. Ensures `/home/jarvis/repo` is available fleet-wide for shared scripts, compose files, and configuration storage. --- ## 2. Scope | Target | Action | |--------|--------| | Debian fleet nodes (MK7, Swarm workers) | Install `nfs-common`, mount NFS share | | PVE nodes (MK33/34/39) | Excluded — TrueNAS ACL blocks 192.168.192.0/27 | | ZimaOS (igor, MK-46) | Excluded — `ansible_os_family != "Debian"` | --- ## 3. Files | File | Location | Purpose | |------|----------|---------| | `main.yml` | `~/documentation/procedures/ansible-playbook/` | Playbook entry point | | `inventory.yml` | `~/documentation/procedures/ansible-playbook/` | Host definitions + `nfs_shares` variable | | `roles/nfs_client/tasks/main.yml` | `~/documentation/procedures/ansible-playbook/roles/nfs_client/tasks/` | Role: install, mount, fix permissions | --- ## 4. Role Task Breakdown ### 4.1 Install nfs-common ```yaml - name: Install nfs-common ansible.builtin.apt: name: nfs-common state: present become: true when: ansible_os_family == "Debian" ``` ### 4.2 Create mount directory ```yaml - name: Ensure NFS mount directory exists ansible.builtin.file: path: "{{ item.local_path }}" state: directory owner: "jarvis" group: "jarvis" mode: '0755' become: true loop: "{{ nfs_shares }}" ``` ### 4.3 Mount NFS share ```yaml - name: Mount NFS share ansible.posix.mount: src: "{{ item.server }}:{{ item.remote_path }}" path: "{{ item.local_path }}" fstype: nfs opts: "{{ item.options | default('defaults') }}" state: mounted become: true loop: "{{ nfs_shares }}" ``` ### 4.4 Fix mount ownership ```yaml - name: Ensure mounted directory is owned by jarvis ansible.builtin.file: path: "{{ item.local_path }}" owner: "jarvis" group: "jarvis" recurse: yes become: true loop: "{{ nfs_shares }}" ``` --- ## 5. Inventory Variables ```yaml nfs_shares: - server: "192.168.16.254" remote_path: "/mnt/Ice/Repo" local_path: "/home/jarvis/repo" options: "vers=4.2,proto=tcp" ``` --- ## 6. Deployment Notes | Decision | Value | Rationale | |----------|-------|-----------| | NFS version | `4.2` | TrueNAS SCALE 25.10.2 default | | Transport | `tcp` | Required for NFSv4.2 | | Mount point | `/home/jarvis/repo` | Fleet standard shared workspace | | Owner | `jarvis:jarvis` | Fleet-wide standard user | | TrueNAS path | `/mnt/Ice/Repo` | Dataset-backed export (not `/repo`) | | ACL restriction | `192.168.0.0/18` | Neo (192.168.192.0/27) excluded | --- ## 7. Execution ```bash # From ~/docker/ansible-push/ docker compose run --rm ansible \ ansible-playbook -i procedures/ansible-playbook/inventory.yml \ procedures/ansible-playbook/main.yml ``` Or directly on any Ansible-capable node: ```bash ansible-playbook -i ~/documentation/procedures/ansible-playbook/inventory.yml \ ~/documentation/procedures/ansible-playbook/main.yml ``` --- ## 8. Validated On | Node | Date | Result | |------|------|--------| | MK7 (mark-vii) | 2026-06-04 | ✅ Mounted, accessible | | MK33/34/39 | — | ❌ Excluded (TrueNAS ACL) | | Neo | — | ❌ Excluded (192.168.192.0/27) | | Igor (MK-38) | — | ❌ Excluded (ZimaOS, not Debian) | --- ## 9. Future Work - Phase 2: Expand to additional NFS exports (`/mnt/Ice/Backup`) - Phase 3: Add `fstab` persistence check and remount logic - Phase 4: Create separate playbook for Neo NFS proxy via MK7 jump host