如何在Ansible中仅对JSON文件指定的主机执行命令?
解决思路与实现步骤
第一步:修正并优化JSON文件读取逻辑
你原来的shell命令存在错误(直接执行文件路径会报错),这里提供两种可靠的读取方式:
方式1:用Ansible原生模块(无需依赖jq)
推荐用slurp读取文件,再用Ansible内置的JSON解析能力处理,避免对jq的依赖:
- name: 读取host1上的/tmp/hosts.json slurp: src: /tmp/hosts.json register: json_content when: inventory_hostname == groups['group1'][0] run_once: true # 仅在host1上执行一次 - name: 解析JSON提取目标主机列表 set_fact: target_hosts: "{{ (json_content.content | b64decode | from_json) | map(attribute='hostName') | list }}" run_once: true delegate_to: localhost # 将变量存到控制节点,让所有主机都能访问
方式2:保留shell+jq的方式(需处理引号)
如果坚持用jq,要修正命令并清理输出中的引号:
- name: 读取host1上的/tmp/hosts.json shell: cat /tmp/hosts.json | jq '.[].hostName' register: data when: inventory_hostname == groups['group1'][0] run_once: true - name: 清理主机名的引号并生成列表 set_fact: target_hosts: "{{ data.stdout_lines | map('replace', '\"', '') | list }}" run_once: true delegate_to: localhost
第二步:在指定主机上执行命令
通过when条件判断当前主机是否在目标列表中,即可实现仅在指定主机执行任务:
- name: 在目标主机执行ls /tmp shell: ls /tmp when: inventory_hostname in target_hosts
关键注意点
run_once: true:确保读取文件的任务只执行一次,避免重复操作delegate_to: localhost:将目标主机列表变量存储在控制节点,让所有被管理主机都能引用该变量- 最终要得到无引号的主机名字符串数组,这样
inventory_hostname in target_hosts才能正确匹配
内容的提问来源于stack exchange,提问作者Alatau
相关产品推荐
相关产品推荐

