- name: Setup ZFS RAID 1 Pool for Proxmox Storage hosts: nodito become: true vars_files: - ../infra_vars.yml - nodito_vars.yml tasks: - name: Verify Proxmox VE is running command: pveversion register: pve_version_check changed_when: false failed_when: pve_version_check.rc != 0 - name: Update package cache apt: update_cache: yes cache_valid_time: 3600 - name: Install ZFS utilities package: name: - zfsutils-linux - zfs-initramfs state: present - name: Load ZFS kernel module modprobe: name: zfs - name: Ensure ZFS module loads at boot lineinfile: path: /etc/modules line: zfs state: present - name: Check if ZFS pool already exists command: zpool list {{ zfs_pool_name }} register: zfs_pool_exists failed_when: false changed_when: false - name: Check if disks are in use shell: | for disk in {{ zfs_disk_1 }} {{ zfs_disk_2 }}; do if mount | grep -q "^$disk"; then echo "ERROR: $disk is mounted" exit 1 fi if lsblk -n -o MOUNTPOINT "$disk" | grep -v "^$" | grep -q .; then echo "ERROR: $disk has mounted partitions" exit 1 fi done register: disk_usage_check failed_when: disk_usage_check.rc != 0 changed_when: false - name: Create ZFS RAID 1 pool with optimized settings command: > zpool create {{ zfs_pool_name }} -o ashift=12 -O mountpoint=none mirror {{ zfs_disk_1 }} {{ zfs_disk_2 }} when: zfs_pool_exists.rc != 0 register: zfs_pool_create_result - name: Check if ZFS dataset already exists command: zfs list {{ zfs_pool_name }}/vm-storage register: zfs_dataset_exists failed_when: false changed_when: false - name: Create ZFS dataset for Proxmox storage command: zfs create {{ zfs_pool_name }}/vm-storage when: zfs_dataset_exists.rc != 0 register: zfs_dataset_create_result - name: Set ZFS dataset properties for Proxmox command: zfs set {{ item.property }}={{ item.value }} {{ zfs_pool_name }}/vm-storage loop: - { property: "mountpoint", value: "{{ zfs_pool_mountpoint }}" } - { property: "compression", value: "lz4" } - { property: "atime", value: "off" } - { property: "xattr", value: "sa" } - { property: "acltype", value: "posixacl" } - { property: "dnodesize", value: "auto" } when: zfs_dataset_exists.rc != 0 - name: Set ZFS pool properties for Proxmox command: zpool set autotrim=off {{ zfs_pool_name }} when: zfs_pool_exists.rc != 0 - name: Set ZFS pool mountpoint for Proxmox command: zfs set mountpoint={{ zfs_pool_mountpoint }} {{ zfs_pool_name }} when: zfs_pool_exists.rc == 0 - name: Export and re-import ZFS pool for Proxmox compatibility shell: | zpool export {{ zfs_pool_name }} zpool import {{ zfs_pool_name }} when: zfs_pool_exists.rc != 0 register: zfs_pool_import_result - name: Ensure ZFS services are enabled systemd: name: "{{ item }}" enabled: yes state: started loop: - zfs-import-cache - zfs-import-scan - zfs-mount - zfs-share - zfs-zed - name: Check if ZFS pool storage already exists in Proxmox config stat: path: /etc/pve/storage.cfg register: storage_cfg_file - name: Check if storage name exists in Proxmox config shell: "grep -q '^zfspool: {{ zfs_pool_name }}' /etc/pve/storage.cfg" register: storage_exists_check failed_when: false changed_when: false when: storage_cfg_file.stat.exists - name: Set storage not configured when config file doesn't exist set_fact: storage_exists_check: rc: 1 when: not storage_cfg_file.stat.exists - name: Debug storage configuration status debug: msg: | Config file exists: {{ storage_cfg_file.stat.exists }} Storage check result: {{ storage_exists_check.rc }} Pool exists: {{ zfs_pool_exists.rc == 0 }} Will remove storage: {{ zfs_pool_exists.rc == 0 and storage_exists_check.rc == 0 }} Will add storage: {{ zfs_pool_exists.rc == 0 and storage_exists_check.rc != 0 }} - name: Remove existing storage if it exists command: pvesm remove {{ zfs_pool_name }} register: pvesm_remove_result failed_when: false when: - zfs_pool_exists.rc == 0 - storage_exists_check.rc == 0 - name: Add ZFS pool storage to Proxmox using pvesm command: > pvesm add zfspool {{ zfs_pool_name }} --pool {{ zfs_pool_name }} --content rootdir,images --sparse 1 when: - zfs_pool_exists.rc == 0 - storage_exists_check.rc != 0 register: pvesm_add_result - name: Verify ZFS pool is healthy command: zpool status {{ zfs_pool_name }} register: final_zfs_status changed_when: false - name: Fail if ZFS pool is not healthy fail: msg: "ZFS pool {{ zfs_pool_name }} is not in a healthy state" when: "'ONLINE' not in final_zfs_status.stdout"