From bf20da16293085db131821cf9252a5103ca71146 Mon Sep 17 00:00:00 2001 From: Robert Rapp Date: Mon, 12 Oct 2026 19:41:17 +0200 Subject: [PATCH] infra: HA-Ressource und Node-Affinity per pve-host statt tofu, Infra-IP im Inventar Co-Authored-By: Claude Opus 5.5 --- .../ansible/roles/pve-host/tasks/main.yml | 38 +++++++++++++++++++ platform/proxmox/tofu/main.tf | 9 +---- platform/proxmox/tofu/outputs.tf | 11 ++++-- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/platform/proxmox/ansible/roles/pve-host/tasks/main.yml b/platform/proxmox/ansible/roles/pve-host/tasks/main.yml index d6ee8e8..bf721ff 100644 --- a/platform/proxmox/ansible/roles/pve-host/tasks/main.yml +++ b/platform/proxmox/ansible/roles/pve-host/tasks/main.yml @@ -121,3 +121,41 @@ - (item.0.value.vmid | string) + '.conf' in local_cts.stdout_lines - (item.0.value.vmid | string) + '-' + (idx | string) not in pvesr_jobs.stdout changed_when: true + +- name: HA-Konfiguration lesen + ansible.builtin.command: ha-manager config + register: ha_config + check_mode: false + changed_when: false + +- name: Infra-Gäste unter HA stellen (erst wenn der Container auf diesem Knoten existiert) + ansible.builtin.command: > + ha-manager add ct:{{ item.value.vmid }} --state started --max_restart 1 --max_relocate 1 + --comment 'knaster {{ item.key }}' + loop: "{{ knaster_pve.containers | dict2items }}" + when: + - item.value.ha | default(false) + - item.value.node == inventory_hostname + - (item.value.vmid | string) + '.conf' in local_cts.stdout_lines + - ('ct:' + (item.value.vmid | string)) not in ha_config.stdout + changed_when: true + +- name: HA-Regeln lesen + ansible.builtin.command: ha-manager rules config + register: ha_rules + check_mode: false + changed_when: false + +# Strikt: Die Gäste liegen auf tank, den gibt es nur auf dem Heimatknoten und den Replikationszielen +- name: Node-Affinity für Infra-Gäste (Heimatknoten bevorzugt, sonst Replikationsziele) + ansible.builtin.command: > + ha-manager rules add node-affinity knaster-{{ item.key }} --resources ct:{{ item.value.vmid }} + --nodes {{ ([item.value.node ~ ':2'] + (item.value.replicate_to | map('regex_replace', '$', ':1') | list)) | join(',') }} + --strict 1 --comment 'knaster {{ item.key }}' + loop: "{{ knaster_pve.containers | dict2items }}" + when: + - item.value.ha | default(false) + - item.value.node == inventory_hostname + - (item.value.vmid | string) + '.conf' in local_cts.stdout_lines + - ('knaster-' + item.key) not in ha_rules.stdout + changed_when: true diff --git a/platform/proxmox/tofu/main.tf b/platform/proxmox/tofu/main.tf index e09c714..6734c7d 100644 --- a/platform/proxmox/tofu/main.tf +++ b/platform/proxmox/tofu/main.tf @@ -157,10 +157,5 @@ resource "proxmox_virtual_environment_container" "infra" { } } -resource "proxmox_haresource" "infra" { - for_each = { for k, v in local.site.containers : k => v if try(v.ha, false) } - resource_id = "ct:${each.value.vmid}" - state = "started" - comment = "knaster ${each.key}" - depends_on = [proxmox_virtual_environment_container.infra] -} +# HA (Ressource + Node-Affinity-Regel) und Replikation setzt die Ansible-Rolle pve-host per root-SSH. +# So braucht der tofu-Token kein Sys.Console auf /. diff --git a/platform/proxmox/tofu/outputs.tf b/platform/proxmox/tofu/outputs.tf index 324c5b5..15bdff2 100644 --- a/platform/proxmox/tofu/outputs.tf +++ b/platform/proxmox/tofu/outputs.tf @@ -13,14 +13,17 @@ output "gpu_vms" { } output "infra_containers" { - value = { for k, v in proxmox_virtual_environment_container.infra : k => { node = v.node_name, vmid = v.vm_id } } + value = { for k, v in proxmox_virtual_environment_container.infra : k => { node = v.node_name, vmid = v.vm_id, ipv4 = try(v.ipv4["eth0"], null) } } } # tofu output -raw ansible_inventory > ../ansible/inventory.generated.yml output "ansible_inventory" { value = yamlencode({ - all = { children = { gpu_vms = { hosts = { - for k, ip in local.gpu_vm_ipv4 : k => { ansible_host = ip } if ip != null - } } } } + all = { children = { + gpu_vms = { hosts = { for k, ip in local.gpu_vm_ipv4 : k => { ansible_host = ip } if ip != null } } + infra = { hosts = { + for k, v in proxmox_virtual_environment_container.infra : k => { ansible_host = v.ipv4["eth0"] } if try(v.ipv4["eth0"], null) != null + } } + } } }) }