如何提取Ansible事实生成VMware DRS反亲和规则所需的指定格式VM列表
首先需要纠正你之前写法的错误:vmware_vm_vm_drs_rule 模块的 vms 参数需要传入规则覆盖的所有VM的完整列表,你用loop循环给vms传单个VM的写法会反复覆盖同名规则,最终规则内只会保留最后一个VM,完全无法实现多VM反亲和的需求。
解决方法
步骤1:提前收集appX组主机的事实
需要先确保所有appX组主机的系统事实已经收集完成,才能从hostvars中读取到主机名和默认IP信息,参考play结构如下:
--- - name: 收集appX组主机事实 hosts: appX gather_facts: True # 仅收集需要的字段,加快收集速度 gather_subset: - '!all' - 'network' - 'hostname' tasks: [] # 空任务段,仅用于事实收集
步骤2:直接拼接生成要求格式的VM列表
第二个play在本地执行创建DRS规则,直接通过Jinja2列表推导式生成主机名_IP格式的列表传入vms参数即可:
- name: 创建VMware DRS反亲和规则 hosts: localhost gather_facts: False vars_files: - vars/vsphere.yml # 存储vcenter登录变量的文件可自行调整 tasks: - name: 为appX创建反亲和规则 community.vmware.vmware_vm_vm_drs_rule: hostname: '{{ vcenter_hostname }}' username: '{{ vcenter_username }}' password: '{{ vcenter_password }}' validate_certs: False # 如vcenter是自签证书可加上这个参数避免报错 cluster_name: '{{ vsphere_cluster }}' enabled: True vms: "{{ [ for h in groups['appX']: hostvars[h]['ansible_hostname'] ~ '_' ~ hostvars[h]['ansible_default_ipv4']['address'] ] }}" drs_rule_name: appX_rule mandatory: True affinity_rule: False run_once: True
低版本Ansible兼容方案
如果你使用的Ansible版本低于2.10,不支持Jinja2列表推导式,可以用json_query过滤器实现同等效果,需要提前安装jmespath依赖:
pip install jmespath
对应vms参数的写法调整为:
vms: "{{ groups['appX'] | map('extract', hostvars) | map('json_query', 'ansible_hostname + `_` + ansible_default_ipv4.address') | list }}"
异常兼容处理
如果担心部分主机的ansible_default_ipv4字段不存在导致执行报错,可以加default过滤器设置默认值/跳过逻辑:
vms: "{{ [ for h in groups['appX']: hostvars[h]['ansible_hostname'] ~ '_' ~ hostvars[h]['ansible_default_ipv4']['address'] | default('0.0.0.0') ] }}"
内容的提问来源于stack exchange,提问作者sirjames2004
相关产品推荐
相关产品推荐

