Files
homelab-infra/infrastructure/proxmox/ansible/roles/pve_ha/tasks/main.yml
T
panxiao81 2e05b1a96a
yaml / yaml (pull_request) Failing after 25s
terraform / validate (pull_request) Successful in 51s
ansible / collection-test (pull_request) Successful in 1m27s
ansible / lint (pull_request) Successful in 3m45s
声明式管理 Proxmox API 对象与 Samba DNS 上游
2026-09-17 13:22:50 +00:00

181 lines
5.8 KiB
YAML

---
- name: Validate Proxmox API inputs
ansible.builtin.assert:
that:
- pve_api_host | length > 0
- pve_api_user | length > 0
- pve_api_token_id | length > 0
- pve_api_token_secret | length > 0
fail_msg: >-
Export PROXMOX_HOST, PROXMOX_USER, PROXMOX_TOKEN_ID and
PROXMOX_TOKEN_SECRET before running ha.yml.
run_once: true
delegate_to: localhost
no_log: true
tags: [ha]
- name: Select the hardware watchdog module
ansible.builtin.lineinfile:
path: /etc/default/pve-ha-manager
regexp: '^#?\s*WATCHDOG_MODULE='
line: "WATCHDOG_MODULE={{ pve_ha_watchdog_module }}"
create: false
when: pve_ha_watchdog_module | length > 0
notify: Reboot required for watchdog
tags: [ha, watchdog]
- name: Blacklist softdog so the hardware watchdog claims /dev/watchdog
ansible.builtin.copy:
dest: /etc/modprobe.d/pve-ha-watchdog.conf
mode: "0644"
content: |
# Managed by ansible (roles/pve_ha). See that role for the reasoning.
# softdog cannot fence a frozen kernel; blacklisting it lets
# {{ pve_ha_watchdog_module }} register as watchdog0 and own /dev/watchdog.
blacklist softdog
when: pve_ha_watchdog_module | length > 0
notify: Reboot required for watchdog
tags: [ha, watchdog]
- name: Read current HA VM configurations
ansible.builtin.uri:
url: >-
https://{{ pve_api_host }}:8006/api2/json/nodes/{{ item.node }}/qemu/{{ item.vmid }}/config
headers:
Authorization: >-
PVEAPIToken={{ pve_api_user }}!{{ pve_api_token_id }}={{ pve_api_token_secret }}
ca_path: /etc/ssl/certs/ca-certificates.crt
return_content: true
loop: "{{ pve_ha_portable_vms }}"
loop_control:
label: "VM {{ item.vmid }}"
register: pve_ha_vm_config
run_once: true
delegate_to: localhost
no_log: true
tags: [ha]
- name: Reconcile portable CPU models for HA VMs
community.proxmox.proxmox_kvm:
api_host: "{{ pve_api_host }}"
api_user: "{{ pve_api_user }}"
api_token_id: "{{ pve_api_token_id }}"
api_token_secret: "{{ pve_api_token_secret }}"
validate_certs: "{{ pve_api_validate_certs }}"
ca_path: /etc/ssl/certs/ca-certificates.crt
node: "{{ item.node }}"
vmid: "{{ item.vmid }}"
cpu: "{{ item.cpu }}"
update: true
state: present
loop: "{{ pve_ha_portable_vms }}"
loop_control:
label: "VM {{ item.vmid }} -> {{ item.cpu }}"
index_var: vm_index
when: pve_ha_vm_config.results[vm_index].json.data.cpu != item.cpu
run_once: true
delegate_to: localhost
no_log: true
vars:
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
tags: [ha]
- name: Read current HA resources
ansible.builtin.uri:
url: "https://{{ pve_api_host }}:8006/api2/json/cluster/ha/resources"
headers:
Authorization: >-
PVEAPIToken={{ pve_api_user }}!{{ pve_api_token_id }}={{ pve_api_token_secret }}
ca_path: /etc/ssl/certs/ca-certificates.crt
return_content: true
register: pve_ha_resource_state
run_once: true
delegate_to: localhost
no_log: true
tags: [ha]
- name: Reconcile HA resources through the PVE API
community.proxmox.proxmox_cluster_ha_resources:
api_host: "{{ pve_api_host }}"
api_user: "{{ pve_api_user }}"
api_token_id: "{{ pve_api_token_id }}"
api_token_secret: "{{ pve_api_token_secret }}"
validate_certs: "{{ pve_api_validate_certs }}"
ca_path: /etc/ssl/certs/ca-certificates.crt
name: "{{ item.sid }}"
state: present
hastate: "{{ item.state }}"
max_restart: "{{ item.max_restart }}"
max_relocate: "{{ item.max_relocate }}"
loop: "{{ pve_ha_resources }}"
loop_control:
label: "{{ item.sid }}"
when: >-
_current_resource | length == 0 or
_current_resource.state != item.state or
_current_resource.max_restart | int != item.max_restart | int or
_current_resource.max_relocate | int != item.max_relocate | int
run_once: true
delegate_to: localhost
no_log: true
vars:
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
_current_resource: >-
{{ pve_ha_resource_state.json.data |
selectattr('sid', 'equalto', item.sid) | first | default({}) }}
tags: [ha]
- name: Reconcile HA placement rules through the PVE API
community.proxmox.proxmox_cluster_ha_rules:
api_host: "{{ pve_api_host }}"
api_user: "{{ pve_api_user }}"
api_token_id: "{{ pve_api_token_id }}"
api_token_secret: "{{ pve_api_token_secret }}"
validate_certs: "{{ pve_api_validate_certs }}"
ca_path: /etc/ssl/certs/ca-certificates.crt
name: "{{ item.name }}"
state: present
type: "{{ item.type }}"
resources: "{{ item.resources }}"
nodes: "{{ item.nodes }}"
strict: "{{ item.strict }}"
comment: "{{ item.comment }}"
disable: false
loop: "{{ pve_ha_rules }}"
loop_control:
label: "{{ item.name }}"
run_once: true
delegate_to: localhost
no_log: true
vars:
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
tags: [ha]
- name: Read HA placement rules through the PVE API
community.proxmox.proxmox_cluster_ha_rules_info:
api_host: "{{ pve_api_host }}"
api_user: "{{ pve_api_user }}"
api_token_id: "{{ pve_api_token_id }}"
api_token_secret: "{{ pve_api_token_secret }}"
validate_certs: "{{ pve_api_validate_certs }}"
ca_path: /etc/ssl/certs/ca-certificates.crt
register: pve_ha_rule_state
run_once: true
delegate_to: localhost
no_log: true
vars:
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
tags: [ha]
- name: Assert declared placement rules exist
ansible.builtin.assert:
that:
- >-
(pve_ha_rules | map(attribute='name') | list |
difference(pve_ha_rule_state.rules | default([]) |
map(attribute='rule') | list) | length) == 0
fail_msg: A declared HA placement rule is absent after reconciliation
run_once: true
delegate_to: localhost
tags: [ha]