如何从Ansible任务文件向父Play返回变量或信息?
问题描述
我有一个Ansible任务,会循环调用单个任务文件处理数组变量:
- ansible.builtin.include_tasks: my_task.yml loop: "{{ my_list }}" - debug: var: my_var
我希望在my_task.yml中创建/更新my_var变量,然后在父Play中使用它。my_task.yml内容如下:
- set_fact: my_var: "{{ my_var | default([]) + ['new value'] }}"
但在父Play中debug输出my_var时,它是空的。我已经尝试过set_fact和set_stats方法,请问如何让my_task.yml中定义的变量在父Play中可用?
解决方案
方法1:使用set_stats持久化累加变量
set_stats可以将变量存储到Ansible的全局统计数据中,支持跨任务甚至跨Play累加。修改my_task.yml如下:
- set_stats: data: my_var: "{{ ansible_stats.my_var | default([]) + ['new value'] }}" aggregate: yes
开启aggregate: yes后,每次循环都会将新值追加到已有的数组中。在父Play中通过ansible_stats.my_var访问最终结果:
- debug: var: ansible_stats.my_var
方法2:通过register收集循环结果再合并(推荐)
这种方式更符合Ansible的循环设计逻辑,避免跨任务变量传递的上下文隔离问题:
- 修改
my_task.yml,直接生成当前迭代需要的值:
- set_fact: item_value: "new value" # 可根据loop的{{ item }}动态生成对应值
- 在父任务中注册所有循环的执行结果,再提取合并:
- ansible.builtin.include_tasks: my_task.yml loop: "{{ my_list }}" register: task_results - set_fact: my_var: "{{ task_results.results | map(attribute='ansible_facts.item_value') | list }}" - debug: var: my_var
task_results.results会包含每次循环的任务输出,通过map(attribute='ansible_facts.item_value')提取每个迭代生成的值,最后转成数组即可。
方法3:通过hostvars强制共享变量(不推荐)
由于include_tasks配合loop时,每个迭代的任务上下文是隔离的,默认set_fact的变量不会在迭代间保留。可以通过直接操作hostvars来强制变量共享:
修改my_task.yml:
- set_fact: my_var: "{{ hostvars[inventory_hostname].my_var | default([]) + ['new value'] }}"
这种方法依赖主机变量存储,在多主机或复杂Play场景下可能出现预期外的行为,仅适用于简单单主机场景。
内容的提问来源于stack exchange,提问作者jeremywat
相关产品推荐
相关产品推荐

