Exercise 05 — Operating the Cluster

Ansible for Proxmox VE · Module 05

Author

credativ GmbH

~20 min · in ~/ansible-proxmox · needs a working cluster from exercise 03

Objective: give the cluster storage, a service account, and a guest that installs itself — all through the API, from one playbook.

NoteWhere to look

Everything here was on the slides. The handout has each task in full, with the curl equivalent and a link into the API viewer of your own cluster (https://192.168.0.1:8006/pve-docs/api-viewer/). proxmox_storage · proxmox_user · proxmox_kvm · proxmox_backup · blockinfile

playbooks/30-operations.yml is a skeleton again: the play structure, the module_defaults block and every task name are there, each body a TODO. inventory/group_vars/all.yml already holds the values.

1 — Check the ground before you build on it

The variables assume things about your cluster. Verify the one that actually varies:

ansible pve01 -m ansible.builtin.command -a 'pvesm status'

Done when: the Name column contains the storage named in pve_vm_storage. On this lab that is local-lvm; on a ZFS install it would be local-zfs.

2 — Storage, in two halves

Two tasks, two different worlds — that is the lesson of this one:

  • the backup directory on the nodes, plus a snippets/ beneath it: file, over SSH, on every host, and copy for files/qemu-guest-agent.yaml
  • the same directory registered as cluster storage: proxmox_storage, type: dir, content: [backup, snippets], one API call for the whole cluster
  • and the shared NFS library: proxmox_storage, type: nfs, content: [import, iso, vztmpl]
ansible-doc community.proxmox.proxmox_storage

Done when: the three task bodies no longer say TODO.

3 — A service account with a token

Three tasks: the group, the user with a token, and the permission on /.

privsep: false gives the token its user’s permissions. With privsep: true the token additionally needs its own ACL, and the effective rights are the intersection of both — a token that works perfectly for one call and returns an empty list for the next is almost always this.

The API returns a token secret exactly once, at creation. The playbook writes it to ~/pve-token.json; module 06 needs it.

Done when: those three bodies no longer say TODO.

4 — A guest that installs itself

Four tasks: activate the NFS library and find the image, create the VM from it, start it, wait for SSH.

ansible-doc community.proxmox.proxmox_kvm    # scsi, ide, net, boot, sshkeys, timeout

The VM also gets agent: "enabled=1" and the cicustom: line from the slides, so the guest installs qemu-guest-agent on first boot. Mind which keyword you use — one of the two throws your SSH key away.

Read the comment above the first of them before you write it. Proxmox VE mounts an NFS storage on first activation, not when you attach it, so importing in the same run fails with can't find file — and waiting for the path does not help, because nothing has asked the node to mount it yet. Listing the contents activates the storage and confirms the image in one go.

Then add the backup task after it.

Done when: the bodies are filled in. Do not run it yet.

5 — The direct route, then run it

The last play edits /etc/network/interfaces on the node with blockinfile and applies it with ifreload -a. No module owns this file.

ifreload -a applies the change immediately. Get the block wrong and you can cut the node off the network. That is why the playbook keeps a pristine copy first, and why the marker comment matters: blockinfile uses it to find its own block again instead of appending a second one on every run.

Now run the whole thing, twice:

ansible-playbook playbooks/30-operations.yml
ansible-playbook playbooks/30-operations.yml

Done when: the first run looks like this, and the second is quiet apart from one task:

# first run
localhost : ok=11  changed=9  unreachable=0  failed=0
pve01     : ok=2   changed=2  unreachable=0  failed=0
pve02     : ok=2   changed=2  unreachable=0  failed=0
pve03     : ok=5   changed=5  unreachable=0  failed=0

# second run
localhost : ok=10  changed=1  unreachable=0  failed=0  skipped=1
pve01     : ok=2   changed=0  unreachable=0  failed=0
pve02     : ok=2   changed=0  unreachable=0  failed=0
pve03     : ok=4   changed=0  unreachable=0  failed=0

That changed=1 is Back up the VM, and it will never be anything else: a backup is an action, not a state, so there is nothing for the module to compare against.

Two counts also drop. localhost reports skipped=1, and pve03 goes from five tasks to four. Different reasons, both in the playbook. Find them.

web01 is running in the GUI, and ssh student@192.168.0.120 gets you in without a password.

If you finish early

  • Stop web01 with proxmox_kvm, start it again, then run the same task a second time. Note which of the four runs says changed.
  • Move it to another node while it keeps running, then move it back. The slides showed which option the local disk needs.
  • Try state: absent on the running guest. Read the msg in the output before you decide whether it worked.
  • Look at ~/pve-token.json. Why can the playbook only write it once?
  • Open the API viewer and find POST /nodes/{node}/qemu. Compare its parameter names with the options you passed to proxmox_kvm.
  • Create a container instead: community.proxmox.proxmox with pve_ct_template.
  • Add a second guest by changing pve_vm_id and pve_vm_name on the command line with --extra-vars.
  • Scheduled backup jobs have no module. Find the API path that would create one.

Solutions

Solutions are discussed live with the trainer.