Create VMs on KVM with Ansible

So the Ansible virt module doesn’t have a clone option and the creation of guests is a little limited. Because of this we have to use the shell or command modules and try to make them idempotent. This is a simple example and the dictionary can be expanded to a lot more customization. There is a way to use libvirt as a dynamic inventory and set group and host vars on guests, but I’ll cover that in a different post.

---
- name: create VMs
  hosts: kvm
  become: true
  vars_files:
    - vms.yml

  tasks:
    - name: get VM disks
      command: "ls {{ vm_location }}"
      register: disks
      changed_when: "disks.rc != 0"

    - name: create disk
      command: >
               virt-builder --format qcow2 centos-7.4
               -o {{ vm_location}}/{{ item.key }}.{{ item.value.file_type }}
               --root-password password:{{ root_pass }}
      when: item.key not in disks.stdout
      with_dict: "{{ guests }}"

    - name: get list of VMs
      virt:
        command: "list_vms"
      register: vms 

    - name: create vm
      command: >
                virt-install --import --name {{ item.key }}
                --memory {{ item.value.mem }} --vcpus {{ item.value.cpus }}
                --disk {{ vm_location }}/{{ item.key }}.{{ item.value.file_type }}
                --noautoconsole --os-variant {{ item.value.os_type }}
      when: item.key not in vms.list_vms
      with_dict: "{{ guests }}"

    - name: start vm
      virt:
        name: "{{ item.key }}"
        state: running
      with_dict: "{{ guests }}"

So we do a few checks to make sure the disk isn’t already in the directory and another check to make sure the VM isn’t already created. The dictionary is in the referenced vars_file:

---
vm_location: "/data/VMs"
root_pass: "password"

guests:
  test:
    mem: 512
    cpus: 1
    os_type: rhel7
    file_type: qcow2
  test2:
    mem: 512
    cpus: 1
    os_type: rhel7
    file_type: qcow2

Obviously you wouldn’t put the password in plain text, you’d either use ansible-vault, a vars prompt, or a survey in tower.

And here’s our output. I had already created a system called test so it skips over to give us idempotence.

kvm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s