You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:20:31