Ansible如何实现任务仅在指定主机运行而非所有inventory主机
解决方案
你当前的问题本质是循环执行ps任务时没有做主机和应用的归属校验,导致所有主机都会遍历执行所有app的检查命令。直接利用Ansible内置的group_names变量(存储当前主机所属的所有inventory组名列表)添加条件判断即可,同时补上你需要全局执行的uptime任务,修正循环变量的输出逻辑。
修正后的完整playbook
- hosts: "{{ appname.split(',') | product(['_webapp']) | map('join') | list }}" user: user1 gather_facts: no tasks: # 全量主机执行的uptime任务 - name: Execute uptime on all hosts raw: uptime register: uptime_res - name: Print uptime result debug: msg: "{{ uptime_res.stdout }}" # 仅归属主机执行对应app的ps检查 - name: Check app process status raw: "ps -ef | grep {{ item }}" register: ps_res loop: "{{ appname.split(',') }}" # 核心判断:当前主机属于对应app的主机组才执行 when: item + '_webapp' in group_names - name: Print process check result debug: msg: "{{ item.stdout }}" loop: "{{ ps_res.results }}" # 跳过被条件拦截未实际执行的循环项 when: item is not skipped
逻辑说明
- hosts行的写法做了简化,和你原有写法效果一致,会自动匹配传入app名对应的
xxx_webapp主机组 - uptime任务无额外条件,会在play覆盖的所有3台主机上执行,满足第一类命令的要求
- ps任务的when条件会在每次循环时校验:比如循环到app1时,只有属于
app1_webapp组的host3.mybank.com会执行对应ps命令,其余两台主机会直接跳过该次循环,不会执行无关命令 - 由于带循环的任务注册的变量是包含所有循环结果的列表,所以输出ps结果时需要遍历
ps_res.results,同时跳过未执行的项避免报错
执行时直接用你原来的命令即可:
ansible-playbook -i my.hosts main.yml -e appname=app1,app2,app3
内容的提问来源于stack exchange,提问作者Ashar
相关产品推荐
相关产品推荐

