Ansible读取嵌套JSON匹配变量查询VMware虚拟机电源状态方法
Ansible 匹配VMware虚拟机信息实现方案
前置校验:确认变量结构
首先先通过debug确认两个核心变量的结构,避免字段名不匹配导致取值失败:
# 确认vmware_vm_info返回的字段名和层级 - name: 打印虚拟机查询返回结构 ansible.builtin.debug: var: vminfo.instances # 确认CSV读取后的虚拟机列名 - name: 打印CSV读取结果 ansible.builtin.debug: var: vm_csv_list
说明:
vmware_vm_info模块默认返回的所有虚拟机信息存放在vminfo.instances列表下,每个元素包含guest_name(虚拟机名)、power_state(电源状态)两个核心字段,如果你自定义了返回变量层级请对应调整路径。
方法1:使用selectattr过滤器实现匹配(无需额外依赖)
优先推荐该方案,不需要安装jmespath依赖,语法容错率更高:
- name: 匹配CSV虚拟机名并绑定电源状态 ansible.builtin.set_fact: # 生成带电源状态的虚拟机列表,供后续流程调用 vm_with_power_state: "{{ vm_with_power_state | default([]) + [item | combine({'power_state': matched_vm.power_state})] }}" vars: # 筛选guest_name和当前CSV行vmname完全匹配的虚拟机条目 matched_vm: "{{ vminfo.instances | selectattr('guest_name', '==', item.vmname) | first | default({}) }}" loop: "{{ vm_csv_list.list }}" # 过滤匹配不到的虚拟机条目,避免报错 when: matched_vm | length > 0
注意:请将
item.vmname替换为你CSV文件中虚拟机名称对应的列名,比如CSV列名为vm_name则修改为item.vm_name。
方法2:修复json_query匹配写法
如果要使用json_query,首先要解决两个常见的失败原因:
- 控制节点提前安装jmespath依赖:执行
pip install jmespath - 注意查询语句的引号转义规则,正确写法如下:
- name: 使用json_query匹配获取电源状态 ansible.builtin.set_fact: vm_with_power_state: "{{ vm_with_power_state | default([]) + [item | combine({'power_state': matched_power | first})] }}" vars: query_str: "instances[?guest_name == '{{ item.vmname }}'].power_state" matched_power: "{{ vminfo | json_query(query_str) | default([]) }}" loop: "{{ vm_csv_list.list }}" when: matched_power | length > 0
后续流程使用示例
你可以直接用生成的带电源状态的列表做开关机判断:
- name: 批量关闭处于运行状态的虚拟机 community.vmware.vmware_guest_powerstate: hostname: "{{ item.vcenter_host }}" username: "{{ item.vcenter_username }}" password: "{{ item.vcenter_password }}" name: "{{ item.vmname }}" state: powered-off validate_certs: no loop: "{{ vm_with_power_state }}" when: item.power_state == "poweredOn"
注意事项
- 同vCenter下存在重名虚拟机时,以上方案只会取第一个匹配的条目,建议额外加
uuid或者文件夹路径作为二次匹配条件 - 匹配不到的虚拟机会被自动过滤,你可以修改
default参数设置默认值(比如default('unknown'))来保留所有条目
内容的提问来源于stack exchange,提问作者Julia L
相关产品推荐
相关产品推荐

