如何用Ansible循环删除指定保留期外的VMware虚拟机快照
解决VMware虚拟机过期快照批量删除的Ansible Playbook问题
目标
删除所有创建时间超过X天的VMware虚拟机快照
已定义变量
cur_time # 当前时间的EPOCH时间戳 resrv_time # 快照保留截止时间的EPOCH时间戳 snap_time # 快照创建时间的EPOCH时间戳
预期执行流程
- 列出所有带EPOCH格式时间戳的虚拟机快照
- 将快照时间戳与保留截止时间对比
- 若
snap_time < resrv_time,则删除该快照
已实现功能
时间戳转EPOCH格式功能正常,且可通过with_dict遍历所有快照,示例代码:
- name: Snapshot loop debug: msg: '{{ ansible_fqdn }} has {{ item.key }} with{{ snap_time }}' with_dict: "{{ vm_facts.instance.snapshots }}" vars: snap_time: '{{ (item.value[0:19]| to_datetime(format="%Y-%m-%dT%H:%M:%S")).timestamp() if item.key == "creation_time" }}' register: snap_name when: item.key == "name" or item.key == "creation_time"
待解决问题
需要实现:循环匹配快照的name与creation_time,当满足snap_time < resrv_time条件时执行删除操作。当前困惑点包括:
- 如何配置双重条件循环
- 如何让快照信息变量全局可见以跨任务调用
解决方案
1. 重构快照数据,关联名称与时间戳
先通过set_fact把分散的快照name和creation_time整合成结构化列表,方便后续统一遍历:
- name: 整理快照为结构化列表 set_fact: vm_snapshots: >- {% set snaps = [] %} {% for snap in vm_facts.instance.snapshots %} {% if snap.key == 'name' %} {% set _ = snaps.append({'name': snap.value}) %} {% elif snap.key == 'creation_time' %} {% set last_snap = snaps.pop() %} {% set _ = last_snap.update({'creation_time': (snap.value[0:19]|to_datetime(format="%Y-%m-%dT%H:%M:%S")).timestamp()}) %} {% set _ = snaps.append(last_snap) %} {% endif %} {% endfor %} {{ snaps }}
2. 遍历结构化列表,执行快照删除
基于整理后的vm_snapshots列表,直接添加条件判断调用VMware快照删除模块:
- name: 删除过期快照 vmware_guest_snapshot: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" datacenter: "{{ datacenter_name }}" name: "{{ ansible_fqdn }}" snapshot_name: "{{ item.name }}" state: absent remove_children: no # 根据需求选择是否删除子快照 loop: "{{ vm_snapshots }}" when: item.creation_time < resrv_time delegate_to: localhost
3. 变量全局可见说明
- 用
set_fact定义的vm_snapshots变量会在当前Play的所有后续任务中全局可用,无需额外配置 - 原代码中
register: snap_name得到的是零散的任务执行结果,不适合跨任务调用,因此推荐用结构化数据整理的方式
关键注意点
- 确保
vm_facts已正确获取到虚拟机快照信息,可通过debug: var=vm_facts.instance.snapshots验证结构 resrv_time需提前计算为EPOCH时间戳,例如保留7天的话:resrv_time: "{{ (ansible_date_time.epoch | int) - (7*86400) }}"
内容的提问来源于stack exchange,提问作者NeilWang
相关产品推荐
相关产品推荐

