Ansible role: delegated_vm_install 1.0.0 released

3 minute read


I use KVM and cloud-init to provision virtual machines on my home network and wrote a few articles about it.

on my blog on how to use cloud images with cloud-init on a “non-cloud” environment.

I created an Ansible role: ansible-role-virt_install_vm for it.

This role works great, but I wanted to have the possibility to provision the virtual machine in a delegated way.

For this reason I create the ansible role delegated_vm_install.

Delegated_vm_install 1.0.0 is available at:

Have fun!

Delegated VM install

An Ansible role to install a libvirt virtual machine with virt-install and cloud-init.

This role is designed to delegate the install to a libvirt hypervisor.


The role is a wrapper around the following roles:

Install the required roles with

$ ansible-galaxy install -r requirements.yml

this will install the latest default branch releases.

Or follow the installation instruction for each role on Ansible Galaxy.


Ansible galaxy

The role is available on Ansible Galaxy.

To install the role from Ansible Galaxy execute the command below. This will install the role with the dependencies.

ansible-galaxy install stafwag.delegated_vm_install

Source Code

If you want to use the source code directly.

Clone the role source code.

$ git clone

and put into the role search path

Supported GNU/Linux Distributions

It should work on most GNU/Linux distributions. cloud-localds is required. cloud-localds was available on Centos/RedHat 7 but not on Redhat 8. You’ll need to install it manually to use the role on Centos/RedHat 8.

  • Archlinux
  • Debian
  • Centos 7
  • RedHat 7
  • Ubuntu

Role Variables and templates


Virtual Machine specific

  • vm_ip_address: Required. The virtual machine ip address.
  • vm_kvm_host: Required. The hypervisor host the role will delegate the installation.


The delegated_vm_install hash is used for the defaults to set up the virtual machine. If you need to overwrite for a virtual machine or hosts group, you can use the delegated_vm_install_overwrite hash. Both hashes will be merged, if a variable is in both hashes the values of delegated_vm_install_overwrite is used.

  • delegated_vm_install:
    • security: Optional
      • file:
        • user: Default: root
        • group: Default: kvm
        • mode: Default: 660
      • dir:
        • user: Default: root
        • group: Defailt: root
        • mode: Default: 0751
    • post:
      • pause: Optional. Default: seconds: 10
      • update_etc_hosts Optional. Default: true
      • ensure_running Optional. Default: true
      • ensure_running Optional. Default: true
      • package_update Optional. Default: true
      • reboot_after_update Optional. Default: true
      • always Optional. Default: false
    • vm:
      • template: Optional. Default. templates/vms/debian_vm_template.yml The virtual machine template.
      • hostname: Optional. Default: ``````. The vm hostname.
      • path: Optional. Default: /var/lib/libvirt/images/
      • boot_disk: Required src: The path to installation image.
      • size: Optional. Default: 100G
      • disks Optional array with stafwag.qemu_img disks.
      • default_user:
        • name: Default: ``````
        • passwd : The password hash Default !! Set it to false to lock the user.
        • ssh_authorized_keys: The ssh keys default ""
      • dns_nameservers:: Optional. Default:
      • dns_search: Optional. Default ''
      • interface: Optional. Default enp1s0
      • gateway: Required. The vm gateway.
      • reboot: Optional. Default: false. Reboot the vm after cloud-init is completed
      • poweroff: Optional. Default: true. Poweroff The vm after cloud-init is completed
      • wait: Optional. Default: -1. The wait argument passed to virt-install. A negative value will wait till The vm is shutdown. 0 will execut the virt-install command and disconnect
      • commands: Optional. Default []. List of commands to be executed duing the cloud-init phase.
  • delegated_vm_install_overwrite: The overwrite hash.

Return variables

  • vm:
    • hostname: The virtual machine hostname.
    • path: The virtual machine path.
    • default_user: The default user hash.
    • dns_nameservers:: Optional. Default:
    • dns_search: Optional. Default ''
    • interface: Optional. Default enp1s0
    • vm.ip_adress*: Required. The vm ip address.
    • vm.gateway: Required. The vm gateway.
    • qemu_img: An array the qemu_img disks
    • virt_install_import.disks: Disk string array. Used by

Example playbook


Create a inventory.

  • inventory_vms.yml
    ansible_user: staf
    ansible_python_interpreter: /usr/bin/python3
        path: /var/lib/libvirt/images/k3s/
          size: 50G
          - name: "_zfsdata.qcow2"
            size: 20G
            owner: root
        memory: 4096
        cpus: 4
          passwd: false
            - ""
      vm_ip_address: ""
      vm_kvm_host: vicky
      vm_ip_address: ""
      vm_kvm_host: vicky
      vm_ip_address: ""
      vm_kvm_host: vicky


  • create_vms.yml
- name: Setup the virtual machine
  hosts: k3s_cluster
  become: true
  gather_facts: false
    - role: stafwag.delegated_vm_install
        ansible_ssh_common_args: '-o StrictHostKeyChecking=no'

Run the playbook

$ ansible-playbook -i inventory_vms.yml create_vms.yml

Have fun!

Leave a comment