# PURPOSE: Show disk usage # DESCRIPTION: Report attached Windows volumes and common operational Linux mounts. # TARGETS: windows, linux # INPUTS (omitted values inherit inventory / role defaults): # aim_debug [bool]: false # AUTH: existing inventory / Vault credentials; no embedded passwords. # NOTES: # Windows reports attached storage volumes from community.windows.win_disk_facts; mapped/network drives are excluded. # Linux excludes pseudo/system mounts and reports common operational paths plus network/storage filesystems. # EXAMPLE: ansible-playbook -i inventories//hosts.yml # playbooks/debug_show_disk_usage.yml --limit --vault-id @prompt - name: Debug | Windows disk usage hosts: windows gather_facts: false tasks: - name: AIM | Validate diagnostics option ansible.builtin.assert: that: - (aim_debug | default(false)) is boolean or (aim_debug | default(false) | string | lower) in ['true', 'false'] fail_msg: aim_debug must be a YAML/JSON boolean. quiet: true - name: AIM | Reject mixed platform membership ansible.builtin.assert: that: - (group_names | intersect(['linux', 'windows', 'sophosxgs', 'pfsense']) | length) <= 1 fail_msg: This host belongs to incompatible platform groups. Use globally unique subgroups. quiet: true - name: AIM | Execution context ansible.builtin.debug: msg: host: '{{ inventory_hostname }}' diagnostics: Enabled; secret values are never included by this task. when: aim_debug | default(false) | bool - name: Windows | Gather attached disk and volume facts community.windows.win_disk_facts: filter: - partitions - volumes changed_when: false - name: Windows | Normalize attached volume usage ansible.builtin.set_fact: _windows_disk_report: "{{ ansible_facts.disks | default([]) | aim_report_disks('windows') }}" - name: Windows | Print disk usage ansible.builtin.debug: msg: |- {{ inventory_hostname }} {% for d in _windows_disk_report.filesystems | default([]) %} {% if d.status == 'available' %} {{ '%-18s' | format(d.name) }} {{ (d.used_bytes / 1073741824) | round(2) }} GB / {{ (d.total_bytes / 1073741824) | round(2) }} GB | {{ d.used_percent | round(1) }}% used | {{ (d.available_bytes / 1073741824) | round(2) }} GB free | {{ d.filesystem_type | default('unknown', true) }} | {{ d.mount }} {% else %} {{ '%-18s' | format(d.name) }} unavailable | {{ d.mount }} {% endif %} {% endfor %} - name: AIM | Publish operation result ansible.builtin.set_stats: per_host: true aggregate: false data: aim_output: protocol: aim_output_v1 schema: filesystem_usage_v1 data: "{{ _windows_disk_report }}" - name: Debug | Linux disk usage hosts: linux gather_facts: false become: false vars: _disk_common_mounts: - / - /boot - /boot/efi - /home - /var - /var/log - /tmp - /opt - /srv _disk_network_storage_fstypes: - nfs - nfs4 - cifs - smb3 - ceph - glusterfs - fuse.sshfs - fuse.glusterfs _disk_excluded_fstypes: - proc - sysfs - devtmpfs - tmpfs - cgroup - cgroup2 - overlay - squashfs - nsfs - tracefs - debugfs - securityfs - pstore - configfs - hugetlbfs - mqueue - rpc_pipefs - autofs - fusectl - binfmt_misc tasks: - name: AIM | Validate diagnostics option ansible.builtin.assert: that: - (aim_debug | default(false)) is boolean or (aim_debug | default(false) | string | lower) in ['true', 'false'] fail_msg: aim_debug must be a YAML/JSON boolean. quiet: true - name: AIM | Reject mixed platform membership ansible.builtin.assert: that: - (group_names | intersect(['linux', 'windows', 'sophosxgs', 'pfsense']) | length) <= 1 fail_msg: This host belongs to incompatible platform groups. Use globally unique subgroups. quiet: true - name: Linux | Collect mount facts ansible.builtin.setup: filter: - ansible_mounts gather_subset: - '!all' - '!min' changed_when: false - name: Linux | Reset selected mount report ansible.builtin.set_fact: _linux_disk_mounts: [] - name: Linux | Select common operational mounts ansible.builtin.set_fact: _linux_disk_mounts: '{{ (_linux_disk_mounts | default([])) + [item] }}' loop: '{{ ansible_facts.mounts | default(ansible_mounts | default([])) }}' loop_control: label: "{{ item.mount | default('?') }}" when: - item.fstype | default('') not in _disk_excluded_fstypes - >- (item.mount | default('')) in _disk_common_mounts or (item.mount | default('')).startswith('/mnt/') or (item.mount | default('')).startswith('/media/') or (item.fstype | default('')) in _disk_network_storage_fstypes - name: Linux | Execution context ansible.builtin.debug: msg: host: '{{ inventory_hostname }}' selected_mounts: "{{ (_linux_disk_mounts | default([])) | map(attribute='mount') | list }}" diagnostics: Enabled; pseudo/system mounts are excluded. when: aim_debug | default(false) | bool - name: Linux | Print disk usage ansible.builtin.debug: msg: |- {{ inventory_hostname }} {% for m in (_linux_disk_mounts | default([]) | sort(attribute='mount')) %} {% set total = m.size_total | default(0) | float %} {% set free = m.size_available | default(0) | float %} {% set used = total - free %} {% set pct = ((used / total) * 100) if total > 0 else 0 %} {{ '%-18s' | format(m.mount) }} {{ (used / 1073741824) | round(2) }} GB / {{ (total / 1073741824) | round(2) }} GB | {{ pct | round(1) }}% used | {{ (free / 1073741824) | round(2) }} GB free | {{ m.fstype }} {% endfor %} - name: AIM | Publish operation result ansible.builtin.set_stats: per_host: true aggregate: false data: aim_output: protocol: aim_output_v1 schema: filesystem_usage_v1 data: "{{ _linux_disk_mounts | aim_report_disks('linux') }}"