You've already forked role_proxmox
Compare commits
2 Commits
47345a9c95
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e3f6c9b02e | |||
| d4c68a3ed3 |
0
.ansible/.lock
Normal file
0
.ansible/.lock
Normal file
@@ -1,3 +1,3 @@
|
||||
# role_modele
|
||||
# role_proxmox
|
||||
|
||||
Modèle
|
||||
Manage Proxmox VE instances.
|
||||
|
||||
94
defaults/main.yml
Normal file
94
defaults/main.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
# vars file for proxmox
|
||||
|
||||
# Informations to connect to API
|
||||
proxmox_api_host: ""
|
||||
proxmox_api_user: ""
|
||||
proxmox_api_token_id: ""
|
||||
proxmox_api_token_secret: ""
|
||||
proxmox_api_validate_certs: false
|
||||
|
||||
# Proxmox VE node
|
||||
## Node
|
||||
proxmox_node_interfaces: []
|
||||
|
||||
## Cluster
|
||||
proxmox_cluster_name: ""
|
||||
# proxmox_cluster_link0: ""
|
||||
# proxmox_cluster_link1: ""
|
||||
|
||||
## Storage
|
||||
proxmox_storage: []
|
||||
|
||||
# Images list to download
|
||||
proxmox_images: []
|
||||
# Example:
|
||||
# - url: "https://cloud.debian.org/images/cloud/bookworm-backports/latest/debian-12-backports-genericcloud-amd64.qcow2"
|
||||
# dest: /mnt/pve/pumbaa/disk_image/bookworm.qcow2
|
||||
|
||||
# Proxmox VE instance
|
||||
## Delegate tasks to Proxmox VE host (local API call !)
|
||||
proxmox_delegate_to: ""
|
||||
|
||||
## Type of instance (ct or vm)
|
||||
proxmox_instance_type: ""
|
||||
|
||||
## Instance configuration
|
||||
proxmox_instance_node: ""
|
||||
proxmox_instance_autostart: true
|
||||
proxmox_instance_args: ""
|
||||
proxmox_instance_cores: 1
|
||||
proxmox_instance_cpu: kvm64
|
||||
proxmox_instance_full: false
|
||||
proxmox_instance_hotplug:
|
||||
- cpu
|
||||
- disk
|
||||
- memory
|
||||
- network
|
||||
- usb
|
||||
proxmox_instance_ipconfig: {}
|
||||
proxmox_instance_memory: 1024
|
||||
proxmox_instance_migrate: true
|
||||
proxmox_instance_net: {}
|
||||
proxmox_instance_numa: true
|
||||
proxmox_instance_onboot: true
|
||||
proxmox_instance_protection: true
|
||||
proxmox_instance_vmid: ""
|
||||
|
||||
proxmox_instance_disks: []
|
||||
# Example:
|
||||
# - disk: virtio0
|
||||
# storage: ssd120
|
||||
# size: 8
|
||||
# img: "{{ proxmox_images[0].dest }}"
|
||||
# - disk: virtio1
|
||||
# backup: true
|
||||
# mbps: 10
|
||||
# storage: nfs
|
||||
# size: 10
|
||||
|
||||
proxmox_instance_cloudinit: true
|
||||
proxmox_instance_cloudinit_cipassword: ""
|
||||
proxmox_instance_cloudinit_ciuser: ""
|
||||
proxmox_instance_cloudinit_nameservers: ""
|
||||
proxmox_instance_cloudinit_searchdomains: null
|
||||
proxmox_instance_cloudinit_sshkeys: ""
|
||||
|
||||
## HA configuration
|
||||
proxmox_instance_ha:
|
||||
max_restart: 3
|
||||
max_relocate: 2
|
||||
state: started
|
||||
|
||||
## Configuration to wait SSH
|
||||
proxmox_instance_ssh_ip: ""
|
||||
proxmox_instance_ssh_port: ""
|
||||
|
||||
## Start instance after installation
|
||||
proxmox_start_instance: true
|
||||
|
||||
## Reboot instance when changed
|
||||
proxmox_reboot_instance: true
|
||||
|
||||
## Start qemu-guest-agent.service at the end
|
||||
proxmox_start_agent: true
|
||||
93
handlers/main.yml
Normal file
93
handlers/main.yml
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
# handlers file for proxmox
|
||||
|
||||
- name: Configure cloud-init
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
agent: "enabled=1,fstrim_cloned_disks=1"
|
||||
cipassword: "{{ proxmox_instance_cloudinit_cipassword }}"
|
||||
ciuser: "{{ proxmox_instance_cloudinit_ciuser }}"
|
||||
ciupgrade: false
|
||||
ide:
|
||||
ide2: "{{ proxmox_instance_disks[0].storage }}:cloudinit"
|
||||
ipconfig: "{{ proxmox_instance_ipconfig }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
nameservers: "{{ proxmox_instance_cloudinit_nameservers }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
searchdomains: "{{ proxmox_instance_cloudinit_searchdomains }}"
|
||||
sshkeys: "{{ proxmox_instance_cloudinit_sshkeys }}"
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
update: true
|
||||
update_unsafe: true
|
||||
when: proxmox_instance_cloudinit
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Start instance
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
state: started
|
||||
when:
|
||||
- proxmox_start_instance
|
||||
- not rebooted.changed
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Wait SSH port is open
|
||||
ansible.builtin.wait_for:
|
||||
host: "{{ proxmox_instance_ssh_ip }}"
|
||||
port: "{{ proxmox_instance_ssh_port }}"
|
||||
search_regex: OpenSSH
|
||||
delay: 30
|
||||
when: proxmox_start_instance
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Wait cloud-init
|
||||
ansible.builtin.command:
|
||||
cmd: cloud-init status
|
||||
when: proxmox_instance_cloudinit
|
||||
register: cloudinit_status
|
||||
changed_when: cloudinit_status.stdout_lines | select("search", "done") | list | length > 0
|
||||
failed_when: cloudinit_status.rc == 1
|
||||
until: cloudinit_status.stdout_lines | select("search", "done") | list | length > 0
|
||||
retries: 100
|
||||
delay: 36
|
||||
ignore_errors: true
|
||||
|
||||
- name: Disable maintenance mode on node
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- ha-manager
|
||||
- crm-command
|
||||
- node-maintenance
|
||||
- disable
|
||||
- "{{ inventory_hostname_short }}"
|
||||
become: true
|
||||
register: proxmox_maintenance_disabled
|
||||
changed_when: proxmox_maintenance_disabled.rc == 0
|
||||
listen: Disable maintenance mode
|
||||
|
||||
- name: Wait for the instances to return to the current host
|
||||
community.proxmox.proxmox_vm_info:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
node: "{{ inventory_hostname_short }}"
|
||||
type: all
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
register: proxmox_current_instances
|
||||
retries: 20
|
||||
delay: 30
|
||||
until: current == expected
|
||||
vars:
|
||||
current: "{{ proxmox_current_instances.proxmox_vms | map(attribute='name') | sort }}"
|
||||
expected: "{{ proxmox_node_instances.proxmox_vms | map(attribute='name') | sort }}"
|
||||
listen: Disable maintenance mode
|
||||
@@ -1,7 +1,7 @@
|
||||
galaxy_info:
|
||||
namespace: ykn
|
||||
author: pulsar89.5
|
||||
description: Rôle modèle
|
||||
description: Manage Proxmox VE instances
|
||||
|
||||
license: GPL-3.0-or-later
|
||||
|
||||
@@ -10,6 +10,6 @@ galaxy_info:
|
||||
platforms:
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
- bookworm
|
||||
|
||||
dependencies: []
|
||||
|
||||
149
tasks/instance_vm_configuration.yml
Normal file
149
tasks/instance_vm_configuration.yml
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
# tasks file for proxmox
|
||||
|
||||
- name: Build disks list
|
||||
ansible.builtin.set_fact:
|
||||
proxmox_instance_disks: "{{ proxmox_instance_disks + specific }}"
|
||||
when: specific | length > 0
|
||||
loop: "{{ lookup('ansible.builtin.varnames', '^proxmox_instance_disks_.+', wantlist=True) }}"
|
||||
vars:
|
||||
specific: "{{ lookup('ansible.builtin.vars', item, default='') }}"
|
||||
|
||||
- name: Configure disks
|
||||
community.proxmox.proxmox_disk:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
aio: "{{ item.aio | default(omit) }}"
|
||||
backup: "{{ item.backup | default(omit) }}"
|
||||
cache: "{{ item.cache | default(omit) }}"
|
||||
disk: "{{ item.disk }}"
|
||||
iothread: "{{ item.iothread | default(omit) }}"
|
||||
mbps: "{{ item.mbps | default(omit) }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
storage: "{{ item.storage }}"
|
||||
size: "{{ item.size }}"
|
||||
state: present
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
loop: "{{ proxmox_instance_disks }}"
|
||||
loop_control:
|
||||
label: "{{ item.disk }}"
|
||||
index_var: disk_number
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Get instance informations
|
||||
community.proxmox.proxmox_vm_info:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
config: current
|
||||
name: "{{ inventory_hostname }}"
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
register: instance_current_infos
|
||||
|
||||
- name: Grow disk size
|
||||
community.proxmox.proxmox_disk:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
aio: "{{ item.aio | default(omit) }}"
|
||||
backup: "{{ item.backup | default(omit) }}"
|
||||
cache: "{{ item.cache | default(omit) }}"
|
||||
disk: "{{ item.disk }}"
|
||||
iothread: "{{ item.iothread | default(omit) }}"
|
||||
mbps: "{{ item.mbps | default(omit) }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
storage: "{{ item.storage }}"
|
||||
size: "{{ item.size }}G"
|
||||
state: resized
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
when:
|
||||
- proxmox_instance_disks | length > 0
|
||||
- instance_current_infos.proxmox_vms | length > 0
|
||||
- formated_size not in instance_current_infos.proxmox_vms[0].config[item.disk]
|
||||
loop: "{{ proxmox_instance_disks }}"
|
||||
loop_control:
|
||||
label: "{{ item.disk }}"
|
||||
index_var: disk_number
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
vars:
|
||||
formated_size: "size={{ item.size }}G"
|
||||
|
||||
- name: Reconfigure instance
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
agent: "enabled=1,fstrim_cloned_disks=1"
|
||||
autostart: "{{ proxmox_instance_autostart }}"
|
||||
cores: "{{ proxmox_instance_cores }}"
|
||||
cpu: "{{ proxmox_instance_cpu }}"
|
||||
hotplug: "{{ proxmox_instance_hotplug | join(',') }}"
|
||||
ipconfig: "{{ proxmox_instance_ipconfig }}"
|
||||
memory: "{{ proxmox_instance_memory }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
nameservers: "{{ proxmox_instance_cloudinit_nameservers }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
numa_enabled: "{{ proxmox_instance_numa }}"
|
||||
onboot: "{{ proxmox_instance_onboot }}"
|
||||
protection: "{{ proxmox_instance_protection }}"
|
||||
tablet: false
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
update: true
|
||||
update_unsafe: true
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Get changed information about the instance
|
||||
community.proxmox.proxmox_vm_info:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
config: pending
|
||||
name: "{{ inventory_hostname }}"
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
when: not create_instance.changed
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
register: instance_pending_infos
|
||||
|
||||
- name: Reboot the instance
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
state: restarted
|
||||
timeout: 300
|
||||
when:
|
||||
- proxmox_reboot_instance
|
||||
- not create_instance.changed
|
||||
- instance_current_infos.proxmox_vms[0].config != instance_pending_infos.proxmox_vms[0].config
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
notify: Wait SSH port is open
|
||||
register: rebooted
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Ensure instance is started
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
state: started
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
notify: Wait SSH port is open
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
44
tasks/instance_vm_ha.yml
Normal file
44
tasks/instance_vm_ha.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
# tasks file for proxmox
|
||||
|
||||
- name: Build HA resources (vm:<vmid>) for node
|
||||
set_fact:
|
||||
ha_resources_for_node: >-
|
||||
{{ ['vm:'] | product(
|
||||
query('inventory_hostnames', 'type_proxmox_kvm:&zone_gaia') |
|
||||
sort |
|
||||
map('extract', hostvars) |
|
||||
selectattr('proxmox_instance_node', 'equalto', proxmox_instance_node) |
|
||||
map(attribute='proxmox_instance_vmid')
|
||||
) | map('join') | list }}
|
||||
|
||||
- name: Ensure HA services exist for VMs
|
||||
community.proxmox.proxmox_cluster_ha_resources:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
comment: "Managed by Ansible"
|
||||
hastate: "{{ proxmox_instance_ha.state }}"
|
||||
max_relocate: "{{ proxmox_instance_ha.max_relocate }}"
|
||||
max_restart: "{{ proxmox_instance_ha.max_restart }}"
|
||||
name: "vm:{{ proxmox_instance_vmid }}"
|
||||
state: present
|
||||
become: true
|
||||
delegate_to: "{{ proxmox_delegate_to }}"
|
||||
|
||||
- name: Create HA node affinity rule
|
||||
community.proxmox.proxmox_cluster_ha_rules:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
comment: Managed by ansible
|
||||
disable: false
|
||||
name: "{{ proxmox_instance_node }}"
|
||||
nodes: ["{{ proxmox_instance_node }}"]
|
||||
resources: "{{ ha_resources_for_node }}"
|
||||
state: present
|
||||
type: node-affinity
|
||||
become: true
|
||||
delegate_to: "{{ proxmox_delegate_to }}"
|
||||
71
tasks/instance_vm_template.yml
Normal file
71
tasks/instance_vm_template.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
# tasks file for proxmox
|
||||
|
||||
- name: Create instance
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
agent: "enabled=1,fstrim_cloned_disks=1"
|
||||
autostart: "{{ proxmox_instance_autostart }}"
|
||||
cores: "{{ proxmox_instance_cores }}"
|
||||
cpu: "{{ proxmox_instance_cpu }}"
|
||||
hotplug: "{{ proxmox_instance_hotplug | join(',') }}"
|
||||
ipconfig: "{{ proxmox_instance_ipconfig }}"
|
||||
memory: "{{ proxmox_instance_memory }}"
|
||||
name: "{{ inventory_hostname }}"
|
||||
nameservers: "{{ proxmox_instance_cloudinit_nameservers }}"
|
||||
net: "{{ proxmox_instance_net }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
numa_enabled: "{{ proxmox_instance_numa }}"
|
||||
onboot: "{{ proxmox_instance_onboot }}"
|
||||
scsihw: virtio-scsi-single
|
||||
tablet: false
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
register: create_instance
|
||||
notify:
|
||||
- Configure cloud-init
|
||||
- Start instance
|
||||
- Wait SSH port is open
|
||||
- Wait cloud-init
|
||||
|
||||
- name: Import virtual disk
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
qm set {{ proxmox_instance_vmid }}
|
||||
--{{ proxmox_instance_disks[0].disk }}
|
||||
{{ proxmox_instance_disks[0].storage }}:0,import-from={{ proxmox_instance_disks[0].img }}
|
||||
chdir: "{{ proxmox_instance_disks[0].img | ansible.builtin.dirname }}"
|
||||
when: create_instance.changed # noqa: no-handler no-changed-when
|
||||
become: true
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Workaround to add args to the VM
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/pve/qemu-server/{{ proxmox_instance_vmid }}.conf
|
||||
line: "args: {{ proxmox_instance_args }}"
|
||||
state: present
|
||||
when: proxmox_instance_args | length > 0
|
||||
become: true
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
|
||||
- name: Add configuration items
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
boot: order=virtio0
|
||||
name: "{{ inventory_hostname }}"
|
||||
node: "{{ proxmox_instance_node }}"
|
||||
serial:
|
||||
serial0: socket
|
||||
update: true
|
||||
update_unsafe: true
|
||||
vmid: "{{ proxmox_instance_vmid }}"
|
||||
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
|
||||
notify:
|
||||
- Start instance
|
||||
- Wait SSH port is open
|
||||
26
tasks/main.yml
Normal file
26
tasks/main.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# tasks file for proxmox
|
||||
|
||||
# Node
|
||||
- name: Import Proxmox VE configuration tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: node_configuration.yml
|
||||
when: proxmox_instance_type | length == 0
|
||||
|
||||
# Instance: vm
|
||||
- name: Import instance creation tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: instance_vm_template.yml
|
||||
when: proxmox_instance_type == "vm"
|
||||
|
||||
- name: Import instance configuration tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: instance_vm_configuration.yml
|
||||
when: proxmox_instance_type == "vm"
|
||||
|
||||
- name: Import HA configuration tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: instance_vm_ha.yml
|
||||
when:
|
||||
- proxmox_instance_type == "vm"
|
||||
- proxmox_instance_ha | length > 0
|
||||
120
tasks/node_configuration.yml
Normal file
120
tasks/node_configuration.yml
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
# tasks file for proxmox
|
||||
|
||||
- name: Install prerequisite
|
||||
ansible.builtin.apt:
|
||||
name: python3-proxmoxer
|
||||
update_cache: true
|
||||
become: true
|
||||
|
||||
- name: Manage Proxmox VE node bridge interface
|
||||
community.proxmox.proxmox_node_network:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
autostart: "{{ item.autostart | default(true) }}"
|
||||
cidr: "{{ item.cidr | default(omit) }}"
|
||||
cidr6: "{{ item.cidr6 | default(omit) }}"
|
||||
comments: "{{ item.comments | default(omit) }}"
|
||||
gateway: "{{ item.gateway | default(omit) }}"
|
||||
gateway6: "{{ item.gateway6 | default(omit) }}"
|
||||
iface_type: bridge
|
||||
iface: "{{ item.iface }}"
|
||||
mtu: "{{ item.mtu | default(omit) }}"
|
||||
node: "{{ inventory_hostname_short }}"
|
||||
state: "{{ item.states | default('present') }}"
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
loop: "{{ proxmox_node_interfaces | selectattr('type', 'equalto', 'bridge') }}"
|
||||
loop_control:
|
||||
label: "{{ item.iface }}"
|
||||
|
||||
- name: Manage Proxmox VE node eth interface
|
||||
community.proxmox.proxmox_node_network:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
autostart: "{{ item.autostart | default(true) }}"
|
||||
cidr: "{{ item.cidr | default(omit) }}"
|
||||
cidr6: "{{ item.cidr6 | default(omit) }}"
|
||||
comments: "{{ item.comments | default(omit) }}"
|
||||
gateway: "{{ item.gateway | default(omit) }}"
|
||||
gateway6: "{{ item.gateway6 | default(omit) }}"
|
||||
iface_type: eth
|
||||
iface: "{{ item.iface }}"
|
||||
mtu: "{{ item.mtu | default(omit) }}"
|
||||
node: "{{ inventory_hostname_short }}"
|
||||
state: "{{ item.states | default('present') }}"
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
loop: "{{ proxmox_node_interfaces | selectattr('type', 'equalto', 'eth') }}"
|
||||
loop_control:
|
||||
label: "{{ item.iface }}"
|
||||
|
||||
- name: Proxmox VE cluster management tasks
|
||||
when: proxmox_cluster_name | length > 0
|
||||
block:
|
||||
- name: List existing Proxmox VE cluster join information
|
||||
community.proxmox.proxmox_cluster_join_info:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
register: proxmox_cluster_join
|
||||
|
||||
- name: Define variables to join an existing Proxmox VE cluster
|
||||
ansible.builtin.set_fact:
|
||||
proxmox_cluster_name: "{{ proxmox_cluster_join.cluster_join.totem.cluster_name }}"
|
||||
proxmox_cluster_master_ip: "{{ proxmox_cluster_join.cluster_join.nodelist[0].pve_addr }}"
|
||||
proxmox_cluster_fingerprint: "{{ proxmox_cluster_join.cluster_join.nodelist[0].pve_fp }}"
|
||||
when: proxmox_cluster_join.cluster_join.nodelist | length > 0
|
||||
|
||||
- name: Manage Proxmox VE Cluster
|
||||
community.proxmox.proxmox_cluster:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
cluster_name: "{{ proxmox_cluster_name }}"
|
||||
fingerprint: "{{ proxmox_cluster_fingerprint | default(omit) }}"
|
||||
link0: "{{ proxmox_cluster_link0 | default(omit) }}"
|
||||
link1: "{{ proxmox_cluster_link1 | default(omit) }}"
|
||||
master_ip: "{{ proxmox_cluster_master_ip | default(omit) }}"
|
||||
state: "{{ item.states | default('present') }}"
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
when: >-
|
||||
proxmox_cluster_join.cluster_join.nodelist | length == 0
|
||||
or
|
||||
proxmox_cluster_join.cluster_join.nodelist | selectattr('name', 'equalto', inventory_hostname_short) | list | length == 0
|
||||
|
||||
- name: Manage Proxmox VE storage
|
||||
community.proxmox.proxmox_storage:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
content: "{{ item.content }}"
|
||||
name: "{{ item.name }}"
|
||||
nfs_options: "{{ item.nfs_options | default(omit) }}"
|
||||
nodes: "{{ item.nodes }}"
|
||||
state: "{{ item.states | default('present') }}"
|
||||
type: "{{ item.type }}"
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
loop: "{{ proxmox_storage }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Download images
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ item.url }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: u=rw,g=r,o=r
|
||||
become: true
|
||||
loop: "{{ proxmox_images }}"
|
||||
loop_control:
|
||||
label: "{{ item.dest | ansible.builtin.basename }}"
|
||||
104
tasks/node_update.yml
Normal file
104
tasks/node_update.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
|
||||
- name: Update apt cache
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
become: true
|
||||
|
||||
- name: List upgradable packages
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- apt
|
||||
- list
|
||||
- --upgradable
|
||||
register: apt_upgradable
|
||||
changed_when: apt_upgradable.stdout_lines | length > 1
|
||||
|
||||
- name: Upgrade tasks
|
||||
when: apt_upgradable.stdout_lines | length > 1
|
||||
block:
|
||||
- name: List instance on the current node
|
||||
community.proxmox.proxmox_vm_info:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
node: "{{ inventory_hostname_short }}"
|
||||
type: all
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
register: proxmox_node_instances
|
||||
|
||||
- name: Enable maintenance node
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- ha-manager
|
||||
- crm-command
|
||||
- node-maintenance
|
||||
- enable
|
||||
- "{{ inventory_hostname_short }}"
|
||||
become: true
|
||||
register: proxmox_maintenance_enabled
|
||||
changed_when: proxmox_maintenance_enabled.rc == 0
|
||||
notify: Disable maintenance mode
|
||||
|
||||
- name: Wait for the instances to be migrated
|
||||
community.proxmox.proxmox_vm_info:
|
||||
api_host: "{{ proxmox_api_host }}"
|
||||
api_token_id: "{{ proxmox_api_token_id }}"
|
||||
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||
api_user: "{{ proxmox_api_user }}"
|
||||
node: "{{ inventory_hostname_short }}"
|
||||
type: all
|
||||
validate_certs: "{{ proxmox_api_validate_certs }}"
|
||||
become: true
|
||||
register: proxmox_current_instances
|
||||
retries: 20
|
||||
delay: 30
|
||||
until: proxmox_current_instances.proxmox_vms | selectattr('hastate', 'defined') | selectattr('hastate', 'equalto', 'started') | list | length == 0
|
||||
|
||||
- name: Run the full-upgrade
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
become: true
|
||||
|
||||
- name: Reboot
|
||||
ansible.builtin.reboot:
|
||||
become: true
|
||||
|
||||
- name: Clean apt things
|
||||
ansible.builtin.apt:
|
||||
clean: true
|
||||
become: true
|
||||
|
||||
- name: List installed packages
|
||||
ansible.builtin.command: # noqa: no-changed-when
|
||||
argv:
|
||||
- apt
|
||||
- list
|
||||
- --installed
|
||||
register: apt_list
|
||||
check_mode: false
|
||||
|
||||
- name: Remove old kernels
|
||||
ansible.builtin.apt:
|
||||
name: "{{ installed_kernels[:-2] }}"
|
||||
state: absent
|
||||
when: installed_kernels | length > 2
|
||||
become: true
|
||||
vars:
|
||||
installed_kernels:
|
||||
apt_list.stdout_lines |
|
||||
select('search', '^proxmox-kernel') |
|
||||
select('search', 'automatic') |
|
||||
split('/') | first | list
|
||||
check_mode: true
|
||||
|
||||
- name: Autoremove apt packages
|
||||
ansible.builtin.apt:
|
||||
autoremove: true
|
||||
purge: true
|
||||
become: true
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
Reference in New Issue
Block a user