如何在Ansible中按实例编号排序后优先删除最新Azure VM实例
问题:Azure Ansible实例按数字排序并筛选待删除资源
背景说明
在Azure云平台通过Ansible基于instancesCount变量部署任意数量的VM实例,资源命名规则为{{ env }}-xxx-{{ vmName }}-{{ count }},关联资源(NIC、系统磁盘等)会在名称末尾追加标识(如xxx-nic、xxx-osDisk)。
当instancesCount变量值减小(例如从3改为1)时,需要优先删除数字编号最大的最新实例(如dev-xxx-myvm-3、dev-xxx-myvm-2),仅保留编号最小的实例。但通过azure_rm_virtualmachine_info获取的VM列表是无序的(例如10个实例时,dev-xxx-myvm-10会排在dev-xxx-myvm-2之前),导致无法直接用切片运算符[-(to_remove|int):]筛选正确的待删除实例。
解决方案
1. 按名称末尾数字升序排序VM列表
使用Jinja2的sort过滤器,结合自定义排序键从VM名称中提取末尾的数字,将列表按数字升序排列:
- name: 按名称末尾数字升序排序VM列表 set_fact: sorted_vms: "{{ existing_vms.vms | sort(attribute='name', key=lambda x: x.name.split('-')[-1] | int) }}"
逻辑说明:将每个VM名称按-拆分,取最后一段转换为整数作为排序依据,确保dev-xxx-myvm-10排在dev-xxx-myvm-9之后,实现正确的数字升序。
2. 计算待删除的实例数量
- name: 计算待删除的VM数量 set_fact: to_remove: "{{ sorted_vms | length - instancesCount | int }}"
3. 筛选待删除的实例
升序排序后,列表的最后to_remove个元素即为数字编号最大的实例(需要优先删除的最新实例):
- name: 打印待删除的VM名称 debug: var: item.name loop: "{{ sorted_vms[-(to_remove|int):] }}" when: to_remove | int > 0
添加when条件,避免当instancesCount大于等于现有实例数时执行无效循环。
4. 批量删除关联资源
基于筛选出的VM,调用Ansible Azure模块批量删除对应资源:
删除VM
- name: 删除待删除的VM azure_rm_virtualmachine: resource_group: "{{ resource_group }}" name: "{{ item.name }}" state: absent loop: "{{ sorted_vms[-(to_remove|int):] }}" when: to_remove | int > 0
删除关联NIC
- name: 删除关联的NIC azure_rm_networkinterface: resource_group: "{{ resource_group }}" name: "{{ item.name }}-nic" state: absent loop: "{{ sorted_vms[-(to_remove|int):] }}" when: to_remove | int > 0
删除关联系统磁盘
- name: 删除关联的系统磁盘 azure_rm_manageddisk: resource_group: "{{ resource_group }}" name: "{{ item.name }}-osDisk" state: absent loop: "{{ sorted_vms[-(to_remove|int):] }}" when: to_remove | int > 0
内容的提问来源于stack exchange,提问作者Flow
相关产品推荐
相关产品推荐

