An Ansible playground, starring QEMU.

A handy self-learning tool to play with Ansible, without installing heavy things like Vagrant or parting with cash for cloud instances…

It is assumed the user is starting with a provisioned Alpine disk image. Ansible's minimal requirements are Python and SSH.

Create derived COW-images from the base alpine image,

qemu-img create -f qcow2 -F qcow2 -b alpine.qcow2 alpine2.qcow2

This means that any machines using alpine$i.qcow2 will have their modifications isolated to this "COW layer". Remove the COW layer to start from scratch. alpine.qcow2 will always remain pristine for future runs.

Create COW-images for a cluster of 4 machines,

for i in $(seq 1 4) ; do qemu-img create -f qcow2 -F qcow2 -o backing_file=../alpine.qcow2  alpine$i.qcow2 ; done

The following script is a convenience for starting the cluster,

alpine_cluster_run() {
    pushd $HOME/vdisks/disks/cluster 2>&1>/dev/null
    set -x
    for i in $(seq 1 4); do
	__ssh_port=$((60022 + $i))
	__http_port=$((8022 + $i))
	__https_port=$((8032 + $i))   # BEWARE OFFSET!
	__web_port=$((8099 + $i))
	__disk=alpine$i.qcow2
	__mac_addr=$(printf "DE:AD:BE:EF:00:%02X\n" $i)

	qemu-system-x86_64 \
	    -daemonize \
	    -hda $__disk \
	    -nic user,ipv6=off,model=virtio-net-pci,mac=$__mac_addr,hostfwd=tcp::$__ssh_port-:22,hostfwd=tcp::$__http_port-:80,hostfwd=tcp::$__https_port-:443 \
	    -m 1G \
	    -enable-kvm
    done
    set +x
    popd 2>&1>/dev/null
}

alpine_cluster_run 

With the following hosts definition,

cat hosts 
[webservers]
alpine1 ansible_host=127.0.0.1 ansible_port=60023 
alpine2 ansible_host=127.0.0.1 ansible_port=60024
alpine3 ansible_host=127.0.0.1 ansible_port=60025
alpine4 ansible_host=127.0.0.1 ansible_port=60026

It is now possible to run playbooks on the QEMU cluster,

ansible-playbook webservers <YAML>

Verification of the web service is done thusly,

wget -O- http://localhost:60023

And for https,

wget --no-check-certificate -O- https://localhost:8036

Etc.

As a side-note, you can do PKI for HTTPS like this,

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -subj /CN=localhost -keyout files/nginx.key -out files/nginx.crt

Created: 2021-11-28 Sun 17:57

Validate