--- - name: Create new virtual instance hosts: "{{myhosts}}" gather_facts: false vars: vmhost_uri: "qemu+ssh://root@{{ vmhost }}/system" root_pubkey: "{{ lookup('file', ansible_private + '/ssh/id_rsa.pub') }}" char: "{{ 'bcdefghijklmnopqrstuvwxyz'|list }}" console_log: "/var/log/libvirt/qemu/{{ inventory_hostname }}.console.log" os_disk_image: "/srv/libvirt/ssd/{{ inventory_hostname }}.a.img" dsk_opts: bus=virtio,cache=none,device=disk,format=raw base: /srv/libvirt/hdd/{{ inventory_hostname }} inject: >- {% if not '--cdrom' in virt_install_os_args %}{{ true }}{% endif %} virt_install_disks: >- {% if datadisks is defined %} {% for i in range(datadisks|count) %} --disk {{ base }}.{{ char[i] }}.img,{{ dsk_opts }},size={{ datadisks[i] }},sparse=no {% 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 virt: uri: "{{ vmhost_uri }}" command: list_vms delegate_to: localhost register: result check_mode: false - name: clean up old facts cache 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 tempfile: state: directory register: tmpdir delegate_to: "{{ vmhost }}" when: - inventory_hostname not in result.list_vms - inject is defined - name: create inject file copy: content: | rootpw --lock %post umask 077 mkdir -p /root/.ssh echo '{{ root_pubkey }}' > /root/.ssh/authorized_keys %end dest: "{{ tmpdir.path }}/include.ks" delegate_to: "{{ vmhost }}" when: - inventory_hostname not in result.list_vms - inject is defined - name: run virt-install 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 -%} --hostdev {{ dev }} \ {% 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 virt: uri: "{{ vmhost_uri }}" name: "{{ inventory_hostname }}" command: status register: vmstatus until: vmstatus.status == "shutdown" retries: 1000 delay: 20 delegate_to: localhost when: inventory_hostname not in result.list_vms - name: clean tempdir file: path: "{{ tmpdir.path }}" state: absent delegate_to: "{{ vmhost }}" when: tmpdir.path is defined - name: start vm virt: uri: "{{ vmhost_uri }}" name: "{{ inventory_hostname }}" command: start delegate_to: localhost when: inventory_hostname not in result.list_vms - name: wait for ssh to start 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 keys from new host local_action: command ssh-keyscan -t ed25519 {{ inventory_hostname }} register: hostkeys when: inventory_hostname not in result.list_vms - name: add new ssh host key to known_hosts 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 command: "ssh {{ inventory_hostname }} '{{ virt_install_python_cmd }}'" delegate_to: localhost when: - inventory_hostname not in result.list_vms - virt_install_python_cmd is defined