--- - name: Backup selected Proxmox VMs and LXCs hosts: proxmox become: true vars: backup_dir: "/var/lib/vz/dump" storage: "local" compression: "zstd" maxfiles: 3 guests: #- { id: 104, type: "lxc", name: "jellyfin" } - { id: 108, type: "lxc", name: "docker" } #- { id: 101, type: "qemu", name: "pnetlab" } tasks: - name: Ensure backup directory exists file: path: "{{ backup_dir }}" state: directory mode: '0755' - name: Run vzdump backup with logging shell: | LOGFILE="{{ backup_dir }}/proxmox_backup.log" START=$(date +%s) echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting backup of {{ item.name }} ({{ item.type }}) [ID: {{ item.id }}]" >> "$LOGFILE" OUTPUT=$(vzdump {{ item.id }} --mode stop --compress {{ compression }} --storage {{ storage }} --remove 0 2>&1) STATUS=$? END=$(date +%s) DURATION=$((END - START)) if [ $STATUS -eq 0 ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✅ SUCCESS - {{ item.name }} [{{ item.id }}] - Duration: ${DURATION}s" >> "$LOGFILE" else echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ FAILURE - {{ item.name }} [{{ item.id }}] - Duration: ${DURATION}s" >> "$LOGFILE" echo "---- ERROR OUTPUT ----" >> "$LOGFILE" echo "$OUTPUT" >> "$LOGFILE" echo "----------------------" >> "$LOGFILE" fi args: executable: /bin/bash loop: "{{ guests }}" - name: Rename backup files to include guest name shell: | latest_file=$(ls -t {{ backup_dir }}/vzdump-{{ item.type }}-{{ item.id }}-*.{{ compression }} | head -n 1) new_file="{{ backup_dir }}/{{ item.name }}-{{ item.type }}-{{ item.id }}-{{ '%Y%m%d-%H%M%S' | strftime(ansible_date_time.epoch | int) }}.{{ compression }}" cp "$latest_file" "$new_file" args: executable: /bin/bash loop: "{{ guests }}" - name: Prune old backups (keep last {{ maxfiles }}) shell: | ls -tp {{ backup_dir }}/{{ item.name }}-{{ item.type }}-{{ item.id }}-*{{ compression }} | grep -v '/$' | tail -n +{{ maxfiles + 1 }} | xargs -r rm -- args: executable: /bin/bash loop: "{{ guests }}"