In an effort to modernize my workflows I’ve finally started to add roles to my growing collection of Ansible playbooks. The first iteration was to remove some simple copy past I’ve done to make rolling back upgrades simple and nearly perfectly reliable. The previous workflow would be identifying risky updates, shutting down the VM, run a ZFS snapshot, start it up, then run the upgrade. Rolling back was simply reverting the snapshot and starting the VM- easy and almost impossible to screw up. The core issue was that my collection of services has grown to 20+ which means manual processes just didn’t scale.
The role certainly isn’t the cleanest but it gets the job done. Here’s the content of the role:
---
- name: Check if VM exists
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
api_host: "{{ api_host }}"
node: "{{ node }}"
vmid: "{{ vmid }}"
delegate_to: 127.0.0.1
- name: Shutdown VM
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
api_host: "{{ api_host }}"
node: "{{ node }}"
vmid: "{{ vmid }}"
state: stopped
delegate_to: 127.0.0.1
- name: Delete old snapshot
community.general.proxmox_snap:
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
api_host: "{{ api_host }}"
vmid: "{{ vmid }}"
state: absent
snapname: pre-updates
delegate_to: 127.0.0.1
- name: Create new snapshot
community.general.proxmox_snap:
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
api_host: "{{ api_host }}"
vmid: "{{ vmid }}"
state: present
snapname: pre-updates
delegate_to: 127.0.0.1
- name: Pause for 5 seconds
ansible.builtin.pause:
seconds: 5
delegate_to: 127.0.0.1
- name: start VM
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
api_host: "{{ api_host }}"
node: "{{ node }}"
vmid: "{{ vmid }}"
state: started
delegate_to: 127.0.0.1
- name: Pause for 10 seconds
ansible.builtin.pause:
seconds: 20
---
The delegate_to
tags are used as the role is used on playbooks executed on application hosts. This allows me to only have credentials wherever I’m executing it from and deal with the proxmoxer
dependency locally.