- Add comprehensive Docker user namespace testing documentation - Add Docker configuration rollback runbook for disaster recovery - Add VM snapshot backup playbook for system protection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
207 lines
7.5 KiB
YAML
207 lines
7.5 KiB
YAML
---
|
|
# ==============================================================================
|
|
# VM Snapshot Backup Playbook
|
|
# ==============================================================================
|
|
# Create snapshots of VMs before risky operations
|
|
# Supports KVM/libvirt VMs via hypervisor connection
|
|
# ==============================================================================
|
|
|
|
- name: Create VM Snapshots for Backup
|
|
hosts: localhost
|
|
gather_facts: true
|
|
vars:
|
|
hypervisor_uri: "qemu+ssh://grok@grok.home.serneels.xyz/system"
|
|
snapshot_description: "Pre-maintenance backup"
|
|
snapshot_prefix: "backup"
|
|
target_vms: [] # Empty list means all running VMs
|
|
|
|
tasks:
|
|
- name: Display snapshot operation information
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "=== VM Snapshot Backup Operation ==="
|
|
- "Hypervisor: {{ hypervisor_uri }}"
|
|
- "Date: {{ ansible_date_time.iso8601 }}"
|
|
- "Target VMs: {{ target_vms | default('all running VMs') }}"
|
|
tags: [always]
|
|
|
|
- name: Validate target_vms variable
|
|
ansible.builtin.assert:
|
|
that:
|
|
- target_vms is defined
|
|
- target_vms is iterable
|
|
fail_msg: "target_vms must be a list of VM names"
|
|
tags: [always]
|
|
|
|
# ==========================================================================
|
|
# Get VM List
|
|
# ==========================================================================
|
|
|
|
- name: Get list of all running VMs
|
|
ansible.builtin.shell: |
|
|
ssh grokbox "sudo virsh list --name"
|
|
register: all_vms_raw
|
|
changed_when: false
|
|
when: target_vms | length == 0
|
|
tags: [discover]
|
|
|
|
- name: Parse running VMs list
|
|
ansible.builtin.set_fact:
|
|
discovered_vms: "{{ all_vms_raw.stdout_lines | select() | list }}"
|
|
when: target_vms | length == 0
|
|
tags: [discover]
|
|
|
|
- name: Set final VM list
|
|
ansible.builtin.set_fact:
|
|
vms_to_backup: "{{ target_vms if target_vms | length > 0 else discovered_vms }}"
|
|
tags: [discover]
|
|
|
|
- name: Display VMs to be backed up
|
|
ansible.builtin.debug:
|
|
msg: "VMs to backup: {{ vms_to_backup }}"
|
|
tags: [discover]
|
|
|
|
# ==========================================================================
|
|
# Pre-flight Checks
|
|
# ==========================================================================
|
|
|
|
- name: Check if VMs exist and are running
|
|
ansible.builtin.shell: |
|
|
ssh grokbox "sudo virsh domstate {{ item }}"
|
|
register: vm_states
|
|
failed_when: vm_states.rc != 0
|
|
changed_when: false
|
|
loop: "{{ vms_to_backup }}"
|
|
tags: [validate]
|
|
|
|
- name: Verify all VMs are running
|
|
ansible.builtin.assert:
|
|
that:
|
|
- item.stdout == 'running'
|
|
fail_msg: "VM {{ item.item }} is not running (state: {{ item.stdout }})"
|
|
success_msg: "VM {{ item.item }} is running"
|
|
loop: "{{ vm_states.results }}"
|
|
tags: [validate]
|
|
|
|
- name: Check for existing snapshots
|
|
ansible.builtin.shell: |
|
|
ssh grokbox "sudo virsh snapshot-list {{ item }} --name"
|
|
register: existing_snapshots
|
|
changed_when: false
|
|
loop: "{{ vms_to_backup }}"
|
|
tags: [validate]
|
|
|
|
- name: Display existing snapshots
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "VM: {{ item.item }}"
|
|
- "Existing snapshots: {{ item.stdout_lines | default(['none']) | join(', ') }}"
|
|
loop: "{{ existing_snapshots.results }}"
|
|
tags: [validate]
|
|
|
|
# ==========================================================================
|
|
# Create Snapshots
|
|
# ==========================================================================
|
|
|
|
- name: Generate snapshot name with timestamp
|
|
ansible.builtin.set_fact:
|
|
snapshot_timestamp: "{{ ansible_date_time.epoch }}"
|
|
tags: [snapshot]
|
|
|
|
- name: Create VM snapshots
|
|
ansible.builtin.shell: |
|
|
ssh grokbox "sudo virsh snapshot-create-as {{ item }} \
|
|
--name '{{ snapshot_prefix }}_{{ snapshot_timestamp }}' \
|
|
--description '{{ snapshot_description }} - {{ ansible_date_time.iso8601 }}' \
|
|
--atomic"
|
|
register: snapshot_create
|
|
loop: "{{ vms_to_backup }}"
|
|
tags: [snapshot]
|
|
|
|
- name: Verify snapshot creation
|
|
ansible.builtin.shell: |
|
|
ssh grokbox "sudo virsh snapshot-info {{ item }} {{ snapshot_prefix }}_{{ snapshot_timestamp }}"
|
|
register: snapshot_info
|
|
changed_when: false
|
|
loop: "{{ vms_to_backup }}"
|
|
tags: [snapshot, verify]
|
|
|
|
# ==========================================================================
|
|
# Generate Backup Report
|
|
# ==========================================================================
|
|
|
|
- name: Create backup report directory
|
|
ansible.builtin.file:
|
|
path: "./stats/vm_backups"
|
|
state: directory
|
|
mode: '0755'
|
|
tags: [report]
|
|
|
|
- name: Generate backup report
|
|
ansible.builtin.copy:
|
|
content: |
|
|
================================================================================
|
|
VM SNAPSHOT BACKUP REPORT
|
|
================================================================================
|
|
Date: {{ ansible_date_time.iso8601 }}
|
|
Hypervisor: {{ hypervisor_uri }}
|
|
Snapshot Name: {{ snapshot_prefix }}_{{ snapshot_timestamp }}
|
|
Description: {{ snapshot_description }}
|
|
|
|
VMs Backed Up:
|
|
{% for vm in vms_to_backup %}
|
|
- {{ vm }}
|
|
{% endfor %}
|
|
|
|
Snapshot Details:
|
|
{% for result in snapshot_info.results %}
|
|
|
|
VM: {{ result.item }}
|
|
{{ result.stdout }}
|
|
{% endfor %}
|
|
|
|
ROLLBACK INSTRUCTIONS
|
|
================================================================================
|
|
|
|
To restore a VM to this snapshot:
|
|
|
|
1. Stop the VM (if running):
|
|
ssh grokbox "sudo virsh shutdown <vm_name>"
|
|
|
|
2. Revert to snapshot:
|
|
ssh grokbox "sudo virsh snapshot-revert <vm_name> {{ snapshot_prefix }}_{{ snapshot_timestamp }}"
|
|
|
|
3. Start the VM:
|
|
ssh grokbox "sudo virsh start <vm_name>"
|
|
|
|
To delete this snapshot after verification:
|
|
ssh grokbox "sudo virsh snapshot-delete <vm_name> {{ snapshot_prefix }}_{{ snapshot_timestamp }}"
|
|
|
|
================================================================================
|
|
END OF REPORT
|
|
================================================================================
|
|
dest: "./stats/vm_backups/backup_{{ snapshot_timestamp }}.txt"
|
|
mode: '0644'
|
|
tags: [report]
|
|
|
|
# ==========================================================================
|
|
# Display Summary
|
|
# ==========================================================================
|
|
|
|
- name: Display backup summary
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "=== VM Snapshot Backup Complete ==="
|
|
- "Snapshot Name: {{ snapshot_prefix }}_{{ snapshot_timestamp }}"
|
|
- "VMs Backed Up: {{ vms_to_backup | length }}"
|
|
- "Backup Report: ./stats/vm_backups/backup_{{ snapshot_timestamp }}.txt"
|
|
- ""
|
|
- "⚠️ IMPORTANT NOTES:"
|
|
- "1. Snapshots are point-in-time copies"
|
|
- "2. Test restoration procedure before relying on snapshots"
|
|
- "3. Snapshots consume disk space - clean up old snapshots"
|
|
- "4. For critical changes, consider full VM backups"
|
|
- ""
|
|
- "To restore: virsh snapshot-revert <vm> {{ snapshot_prefix }}_{{ snapshot_timestamp }}"
|
|
tags: [always]
|