Ignacio Verona
Ignacio Verona

Reputation: 655

Ansible: Update a virsh VM

I need to create a playbook to update a VM running in a virsh environment. Steps would be:

  1. Backup some contents of a VM (Done)
  2. Shutdown the vm
  3. Copy the new VM image and XML file
  4. Restore backup (just mount the image and untar a file)
  5. Start up the new VM

I've created a hosts file with some variables:

[virsh-hosts]
host1
host2

[vms]
vm1 hypervisor=host1
vm2 hypervisor=host1
vm3 hypervisor=host2

So, for example when updating VM1 I'll need to connect host1, shutdown the VM1, copy the new image and xml file, define it and startup the new VM.

My question is: How can I connect to VM1's hypervisor (through the variable), exec the shutdown, copy the new images and start the new VM?

As far as I know, all the tasks in a playbook are executed in the host being processed, but I need to exec tasks on different hosts (and get the name of that hosts from a variable).

Maybe delegate_to is the solution here or there is some other way?

Thanks in advance.

Upvotes: 1

Views: 2062

Answers (1)

hkariti
hkariti

Reputation: 1719

You can run your play on the virsh-hosts group, and loop through the vms group with a condition:

- hosts: virsh-hosts
  tasks:
    - name: Do something on all vms on this host
      ping:
      when: hostvars[item].hypervisor == inventory_name
      with_items: groups.vms

You can also run on the vms group and use delegate_to like you said:

- hosts: vms
  gather_facts: no
  tasks:
    - ping:
      delegate_to: "{{hypervisor}}"

The big difference here is the group and host variables available. If you delegate a task, the variables available are still the one of the original machine. That means that even if the task will run on host1, host_vars, group_vars and facts will be those of vm1.

If you don't need the VM's host/group vars, use delegate_to as it allows you to work on several VMs in parallel. You should turn off facts gathering (gather_facts: no after the hosts: vms line), so ansible wouldn't try to ssh to the VM, which probably will be shut down.

If on top of that you don't have any scenario in which you need to contact the VM at all, you can even have ansible always contact the hypervisor when running a play on the VM by setting ansible_ssh_host in the inventory:

[vms]
vm1 ansible_ssh_host=host1

This saves you the repated delegate_to lines.

Upvotes: 2

Related Questions