Ansible playbook存在两组主机时能否指定任务执行顺序?
Ansible多组主机任务执行顺序控制方案
Ansible默认使用linear线性执行策略,playbook中定义的多个play会按书写顺序串行执行,必须等前一个play的所有目标主机的所有任务全部执行完成,才会启动下一个play。你遇到的两组play并行执行的情况,属于异常配置导致的,可按以下步骤排查和修复:
基础排查方案
- 检查执行playbook的命令,是否添加了
--strategy free参数:free策略会打乱任务执行顺序,可能出现跨play提前执行的问题,去掉该参数即可恢复默认顺序逻辑。 - 检查
ansible.cfg全局配置文件,是否设置了strategy = free:如果有该配置,修改为strategy = linear即可。
稳妥实现方案(满足web组全部跑完再执行数据库组要求)
直接在play中显式指定线性策略即可,无需额外修改任务逻辑,修改后的playbook如下:
- hosts: webservers remote_user: root strategy: linear # 显式指定线性执行策略,确保该play所有任务跑完才进下一个play # 若需要控制web组内部并发数,可添加serial参数,例如serial: 2 代表每次同时跑2台web主机 tasks: - name: ensure apache is at the latest version yum: name=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf - hosts: databases remote_user: root tasks: - name: ensure postgresql is at the latest version yum: name=postgresql state=latest - name: ensure that postgresql is started service: name=postgresql state=started
强校验实现方案(避免web组部署失败仍操作数据库)
如果需要严格确保所有web服务器全部部署成功才执行数据库操作,可以添加状态标记和校验逻辑:
- hosts: webservers remote_user: root gather_facts: yes tasks: - name: ensure apache is at the latest version yum: name=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf - name: mark webserver deploy completed set_fact: web_deploy_done: true - hosts: databases remote_user: root gather_facts: yes tasks: - name: confirm all webservers deployed successfully assert: that: - hostvars[item]['web_deploy_done'] is defined and hostvars[item]['web_deploy_done'] == true fail_msg: "Web server {{ item }} deployment failed, abort database operation" loop: "{{ groups['webservers'] }}" - name: ensure postgresql is at the latest version yum: name=postgresql state=latest - name: ensure that postgresql is started service: name=postgresql state=started
该方案会逐一校验所有webservers组的主机部署状态,只要有一台web主机部署失败,数据库组的任务会直接中止,避免异常情况下的脏数据操作。
内容的提问来源于stack exchange,提问作者lone a
相关产品推荐
相关产品推荐

