Ansible循环调用角色时获取所有ovirt_disk模块返回值的方法咨询
我明白你的问题了——循环调用添加磁盘的角色时,要么disk_info被最后一次调用覆盖,要么外层注册的变量拿不到ovirt_disk的实际返回值。这是因为角色内部的注册变量默认不会自动传递到外层循环的注册结果里,得做一点小调整来解决。
解决思路
核心是让角色把ovirt_disk模块的返回值暴露给外层playbook,这样每次循环调用角色的结果里,都会包含对应磁盘的信息。
步骤1:修改你的ovirt_vm_add_disk_role角色
在角色的tasks/main.yml里,注册disk_info的任务之后,添加一个set_fact任务,把磁盘信息保存为一个能被外层访问的变量:
# 你原有的注册disk_info的任务 - name: "Update disk information" ovirt_disk: auth: "{{ ovirt_auth }}" activate: true name: "{{ disk_name }}" poll_interval: 10 vm_name: "{{ HOSTNAME }}" delegate_to: localhost register: disk_info # 新增:把disk_info转为角色对外暴露的变量 - name: Export disk result for outer playbook set_fact: role_disk_result: "{{ disk_info }}" delegate_to: localhost
这个任务的作用是把角色内部的disk_info注册变量,转换成一个可以被外层include_role的结果捕获的变量。
步骤2:在外层playbook中获取所有循环结果
你原来的循环调用角色的代码不需要大改,只需要在后续任务中,从注册的asm_data_devices变量里提取每个循环的磁盘信息:
- name: Add DATA Disks loop vars: disk_name: "{{ HOSTNAME }}_{{ item }}" disk_size: "{{ disk_size }}" disk_storage: "{{ invstorage_domain }}" include_role: name: ovirt_vm_add_disk_role with_items: "{{ disks }}" register: asm_data_devices # 新增:遍历所有循环结果,打印每个磁盘的信息 - name: Show all added disk details debug: msg: "Disk {{ item.item }} info: {{ item.role_disk_result.msg[0] }}" loop: "{{ asm_data_devices.results }}" loop_control: label: "{{ item.item }}" # 只显示磁盘名称,让输出更简洁
这样,asm_data_devices.results数组里的每个元素,都会包含对应那次角色调用的role_disk_result变量,里面就是ovirt_disk模块返回的完整信息。
为什么之前的方法不行?
你之前注册的asm_data_devices里只有循环的元数据(比如item和include_args),是因为角色内部的disk_info是任务级的注册变量,默认不会被包含到include_role的返回结果中。通过set_fact把它转为角色级变量后,Ansible才会把这个变量包含到每次include_role执行的结果里。
另一种可选方案:用全局列表收集结果
如果你更习惯用全局变量来收集所有结果,可以在playbook开头初始化一个空列表,然后在角色里把每次的磁盘信息追加进去:
# 在playbook开头初始化列表 - name: Initialize disk results list set_fact: all_disk_results: [] # 循环调用角色的代码不变 - name: Add DATA Disks loop vars: disk_name: "{{ HOSTNAME }}_{{ item }}" disk_size: "{{ disk_size }}" disk_storage: "{{ invstorage_domain }}" include_role: name: ovirt_vm_add_disk_role with_items: "{{ disks }}" # 在角色里添加追加任务(放在注册disk_info之后) - name: Append disk info to global list set_fact: all_disk_results: "{{ all_disk_results + [disk_info.msg[0]] }}" delegate_to: localhost
循环结束后,all_disk_results就会包含所有磁盘的详细信息。不过这种方法依赖全局变量,不如第一种方法更符合Ansible的模块化思想。
备注:内容来源于stack exchange,提问作者TZar

