--- - name: Create new virtual instance hosts: "{{myhosts}}" gather_facts: false vars: vmhost_uri: "qemu+ssh://root@{{ vmhost }}/system" root_pubkey: "{{ lookup('file', '../../files/ssh/adm.pub') }}" char: "{{ 'bcdefghijklmnopqrstuvwxyz'|list }}" console_log: "/var/log/libvirt/qemu/{{ inventory_hostname }}.console.log" os_disk_image: "/srv/libvirt/os/{{ inventory_hostname }}.a.img" dsk_opts: bus=virtio,cache=none,device=disk,format=raw,sparse=no inject: >- {% if not '--cdrom' in virt_install_os_args %}{{ true }}{% endif %} virt_install_disks: >- {% if datadisks is defined %} {% for i in range(datadisks|count) %} {% if datadisks[i].type is defined %} {% set type = datadisks[i].type %} {% else %} {% set type = "hdd" %} {% endif %} {% set base = "/srv/libvirt/" + type + "/" + inventory_hostname %} {% set size = datadisks[i].size %} --disk {{ base }}.{{ char[i] }}.img,{{ dsk_opts }},size={{ size }} {% endfor %} {% endif %} virt_install_network: >- {% for item in network_interfaces %} {% if item.vlan is defined %} {% if item.mac is defined %} --network bridge=br{{ item.vlan }},mac={{ item.mac }},model=virtio {% else %} --network bridge=br{{ item.vlan }},model=virtio {% endif %} {% endif %} {% endfor %} tasks: - name: Get VM list community.libvirt.virt: command: list_vms delegate_to: "{{ vmhost }}" register: result check_mode: false - name: Clean up old facts cache ansible.builtin.file: path: "{{ ansible_dir_root }}/facts/{{ inventory_hostname }}" state: absent delegate_to: localhost when: inventory_hostname not in result.list_vms - name: Create temp directory ansible.builtin.tempfile: state: directory register: tmpdir delegate_to: "{{ vmhost }}" when: - inventory_hostname not in result.list_vms - inject is defined - name: Create inject file ansible.builtin.copy: content: | rootpw --lock %post umask 077 mkdir -p /root/.ssh echo '{{ root_pubkey }}' > /root/.ssh/authorized_keys %end dest: "{{ tmpdir.path }}/include.ks" mode: "0600" owner: root group: "{{ ansible_wheel }}" delegate_to: "{{ vmhost }}" when: - inventory_hostname not in result.list_vms - inject is defined - name: Run virt-install ansible.builtin.command: > virt-install --name {{ inventory_hostname }} \ --graphics none --boot useserial=on --noautoconsole \ --serial pty,log.file={{ console_log }} --sound none \ --vcpus "sockets=1,cores={{ num_cpus }},threads=1,placement=auto" \ --memory {{ mem_size }} --cpu host-passthrough \ --disk {{ os_disk_image }},{{ dsk_opts }},size={{ dsk_size }} \ {% if virt_install_os_variant is defined -%} --os-variant {{ virt_install_os_variant }} \ {% endif -%} {% if inject -%} --initrd-inject {{ tmpdir.path }}/include.ks \ {% endif -%} {% if virt_install_devices is defined -%} {% for dev in virt_install_devices -%} {% if dev | regex_search('^/dev/tty') -%} --serial dev,path={{ dev }} {% else -%} --hostdev {{ dev }} \ {% endif -%} {% endfor -%} {% else -%} --controller usb,model=none \ {% endif -%} {{ virt_install_disks }} \ {{ virt_install_network }} \ {{ virt_install_os_args }} delegate_to: "{{ vmhost }}" when: inventory_hostname not in result.list_vms - name: Wait for install to finish community.libvirt.virt: name: "{{ inventory_hostname }}" command: status register: vmstatus until: vmstatus.status == "shutdown" retries: 1000 delay: 20 delegate_to: "{{ vmhost }}" when: inventory_hostname not in result.list_vms - name: Clean tempdir ansible.builtin.file: path: "{{ tmpdir.path }}" state: absent delegate_to: "{{ vmhost }}" when: tmpdir.path is defined - name: Start VM community.libvirt.virt: name: "{{ inventory_hostname }}" command: start delegate_to: "{{ vmhost }}" when: inventory_hostname not in result.list_vms - name: Wait for ssh to start ansible.builtin.wait_for: delay: 10 host: "{{ inventory_hostname }}" port: 22 state: started timeout: 1200 delegate_to: localhost when: inventory_hostname not in result.list_vms - name: Get SSH public keys from new host ansible.builtin.command: argv: - ssh-keyscan - -t - ed25519 - "{{ inventory_hostname }}" delegate_to: localhost register: hostkeys when: inventory_hostname not in result.list_vms - name: Add new SSH host key to known_hosts ansible.builtin.known_hosts: path: /root/.ssh/known_hosts key: "{{ item }}" host: "{{ inventory_hostname }}" with_items: "{{ hostkeys.stdout.splitlines() }}" delegate_to: localhost when: inventory_hostname not in result.list_vms - name: Install python if required ansible.builtin.command: argv: - ssh - "{{ inventory_hostname }}" - "{{ virt_install_python_cmd }}" delegate_to: localhost when: - inventory_hostname not in result.list_vms - virt_install_python_cmd is defined