--- - name: Converged Proxmox & Optional Linstor Deployment hosts: proxmox become: true gather_facts: true any_errors_fatal: true vars: corosync_ip: "{{ priv_ip | default(ansible_host) }}" master_corosync_ip: "{{ hostvars[groups['proxmox'][0]]['priv_ip'] | default(hostvars[groups['proxmox'][0]]['ansible_host']) }}" is_master: "{{ inventory_hostname == groups['proxmox'][0] }}" tasks: # ========================================== # PHASE 1: REPOSITORIES & LICENSING # ========================================== - name: Apply Proxmox Enterprise Key ansible.builtin.command: pvesubscription set -k {{ pve_enterprise_key }} when: pve_enterprise_key | length > 0 register: pve_key_result changed_when: "'successfully' in pve_key_result.stdout" - name: Manage Proxmox Enterprise Repository ansible.builtin.lineinfile: path: /etc/apt/sources.list.d/pve-enterprise.list regexp: '^#?deb https://enterprise.proxmox.com/debian/pve' line: "{{ '' if pve_enterprise_key | length > 0 else '#' }}deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise" state: present - name: Manage Proxmox No-Subscription Repository ansible.builtin.apt_repository: repo: 'deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription' state: "{{ 'absent' if pve_enterprise_key | length > 0 else 'present' }}" filename: pve-no-subscription - name: Add Linstor Repositories ansible.builtin.include_role: name: linstor_repo when: deploy_linstor | bool # ========================================== # PHASE 2: UPDATES & NAG REMOVAL # ========================================== - name: Update APT cache and run dist-upgrade ansible.builtin.apt: update_cache: yes upgrade: dist autoremove: yes register: apt_upgrade - name: Remove Proxmox Subscription Nag (JS Patch) ansible.builtin.replace: path: /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js regexp: "(Ext.Msg.show\\(\\{\\s+title: gettext\\('No valid subscription'\\),)" replace: "void({ //\\1" notify: Restart pveproxy - name: Install Linstor Packages ansible.builtin.include_role: name: linstor_install when: deploy_linstor | bool - name: Reboot if kernel was updated ansible.builtin.reboot: msg: "Rebooting to apply new PVE Kernel updates" when: apt_upgrade.changed # ========================================== # PHASE 3: PROXMOX CLUSTERING # ========================================== - name: Ensure SSH keypair exists for root ansible.builtin.user: name: root generate_ssh_key: yes ssh_key_bits: 4096 - name: Fetch public SSH keys from all nodes ansible.builtin.slurp: src: /root/.ssh/id_rsa.pub register: ssh_pub_keys - name: Distribute SSH keys to build full-mesh trust ansible.posix.authorized_key: user: root key: "{{ hostvars[item]['ssh_pub_keys']['content'] | b64decode }}" state: present loop: "{{ ansible_play_hosts }}" - name: Automatically accept host keys for cluster subnets ansible.builtin.blockinfile: path: /root/.ssh/config create: yes mode: '0600' block: | Host {{ master_corosync_ip | regex_replace('\.[0-9]+$', '.*') }} {{ hostvars[groups['proxmox'][0]]['ansible_host'] | regex_replace('\.[0-9]+$', '.*') }} StrictHostKeyChecking no UserKnownHostsFile=/dev/null - name: Check current Proxmox cluster status ansible.builtin.command: pvecm status register: pvecm_status ignore_errors: yes changed_when: false - name: Initialize the Proxmox Cluster (Master Node) ansible.builtin.command: pvecm create {{ pve_cluster_name }} --link0 {{ corosync_ip }} when: - pvecm_status.rc != 0 - is_master | bool - name: Wait for Corosync to stabilize ansible.builtin.pause: seconds: 10 when: - pvecm_status.rc != 0 - is_master | bool - name: Join the Proxmox Cluster (Worker Nodes) ansible.builtin.command: > pvecm add {{ master_corosync_ip }} --link0 {{ corosync_ip }} --use_ssh yes when: - pvecm_status.rc != 0 - not is_master | bool async: 60 poll: 10 # ========================================== # PHASE 4: LINSTOR CONFIGURATION # ========================================== - name: Configure Linstor (Skipped if deploy_linstor=false) when: deploy_linstor | bool block: - name: Configure Linstor Cluster ansible.builtin.include_role: name: linstor_cluster - name: Configure Linstor Storage ansible.builtin.include_role: name: linstor_storage - name: Configure Linstor HA ansible.builtin.include_role: name: linstor_ha - name: Configure Proxmox Storage Plugin for Linstor ansible.builtin.include_role: name: proxmox_storage handlers: - name: Restart pveproxy ansible.builtin.service: name: pveproxy state: restarted