如何通过Ansible遍历快照信息并删除指定条件的VMware快照?
问题描述
我正在开发一个Ansible角色用于删除VMware快照,为避免误删所有快照,我希望仅删除名称匹配特定字符串且创建时间超过X天的快照。
我已通过vmware_guest_snapshot_info模块收集了各虚拟机的快照详情,并将结果注册到变量中,得到如下字典结构:
{"changed": false, "guest_snapshots": { "current_snapshot": {"creation_time": "2023-06-06T18:31:37.532826+00:00", "description": "Snapshot TEST", "id": 1243, "name": "Patching_Linux2023-06-06", "state": "poweredOff" }, "snapshots": [ {"creation_time": "2023-06-06T14:38:17.909158+00:00", "description": "", "id": 1242, "name": "Linux_test", "state": "poweredOff" }, { "creation_time": "2023-06-06T18:31:37.532826+00:00", "description": "Snapshot TEST", "id": 1243, "name": "Patching_Linux2023-06-06", "state": "poweredOff" } ] } }
我需要处理多快照场景,尝试编写了如下Ansible删除任务(暂未考虑快照过期时间):
- name: Remove old snapshots vmware_guest_snapshot: hostname: "{{ vcenter_hostname_uni }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: myvcenter validate_certs: no #name: "{{ inventory_hostname |upper }}" folder: "{{ vm_folders }}" vm_id: "{{ item.item }}" snapshot_name: "{{ item.name }}" state: absent delegate_to: "{{vcenter_launcher_uni }}" loop: "{{ snapshots_info.name }}" when: item.name is search('Patching_Linux') tags: - clean_patching_snap
我尝试过多种loop和with_items的写法,但始终无法正确访问所有快照名称,请问该如何解决?
解决方案
核心问题是未正确遍历快照列表,同时需要补充过期时间判断逻辑,分步骤解决:
1. 修正遍历逻辑,正确访问快照列表
从你提供的字典结构来看,所有快照都存放在guest_snapshots.snapshots数组中,原任务的loop: "{{ snapshots_info.name }}"路径不存在,需调整指向正确的快照列表。同时修正vm_id的取值(需对应当前虚拟机的标识),调整后的任务如下:
- name: Remove old snapshots matching criteria vmware_guest_snapshot: hostname: "{{ vcenter_hostname_uni }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: myvcenter validate_certs: no folder: "{{ vm_folders }}" vm_id: "{{ vm_id }}" # 替换为你的虚拟机标识变量,比如inventory_hostname或VM ID snapshot_name: "{{ item.name }}" state: absent delegate_to: "{{ vcenter_launcher_uni }}" loop: "{{ snapshots_info.guest_snapshots.snapshots }}" when: - item.name is search('Patching_Linux') tags: - clean_patching_snap
2. 添加创建时间超过X天的判断
要实现过期筛选,需将快照的creation_time转换为Ansible可处理的时间格式,再与当前时间对比。假设要删除超过7天的快照,补充when条件:
- name: Remove old snapshots matching criteria vmware_guest_snapshot: hostname: "{{ vcenter_hostname_uni }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: myvcenter validate_certs: no folder: "{{ vm_folders }}" vm_id: "{{ vm_id }}" snapshot_name: "{{ item.name }}" state: absent delegate_to: "{{ vcenter_launcher_uni }}" loop: "{{ snapshots_info.guest_snapshots.snapshots }}" vars: # 计算快照已存在的天数 snapshot_age_days: "{{ (ansible_date_time.iso8601 | to_datetime - item.creation_time | to_datetime).days }}" when: - item.name is search('Patching_Linux') - snapshot_age_days | int > 7 # 替换为你需要的过期天数 tags: - clean_patching_snap
关键说明
- 如果是批量处理多台虚拟机,需要在外层先循环VM,再嵌套遍历每台VM的快照列表。
to_datetime过滤器要求Ansible 2.9+版本,若使用旧版本,可手动解析时间格式:item.creation_time | strptime('%Y-%m-%dT%H:%M:%S.%f%z')。- 建议先添加
check_mode: yes运行任务,确认待删除快照符合预期后再执行实际删除操作。
内容的提问来源于stack exchange,提问作者Goul
相关产品推荐
相关产品推荐

