Good day all. It’s been a while.
I’ve created a playbook to find and delete VMware virtual machine snapshots which are 3 days old or older. It works to a point. What I’m not getting is the date format for identifying the snapshots to be deleted. Here’s my code:
---
- hosts: localhost
gather_facts: false
vars:
vault_url: "https://vault.domain.com:443"
vault_token: "{{ lookup('file', '/opt/vault-agent/agent-token') | trim }}"
vault_secret_path: "deploy2/data/deploy-vc"
vcenter_host: "vcenter1bed.domaincorp.domain.com"
datacenter: "Bedford Datacenter"
validate_certs: false
tasks:
- name: Delete old reports
file:
path: '/home/deploy/vm_snapshots.csv'
state: absent
- name: Read vCenter credentials from Vault
community.hashi_vault.vault_read:
url: "{{ vault_url }}"
path: "{{ vault_secret_path }}"
auth_method: token
token: "{{ vault_token }}"
register: secret
tags:
- creds
- name: Set vCenter credentials from Vault
set_fact:
vc_user: "{{ secret.data.data.data.user }}"
vc_pass: "{{ secret.data.data.data.pass }}"
tags:
- creds
- name: Get list of VMs
community.vmware.vmware_vm_info:
hostname: "{{ vcenter_host }}"
username: "{{ vc_user }}"
password: "{{ vc_pass }}"
validate_certs: "{{ validate_certs }}"
register: vm_list
tags:
- listvms
- name: Get snapshots per VM
community.vmware.vmware_guest_snapshot_info:
hostname: "{{ vcenter_host }}"
username: "{{ vc_user }}"
password: "{{ vc_pass }}"
datacenter: "{{ datacenter }}"
validate_certs: "{{ validate_certs }}"
name: "{{ item.guest_name }}"
folder: "/{{ datacenter }}/vm"
loop: "{{ vm_list.virtual_machines }}"
loop_control:
label: "{{ item.guest_name }}"
register: snapshot_data
failed_when: false
tags:
- snaplist
- name: Initialize list of VMs with snapshots
set_fact:
vms_with_snapshots: []
- name: Add each VM with snapshots to the list
set_fact:
vms_with_snapshots: "{{ vms_with_snapshots + [ { 'vm': item.item.guest_name, 'snapshots': item.guest_snapshots.snapshots } ] }}"
when:
- item.guest_snapshots is mapping
- item.guest_snapshots.snapshots is defined
- item.guest_snapshots.snapshots | length > 0
loop: "{{ snapshot_data.results }}"
loop_control:
label: "{{ item.item.guest_name }}"
tags:
- snaplist
- name: Initialize flat snapshot list
set_fact:
all_snapshots: []
- name: Flatten snapshots into a single list
set_fact:
all_snapshots: "{{ all_snapshots + [ item.1 | combine({ 'vm': item.0.vm }) ] }}"
with_subelements:
- "{{ vms_with_snapshots }}"
- snapshots
- name: Sort all snapshots by creation_time
set_fact:
sorted_snapshots: "{{ all_snapshots | sort(attribute='creation_time') }}"
- name: Lookup timestamp string for threshold date (3 days ago)
set_fact:
threshold_date_raw: "{{ lookup('pipe', 'date -u -d \"3 days ago\" +%Y-%m-%dT%H:%M:%SZ') }}"
- name: Parse threshold date into datetime object
set_fact:
threshold_date: "{{ threshold_date_raw | to_datetime('%Y-%m-%dT%H:%M:%SZ') }}"
- name: Delete snapshots older than 3 days
community.vmware.vmware_guest_snapshot:
hostname: "{{ vcenter_host }}"
username: "{{ vc_user }}"
password: "{{ vc_pass }}"
validate_certs: "{{ validate_certs }}"
folder: "/{{ datacenter }}/vm"
datacenter: "{{ datacenter }}"
name: "{{ item.vm }}"
snapshot_name: "{{ item.name }}"
state: present # Use 'present' for testing
when: (item.creation_time | to_datetime('%Y-%m-%dT%H:%M:%S.%f%z')) < (threshold_date | to_datetime('%Y-%m-%dT%H:%M:%SZ'))
loop: "{{ all_snapshots }}"
loop_control:
label: "{{ item.vm }} - {{ item.name }}"
This is the error that's generated when the playbook is run:
TASK [Delete snapshots older than 3 days] *********************************************************************************************
Tuesday 06 May 2025 11:44:03 -0400 (0:00:00.058) 0:03:09.431 ***********
Tuesday 06 May 2025 11:44:03 -0400 (0:00:00.058) 0:03:09.430 ***********
fatal: [localhost]: FAILED! =>
msg: |-
The conditional check '(item.creation_time | to_datetime('%Y-%m-%dT%H:%M:%S.%f%z')) < (threshold_date | to_datetime('%Y-%m-%dT%H:%M:%SZ'))' failed. The error was: time data '2025-05-03 15:44:03' does not match format '%Y-%m-%dT%H:%M:%SZ'
The error appears to be in '/etc/ansible/playbooks/vm/dy_vmsnaprm.yml': line 105, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: Delete snapshots older than 3 days
^ here
This is what output simply listing the extant snapshots looks like:
ok: [localhost] => (item=[{'vm': 'api-dev-01'}, {'id': 2, 'name': 'VM Snapshot 5/2/2025, 9:28:04 AM', 'description': '', 'creation_time': '2025-05-02T13:28:07.321210+00:00', 'state': 'poweredOn', 'quiesced': False}])
Note the format of "creation_time".
Your help, as always, is appreciated.
- playbook
- vmware