Ansible技术问题:汇总所有主机脚本输出并单次发送至API
解决Ansible多主机脚本结果汇总后单次发送API的问题
你的核心问题是原方案中set_fact定义的inventory_data属于单主机作用域变量,无法跨主机累加其他节点的执行结果。要实现所有主机数据汇总后单次发送API,可通过hostvars全局变量收集所有主机的注册结果,配合run_once执行单次API请求,修改后的playbook如下:
- name: 收集所有主机inventory数据并发送至API hosts: all remote_user: me tasks: - name: 执行inventory.sh脚本并注册结果 ansible.builtin.script: scripts/inventory.sh register: inventory_result - name: 汇总所有主机的脚本输出 set_fact: aggregated_inventory: | {% for host in ansible_play_hosts %} {{ hostvars[host]['inventory_result'].stdout }} {% endfor %} run_once: true delegate_to: localhost - name: 单次发送汇总数据到API ansible.builtin.uri: url: https://myapi.com/endpoint method: POST body: "{{ aggregated_inventory }}" status_code: 200 body_format: raw run_once: true delegate_to: localhost
关键任务说明
- 执行脚本并注册结果:在所有目标主机上运行
inventory.sh,每台主机的执行结果会独立存储到inventory_result变量中。 - 汇总所有主机输出:
run_once: true确保该任务仅执行一次ansible_play_hosts获取当前play的全部目标主机列表- 遍历主机列表,通过
hostvars[host]['inventory_result'].stdout提取对应主机的脚本输出,拼接成完整的汇总文本 delegate_to: localhost指定在控制机执行汇总,避免占用远程主机资源
- 发送API请求:
run_once: true保证仅发送一次请求body_format: raw适配纯文本格式的请求体;若API要求JSON格式,可改为body_format: json并调整请求体结构(例如{"inventory_data": "{{ aggregated_inventory }}"})delegate_to: localhost让控制机直接发起API请求,无需通过远程主机转发
可选优化
- 若需过滤执行失败的主机结果,可修改汇总逻辑:
aggregated_inventory: | {% for host in ansible_play_hosts %} {% if hostvars[host]['inventory_result'].rc == 0 %} {{ hostvars[host]['inventory_result'].stdout }} {% endif %} {% endfor %} - 若脚本输出需要按主机名分组,可在循环中添加主机标识:
{{ host }}: {{ hostvars[host]['inventory_result'].stdout }}
内容的提问来源于stack exchange,提问作者Rygo
相关产品推荐
相关产品推荐

