实现Ansible首主机执行首任务、其余主机串行执行后两任务的方法
Ansible 差异化任务执行逻辑配置方案
需求匹配逻辑拆解
- 第一个任务仅在123.345.45.1上执行,其余主机不触发该任务
- 第二、第三个任务覆盖从123.345.45.2开始的所有组内主机,执行时采用单台串行规则:单台主机完整跑完两个任务后,再调度下一台主机执行相同流程,禁止多主机并行跑同阶段任务
现有配置兼容说明
当前inventory文件host.yml无需修改,保持原有组定义即可:
[server-group-1] 123.345.45.1 123.345.45.2 123.345.45.3 123.345.45.4 123.345.45.5
两种可落地的配置实现方式
方式一:拆分独立Play(执行日志更清晰,无跳过冗余记录)
通过两个独立的Play分别匹配不同的执行范围和规则,完全避免任务跳过的冗余日志:
# 第一个Play:仅匹配123.345.45.1,执行第一个任务 - name: 执行第一阶段脚本 hosts: 123.345.45.1 gather_facts: false tasks: - name: Execute first sh shell: "/nityo/execute.sh" # 第二个Play:匹配组内除123.345.45.1外的所有主机,开启单台串行执行 - name: 逐台执行第二、第三阶段脚本 hosts: server-group-1:!123.345.45.1 # 采用Ansible原生inventory语法排除第一台主机 gather_facts: false serial: 1 # 核心控制参数:每次仅调度1台主机,在该主机跑完所有Play内任务后,再调度下一台 tasks: - name: Execute second sh shell: "/nityo/script/execute.sh" loop: "{{ loop_3_times }}" - name: Execute third sh shell: "/nityo/bin/execute.sh"
这种方式的执行流程完全匹配要求:
- 先在123.345.45.1上独立跑完第一个脚本
- 第一轮串行调度123.345.45.2,依次跑完第二个、第三个脚本
- 123.345.45.2上两个任务全部执行完成后,调度123.345.45.3,重复相同流程
- 依次推进到123.345.45.4、123.345.45.5完成执行
方式二:单Play内通过条件判断实现(流程集中易管理)
如果希望把所有任务放在同一个Play里管理,可通过条件判断+串行参数实现,配置如下:
- name: 全流程任务执行 hosts: server-group-1 gather_facts: false serial: 1 # 逐台调度主机,单台跑完所有任务后再切下一台 tasks: - name: Execute first sh shell: "/nityo/execute.sh" when: ansible_host == '123.345.45.1' # 仅第一台主机触发该任务 - name: Execute second sh shell: "/nityo/script/execute.sh" loop: "{{ loop_3_times }}" when: ansible_host != '123.345.45.1' # 排除第一台主机触发 - name: Execute third sh shell: "/nityo/bin/execute.sh" when: ansible_host != '123.345.45.1' # 排除第一台主机触发
这种方式的执行顺序和拆分Play完全一致,仅会在非目标主机上显示几个任务跳过的记录,不影响最终执行逻辑。
注意事项
- 默认Ansible采用线性执行策略:同一任务会在所有匹配的主机上跑完,再统一推进到下一个任务,这种模式无法满足“单台主机跑完全部两个任务后再切下一台”的要求,必须通过
serial: 1将执行维度切换为按主机滚动串行 - 原配置中的变量引用
loop: {{ loop_3_times }}建议补充双引号,避免YAML解析时出现语法问题 - 条件判断中匹配主机时,优先用
ansible_host或inventory中定义的主机名做匹配,避免因为facts未加载导致判断失效
内容的提问来源于stack exchange,提问作者salene
相关产品推荐
相关产品推荐

