Orchestrating Virtual Machines using Ansible and libvirt

Prerequisite

Make sure that libvirt is installed and the qemu:///system connection is working. Add your user to the kvm group.

Set up a Bridge Network

So we can ssh into the VM. Run virt-manager as root and go to Edit -> Connection details. Create a virtual network that looks as follows:

<network>
  <name>network</name>
  <uuid>182ad67f-883a-49a2-972c-8c4393331e4a</uuid>
  <forward mode="nat">
    <nat>
      <port start="1024" end="65535"/>
    </nat>
  </forward>
  <bridge name="virbr0" stp="on" delay="0"/>
  <mac address="52:54:00:ef:53:92"/>
  <domain name="network"/>
  <ip address="192.168.100.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.100.128" end="192.168.100.254"/>
    </dhcp>
  </ip>
</network>

Creating a VM

Install (create) a new VM with a 12GB drive and attach the given ISO to its CD-ROM (note: distros like Fedora require around 14GB just for the base install). Attach it to the virbr0 network bridge so we can ssh into it.

sudo virt-install --name debian10 --ram=4096 --vcpus=2 --disk path=/home/alex/vms/debian10.qcow2,bus=virtio,size=12 -c /home/alex/vms/iso/debian-10.0.0-amd64-xfce-CD-1.iso --network bridge:virbr0 --console pty,target.type=virtio

This will now wait for installation to finish. Open virt-manager as root and you should see the VM as running. Open it and follow the steps to install the distro on the image.

Once installed, open the VM and make sure that the user we will use can sudo without a password.

sudo useradd -m ansible -p ansible
sudo passwd ansible # set to "ansible"
sudo visudo # append "ansible  ALL=(ALL) NOPASSWD: ALL"

Enable the SSH server service.

# for systemd
systemctl enable sshd

On some systems, like OpenSUSE, you need to enable port 22 on the firewall.

firewall-cmd --permanent --add-port=22/tcp
firewall-cmd --reload

Set the hostname to the same name we used for the VM.

sudo hostname-ctl set-hostname debian10

The VM is now saved in virt-manager and can be accessed any time with the libvirt API in qemu:///system.

Generate and Install SSH Keys

Generate an SSH key pair on the host system and install it into each VM so we can SSH without passwords.

ssh-keygen

Check the IP address of VMs using virsh

# optional step to find the name of the network, in this case "network"
sudo virsh net-list

# check IP addresses allocated to each machine
sudo virsh net-dhcp-leases network

Install the SSH keys to each machine (make sure that openssh-server is instaled on each)

ssh-copy-id -i ~/.ssh/ansible_rsa.pub ansible@192.168.100.170

Set up Ansible Hosts

Add the following to /etc/ansible/hosts or somewhere that will be passed to ansible using -i

debian10 ansible_user=ansible ansible_host=192.168.100.170
ubuntu1904 ansible_user=ansible ansible_host=192.168.100.231

Try the following command to verify that ansible can reach the hosts

ansible -i ./ansible-conf.ini -m ping all

Ansible Playbook

Create a playbook. Example:

---

- hosts: ubuntu1904
  tasks:
    - name: Copy file from master to ubuntu1904
      copy: src=. dest=/tmp/mydir

    - name: Ensure dependencies are installed
      become: yes
      apt:
        name: ['libgtk-3-dev', 'help2man', 'python3-sphinx' ]
        update_cache: yes
        state: present

    - name: Make Ubuntu 19.04 build
      shell: cd /tmp/mydir && make clean && make ubuntu1904

    - name: Deploy artifacts
      fetch: src=/tmp/mydir/build/debian10/zrythm_{{ version }}-1_amd64.deb dest=./artifacts/ubuntu1904/zrythm_{{ version }}-1_amd64.deb flat=yes

- hosts: debian10
  tasks:
    - name: Copy file from master to debian10
      copy: src=. dest=/tmp/mydir

    - name: Ensure dependencies are installed
      become: yes
      apt:
        name: ['libgtk-3-dev', 'help2man', 'python3-sphinx' ]
        update_cache: yes
        state: present
        update_cache: yes
        state: present

    - name: Make Debian 10 build
      shell: cd /tmp/mydir && make clean && make debian10
      register: results

    - name: show results
      debug: msg={{ results.stdout_lines }}

    - name: Deploy artifacts
      fetch: src=/tmp/mydir/build/debian10/zrythm_{{ version }}-1_amd64.deb dest=./artifacts/debian10/zrythm_{{ version }}-1_amd64.deb flat=yes

Note: Debian-based systems need to have python-apt installed to use the apt module.

Run the playbook:

ansible-playbook -i ./ansible-conf.ini playbook.yml --extra-vars "version=0.7.186" -v
By Alexandros Theodotou in
Tags : #system, #ansible, #libvirt,