From 097ee79bed45027a985f82c1c58fcc6fdcd1fef1 Mon Sep 17 00:00:00 2001 From: Janic Voser Date: Fri, 14 Aug 2026 00:17:50 +0200 Subject: [PATCH] Updated homelab hosts & structure --- config/ansible.homelab.cfg | 27 ++++++ config/hosts.homelab.yaml | 79 ++++++++++++++++ playbooks/proxmox-patching.yml | 9 ++ playbooks/reachable.yml | 12 +++ roles/proxmox-patching/README.md | 59 ++++++++++++ roles/proxmox-patching/defaults/main.yml | 8 ++ roles/proxmox-patching/handlers/main.yml | 2 + roles/proxmox-patching/meta/main.yml | 52 +++++++++++ roles/proxmox-patching/tasks/dist/Debian.yml | 93 +++++++++++++++++++ .../tasks/dist/no_dist_found.yml | 8 ++ roles/proxmox-patching/tasks/main.yml | 31 +++++++ roles/proxmox-patching/tests/inventory | 2 + roles/proxmox-patching/tests/test.yml | 5 + roles/proxmox-patching/vars/default.yml | 2 + roles/reachable/.travis.yml | 29 ++++++ roles/reachable/README.md | 19 ++++ roles/reachable/defaults/main.yml | 2 + roles/reachable/handlers/main.yml | 2 + roles/reachable/meta/main.yml | 52 +++++++++++ roles/reachable/tasks/main.yml | 4 + roles/reachable/tests/inventory | 2 + roles/reachable/tests/test.yml | 5 + roles/reachable/vars/main.yml | 2 + 23 files changed, 506 insertions(+) create mode 100644 config/ansible.homelab.cfg create mode 100644 config/hosts.homelab.yaml create mode 100644 playbooks/proxmox-patching.yml create mode 100644 playbooks/reachable.yml create mode 100644 roles/proxmox-patching/README.md create mode 100644 roles/proxmox-patching/defaults/main.yml create mode 100644 roles/proxmox-patching/handlers/main.yml create mode 100644 roles/proxmox-patching/meta/main.yml create mode 100644 roles/proxmox-patching/tasks/dist/Debian.yml create mode 100644 roles/proxmox-patching/tasks/dist/no_dist_found.yml create mode 100644 roles/proxmox-patching/tasks/main.yml create mode 100644 roles/proxmox-patching/tests/inventory create mode 100644 roles/proxmox-patching/tests/test.yml create mode 100644 roles/proxmox-patching/vars/default.yml create mode 100644 roles/reachable/.travis.yml create mode 100644 roles/reachable/README.md create mode 100644 roles/reachable/defaults/main.yml create mode 100644 roles/reachable/handlers/main.yml create mode 100644 roles/reachable/meta/main.yml create mode 100644 roles/reachable/tasks/main.yml create mode 100644 roles/reachable/tests/inventory create mode 100644 roles/reachable/tests/test.yml create mode 100644 roles/reachable/vars/main.yml diff --git a/config/ansible.homelab.cfg b/config/ansible.homelab.cfg new file mode 100644 index 0000000..81a8e3b --- /dev/null +++ b/config/ansible.homelab.cfg @@ -0,0 +1,27 @@ +[defaults] +inventory = /home/janic/workspace/ansible/config/hosts.homelab.yaml +roles_path = /home/janic/workspace/ansible/roles +private_key_file = /home/janic/.ssh/id_ed25519_privat_v1 +remote_user = root +host_key_checking = False + +[inventory] + +[privilege_escalation] +become=True +become_method=sudo +become_user=root + +[paramiko_connection] + +[ssh_connection] + +[persistent_connection] + +[accelerate] + +[selinux] + +[colors] + +[diff] diff --git a/config/hosts.homelab.yaml b/config/hosts.homelab.yaml new file mode 100644 index 0000000..a7a9381 --- /dev/null +++ b/config/hosts.homelab.yaml @@ -0,0 +1,79 @@ +all: + children: + # Role Groups + physical: + children: + proxmox: + octoprint: + virtual: + children: + freeipa: + monitoring: + # Hosts + proxmox: + hosts: + pve01: + ansible_host: 172.22.222.201 + pve02: + ansible_host: 172.22.222.202 + pve03: + ansible_host: 172.22.222.203 + pve04: + ansible_host: 172.22.222.204 + vars: + Datacenter_Location: PLZ8912 + pve.default_cluster_balance_group: ClusterBalance + long_task.delay: 30 + octoprint: + hosts: + srvprn01: + ansible_host: 172.22.32.20 + freeipa: + hosts: + srvipa01: + ansible_host: 172.22.3.41 + monitoring: + hosts: + srvmon01: + ansible_host: 172.22.3.10 + # # Disabled 13.08.2026 + # netbox: + # hosts: + # srvntb01: + # ansible_host: 172.22.3.11 + # semaphore: + # hosts: + # srvsem01: + # ansible_host: 172.22.3.30 + # wazuh: + # hosts: + # srvwaz02: + # ansible_host: 172.22.3.34 + docker: + hosts: + srvmgr02: + ansible_host: 172.22.3.32 + # # Disabled 13.08.2026 + # galera: + # hosts: + # srvgdb01: + # ansible_host: 172.22.3.71 + # srvgdb02: + # ansible_host: 172.22.3.72 + # srvgdb03: + # ansible_host: 172.22.3.73 + ghap: + children: + # galera-lb: + # hosts: + # srvlb01: + # ansible_host: 172.22.22.21 + # srvlb02: + # ansible_host: 172.22.22.22 + proxmox-lb: + hosts: + srvpmxlb01: + ansible_host: 172.22.222.198 + srvpmxlb02: + ansible_host: 172.22.222.199 + diff --git a/playbooks/proxmox-patching.yml b/playbooks/proxmox-patching.yml new file mode 100644 index 0000000..b58bd3d --- /dev/null +++ b/playbooks/proxmox-patching.yml @@ -0,0 +1,9 @@ +--- +- name: Playbook to managed clients patching + hosts: all + become: true + serial: 1 + + roles: + - role: proxmox-patching + state: present \ No newline at end of file diff --git a/playbooks/reachable.yml b/playbooks/reachable.yml new file mode 100644 index 0000000..432cbe2 --- /dev/null +++ b/playbooks/reachable.yml @@ -0,0 +1,12 @@ +--- +- name: Check if hosts are reachable for ansible + hosts: all + become: false + serial: + - 10% + - 40% + - 100% + + roles: + - role: reachable + state: present diff --git a/roles/proxmox-patching/README.md b/roles/proxmox-patching/README.md new file mode 100644 index 0000000..019ea82 --- /dev/null +++ b/roles/proxmox-patching/README.md @@ -0,0 +1,59 @@ +Role Name +========= + +This role is here to patch entire Proxmox Clusters at once, be sure to only target one Cluster per execution. + +Requirements +------------ + +Create a default HA Group called CB-Default, where all not ha-managed vms will be put in. ++ +Be sure to have the Person on Call informed, that you will do patches ;-) + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + +``` +all: + children: + proxmox: + children: + homelab: + hosts: + pve01: + ansible_host: 172.22.222.201 + pve02: + ansible_host: 172.22.222.202 + pve03: + ansible_host: 172.22.222.203 + pve04: + ansible_host: 172.22.222.204 + vars: + Datacenter_Location: PLZ8912 + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). + + +Usage +----- +ansible-playbook -l homelab playbooks/proxmox-patching.yml \ No newline at end of file diff --git a/roles/proxmox-patching/defaults/main.yml b/roles/proxmox-patching/defaults/main.yml new file mode 100644 index 0000000..334f78c --- /dev/null +++ b/roles/proxmox-patching/defaults/main.yml @@ -0,0 +1,8 @@ +--- +# defaults file for ./playbooks/roles/proxmox-patching +long_task: # 40x 15s => 10 Minutes + retries: 40 + delay: 15 +pve: + # All vms in no ha_group will be added to the default. + default_cluster_balance_group: CB-Default \ No newline at end of file diff --git a/roles/proxmox-patching/handlers/main.yml b/roles/proxmox-patching/handlers/main.yml new file mode 100644 index 0000000..eba7f11 --- /dev/null +++ b/roles/proxmox-patching/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for ./playbooks/roles/proxmox-patching diff --git a/roles/proxmox-patching/meta/main.yml b/roles/proxmox-patching/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/roles/proxmox-patching/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/proxmox-patching/tasks/dist/Debian.yml b/roles/proxmox-patching/tasks/dist/Debian.yml new file mode 100644 index 0000000..117ec0e --- /dev/null +++ b/roles/proxmox-patching/tasks/dist/Debian.yml @@ -0,0 +1,93 @@ +--- +# Ensure Ceph is healthy, before starting to patch +- name: Ensure Ceph is HEALTH_OK and no rebalancing + shell: | + ceph status | grep 'HEALTH_OK' && ! ceph status | grep -q -e 'degraded' -e 'remapped' + register: ceph_health + failed_when: ceph_health.rc != 0 + delegate_to: "{{ play_hosts[0] }}" +# Ensure no node is in Maintenance Mode before patching +- name: Ensure no node is in mainteance mode + shell: ha-manager status | grep '^lrm ' | grep -e maintenance | wc -l + register: no_node_maintenance + failed_when: no_node_maintenance.stdout|int != 0 + delegate_to: "{{ play_hosts[0] }}" +# Check that all VMs are in a HA Group, so they will be migrated when the host gets set to maintenance Mode +- name: Ensure all VMs are in a HA Group + shell: | + for res in $(pvesh get /cluster/resources -type vm --output-format json|jq '.[]|select(has("hastate")|not)|.vmid'); do ha-manager add $res ;done + +- block: + # Set the noout flag to ensure no data on ceph is moved, while a host is unavailable + - name: Set Ceph noout flag (only first run) + shell: ceph osd set noout + # Enable the maintenance Mode of the Host + - name: Enable maintenance mode and migrate VMs + shell: ha-manager crm-command node-maintenance enable {{ inventory_hostname }} + ignore_errors: false + + # Wait till all resources are migrate away + - name: Wait until no VMs are running on this host + shell: | + qm list | grep running | wc -l + register: vm_count + changed_when: false + retries: "{{ long_task.retries }}" + delay: "{{ long_task.delay }}" + until: vm_count.stdout|int == 0 + - name: Wait until no LXCs are running on this host + shell: | + pct list | grep running | wc -l + register: lxc_count + changed_when: false + retries: "{{ long_task.retries }}" + delay: "{{ long_task.delay }}" + until: lxc_count.stdout|int == 0 + + # Install latest Packages + - name: Update apt packages + apt: + update_cache: yes + upgrade: dist + autoremove: yes + + # Compare if the current running kernel is the same as the latest kernel + - name: Get expected boot kernel version + shell: | + grep vmlinuz /boot/grub/grub.cfg | head -1 | awk '{ print $2 }' | sed -e 's%/boot/vmlinuz-%%;s%/ROOT/pve-1@%%' + register: boot_kernel + changed_when: false + - name: Get currently running kernel version + shell: uname -r + register: running_kernel + changed_when: false + # If a newer kernel is on the system, then reboot + - name: Reboot if required + reboot: + reboot_timeout: 600 + post_reboot_delay: 60 + when: boot_kernel.stdout.strip() != running_kernel.stdout.strip() + + + # Disable Ceph noout, as soon as the host is online + - name: Unset Ceph noout flag + shell: ceph osd unset noout + + - name: Ensure Ceph is HEALTH_OK again + shell: | + ceph status | grep 'HEALTH_OK' && ! ceph status | grep -q -e 'degraded' -e 'remapped' + register: ceph_health + retries: "{{ long_task.retries }}" + delay: "{{ long_task.delay }}" + failed_when: ceph_health.rc != 0 + delegate_to: "{{ play_hosts[0] }}" + + - name: Disable maintenance mode and migrate VMs + shell: ha-manager crm-command node-maintenance disable {{ inventory_hostname }} + ignore_errors: false + - name: Ensure no node is in mainteance mode + shell: ha-manager status | grep '^lrm ' | grep -e maintenance | wc -l + register: no_node_maintenance + failed_when: no_node_maintenance.stdout|int != 0 + retries: "{{ long_task.retries }}" + delay: "{{ long_task.delay }}" \ No newline at end of file diff --git a/roles/proxmox-patching/tasks/dist/no_dist_found.yml b/roles/proxmox-patching/tasks/dist/no_dist_found.yml new file mode 100644 index 0000000..1f06f57 --- /dev/null +++ b/roles/proxmox-patching/tasks/dist/no_dist_found.yml @@ -0,0 +1,8 @@ +--- +- name: Distribution not found + debug: + msg: + - "OS Family: {{ ansible_os_family }}" + - "OS Distro: {{ ansible_distribution }}" + - "OS Major Version: {{ ansible_distribution_major_version }}" + - "OS Version: {{ ansible_distribution_version }}" \ No newline at end of file diff --git a/roles/proxmox-patching/tasks/main.yml b/roles/proxmox-patching/tasks/main.yml new file mode 100644 index 0000000..b6aeb6d --- /dev/null +++ b/roles/proxmox-patching/tasks/main.yml @@ -0,0 +1,31 @@ +--- +# tasks file for ./playbooks/roles/proxmox-patching +- name: Import variables specific to distribution + include_vars: "{{ item }}" + with_first_found: + - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_major_version'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['distribution'] }}.yml" + # ansible_os_family is used as a fallback for distros which are not currently + # supported, but are based on a supported distro family. For example, + # Oracle, Rocky, Alma and Alibaba linux, which are all "RedHat" based. + - "{{ role_path }}/vars/{{ ansible_facts['os_family'] }}-{{ ansible_facts['distribution_version'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['os_family'] }}-{{ ansible_facts['distribution_major_version'] }}.yml" + - "{{ role_path }}/vars/{{ ansible_facts['os_family'] }}.yml" + # If neither distro nor family is supported, try a default configuration. + - "{{ role_path }}/vars/default.yml" + +- name: Update everything for distribution + include_tasks: "{{ item }}" + with_first_found: + - "{{ role_path }}/tasks/dist/{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_version'] }}.yml" + - "{{ role_path }}/tasks/dist/{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_major_version'] }}.yml" + - "{{ role_path }}/tasks/dist/{{ ansible_facts['distribution'] }}.yml" + # ansible_os_family is used as a fallback for distros which are not currently + # supported, but are based on a supported distro family. For example, + # Oracle, Rocky, Alma and Alibaba linux, which are all "RedHat" based. + - "{{ role_path }}/tasks/dist/{{ ansible_facts['os_family'] }}-{{ ansible_facts['distribution_version'] }}.yml" + - "{{ role_path }}/tasks/dist/{{ ansible_facts['os_family'] }}-{{ ansible_facts['distribution_major_version'] }}.yml" + - "{{ role_path }}/tasks/dist/{{ ansible_facts['os_family'] }}.yml" + # If neither distro nor family is supported, try a default configuration. + - "{{ role_path }}/tasks/dist/no_dist_found.yml" diff --git a/roles/proxmox-patching/tests/inventory b/roles/proxmox-patching/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/proxmox-patching/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/proxmox-patching/tests/test.yml b/roles/proxmox-patching/tests/test.yml new file mode 100644 index 0000000..2e33415 --- /dev/null +++ b/roles/proxmox-patching/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - ./playbooks/roles/proxmox-patching diff --git a/roles/proxmox-patching/vars/default.yml b/roles/proxmox-patching/vars/default.yml new file mode 100644 index 0000000..d61f185 --- /dev/null +++ b/roles/proxmox-patching/vars/default.yml @@ -0,0 +1,2 @@ +--- +# vars file for ./playbooks/roles/proxmox-patching diff --git a/roles/reachable/.travis.yml b/roles/reachable/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/roles/reachable/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/roles/reachable/README.md b/roles/reachable/README.md new file mode 100644 index 0000000..c1448e5 --- /dev/null +++ b/roles/reachable/README.md @@ -0,0 +1,19 @@ +Reachable +========= + +This Role is used to test if a node or multiple nodes are reachable by ansible + +Requirements +------------ + +There are no Requirements + +Dependencies +------------ + +There are no dependencies + +Author Information +------------------ + +Written by Janic Voser @ Xelon diff --git a/roles/reachable/defaults/main.yml b/roles/reachable/defaults/main.yml new file mode 100644 index 0000000..3faa28c --- /dev/null +++ b/roles/reachable/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for ./playbooks/roles/reachable diff --git a/roles/reachable/handlers/main.yml b/roles/reachable/handlers/main.yml new file mode 100644 index 0000000..92d154d --- /dev/null +++ b/roles/reachable/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for ./playbooks/roles/reachable diff --git a/roles/reachable/meta/main.yml b/roles/reachable/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/roles/reachable/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/reachable/tasks/main.yml b/roles/reachable/tasks/main.yml new file mode 100644 index 0000000..3504b21 --- /dev/null +++ b/roles/reachable/tasks/main.yml @@ -0,0 +1,4 @@ +--- +# tasks file for ./playbooks/roles/reachable +- name: Ping everything + ping: \ No newline at end of file diff --git a/roles/reachable/tests/inventory b/roles/reachable/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/reachable/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/reachable/tests/test.yml b/roles/reachable/tests/test.yml new file mode 100644 index 0000000..b65219f --- /dev/null +++ b/roles/reachable/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - ./playbooks/roles/reachable diff --git a/roles/reachable/vars/main.yml b/roles/reachable/vars/main.yml new file mode 100644 index 0000000..e2dd0da --- /dev/null +++ b/roles/reachable/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ./playbooks/roles/reachable