feat: Create role

This commit is contained in:
pulsar89.5 2024-05-13 18:03:03 +02:00
parent ff3a9a8e69
commit 00ed4d7294
8 changed files with 406 additions and 4 deletions

View File

@ -1,3 +1,3 @@
# role_modele # role_proxmox
Modèle Manage Proxmox VE instances.

74
defaults/main.yml Normal file
View File

@ -0,0 +1,74 @@
---
# vars file for proxmox
# 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
# Delegate tasks to Proxmox VE host (local API call !)
proxmox_delegate_to: ""
# Informations to connect to API
proxmox_api_host: ""
proxmox_api_user: ""
proxmox_api_token_id: ""
proxmox_api_token_secret: ""
# 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: ""
# 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
# Configuration to wait SSH
proxmox_instance_ssh_ip: ""
proxmox_instance_ssh_port: ""

59
handlers/main.yml Normal file
View File

@ -0,0 +1,59 @@
---
# handlers file for proxmox
- name: Configure cloud-init
community.general.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.general.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
until: cloudinit_status.stdout.find("done") != -1
retries: 100
delay: 36
ignore_errors: true

View File

@ -1,7 +1,7 @@
galaxy_info: galaxy_info:
namespace: ykn namespace: ykn
author: pulsar89.5 author: pulsar89.5
description: Rôle modèle description: Manage Proxmox VE instances
license: GPL-3.0-or-later license: GPL-3.0-or-later
@ -10,6 +10,6 @@ galaxy_info:
platforms: platforms:
- name: Debian - name: Debian
versions: versions:
- all - bookworm
dependencies: [] dependencies: []

24
tasks/get_images.yml Normal file
View File

@ -0,0 +1,24 @@
---
# tasks file for proxmox
- name: Create images storage directory
ansible.builtin.file:
path: "{{ item.dest | ansible.builtin.dirname }}"
state: directory
mode: u=rwX,g=rX,o=rX
become: true
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
loop: "{{ proxmox_images }}"
loop_control:
label: "{{ item.dest | ansible.builtin.dirname }}"
- name: Download images
ansible.builtin.get_url:
url: "{{ item.url }}"
dest: "{{ item.dest }}"
mode: u=rw,g=r,o=r
become: true
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
loop: "{{ proxmox_images }}"
loop_control:
label: "{{ item.dest | ansible.builtin.basename }}"

25
tasks/main.yml Normal file
View File

@ -0,0 +1,25 @@
---
# tasks file for proxmox
- name: Install prerequisite
ansible.builtin.apt:
name: python3-proxmoxer
update_cache: true
become: true
run_once: true
delegate_to: "{{ proxmox_delegate_to | default(omit) }}"
- name: Import image download tasks
ansible.builtin.import_tasks:
file: get_images.yml
when: proxmox_instance_type == "vm"
- name: Import instance creation tasks
ansible.builtin.import_tasks:
file: vm_template.yml
when: proxmox_instance_type == "vm"
- name: Import instance configuration tasks
ansible.builtin.import_tasks:
file: vm_configuration.yml
when: proxmox_instance_type == "vm"

149
tasks/vm_configuration.yml Normal file
View 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.general.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.general.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.general.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.general.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.general.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.general.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: Attendre que le port SSH soit ouvert
register: rebooted
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: Ensure instance is started
community.general.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: Attendre que le port SSH soit ouvert
- name: Flush handlers
ansible.builtin.meta: flush_handlers

71
tasks/vm_template.yml Normal file
View File

@ -0,0 +1,71 @@
---
# tasks file for proxmox
- name: Create instance
community.general.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.general.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