--- - name: Check if VM disk exists delegate_to: localhost ansible.builtin.stat: path: "{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2" register: vm_disk_stat - name: Create VM disk when: not vm_disk_stat.stat.exists delegate_to: localhost ansible.builtin.command: qemu-img create -f qcow2 {{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2 {{ vm_size }}G - name: Generate Random MAC Address delegate_to: localhost ansible.builtin.shell: openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | sed 's/^/02:/' changed_when: false register: mac_address_output - name: Render cloud config templates delegate_to: localhost ansible.builtin.template: src: "{{ item.src }}" dest: /tmp/{{ item.dest_prefix }}-{{ hostname }}.yml loop: - { src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data } - { src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config } - name: Create cloud-init disk delegate_to: localhost ansible.builtin.command: cloud-localds {{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}-cloudinit.iso /tmp/cloud-user-data-{{ hostname }}.yml -N /tmp/cloud-network-config-{{ hostname }}.yml - name: Create VM using libvirt delegate_to: localhost community.libvirt.virt: command: define xml: "{{ lookup('template', 'vm.xml.j2') }}" - name: Start vm delegate_to: localhost community.libvirt.virt: name: "{{ hostname }}" state: running