You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible Playbook单任务中并行执行命令后再执行下一任务

如何让Ansible任务中针对多主机的命令并行执行,全部完成后再进入下一个任务

现有Playbook与配置文件

原始Ansible Playbook

---
  - name: ReadJsonfile
    hosts: localhost
    vars:
      input: "{{ lookup('file','hostinfo.json_pb') | from_json }}"
    tasks:
    - name: Image Server(s)
      command: python3 image.pyc {{item.key}} {{item.value.version}}
      with_dict: "{{input}}"
    - name: configure-firstnet on a server
      command: python3 configure_firstnet.pyc {{item.key}} {{item.value.version}} {{item.value.netconf}}
      with_dict: "{{input}}"

对应的hostinfo.json配置

{
 "hosts":
  {
    "abc":
    {
      "username": "root",
      "password": "welcome1",
      "password2": "WElcome1",
      "version": "19.17",
      "toversion" : "19.18.0.0.0",
      "netconf": "bonding",
      "baseversion": "18.8.0.0"
    },
    "xyz":
    {
      "username": "root",
      "password": "welcome1",
      "password2": "WElcome1",
      "version": "19.18",
      "toversion" : "19.18.0.0.0",
      "netconf": "bonding",
      "baseversion": "18.8.0.0"
    }
  }
}

需求说明

需要在两台机器上并发执行以下命令,待这两条命令全部执行完成后,再进入下一个configure-firstnet on a server任务:

python3 image.pyc abc 19.17
python3 image.pyc xyz 19.18

尝试过的配置及问题

  1. 配置1(poll:10)
---
  - name: ReadJsonfile
    hosts: localhost
    vars:
      input: "{{ lookup('file','hostinfo.json_pb') | from_json }}"
    tasks:
    - name: Updating the captured data in the default payload file
      command: python3 updatejson.py
    - name: Image Server(s)
      command: python3 image.pyc {{item.key}} {{item.value.version}}
      register: async_out
      async: 7200
      poll: 10
      with_dict: "{{input}}"

问题:Playbook会先等待abc上的image.pyc执行完成,再执行xyz的,无法实现并行。

  1. 配置2(poll:0)
- name: Image Server(s)
      command: python3 image.pyc {{item.key}} {{item.value.version}}
      register: async_out
      async: 7200
      poll: 0
      with_dict: "{{input}}"

问题:任务会立即在两台服务器上启动命令,然后直接进入下一个configure-firstnet on a server任务,不符合“第二个任务依赖前一个任务全部完成”的要求。

解决方案

通过先启动所有异步任务(poll:0),再单独添加任务等待所有异步任务完成的方式实现需求,完整Playbook如下:

---
- name: ReadJsonfile
  hosts: localhost
  vars:
    input: "{{ lookup('file','hostinfo.json_pb') | from_json }}"
  tasks:
    - name: Updating the captured data in the default payload file
      command: python3 updatejson.py

    - name: 启动异步镜像任务(后台并行执行)
      command: python3 image.pyc {{item.key}} {{item.value.version}}
      register: async_out
      async: 7200
      poll: 0
      with_dict: "{{ input.hosts }}"  # 注意取json中的hosts字段,原input是整个json对象

    - name: 等待所有异步镜像任务完成
      async_status:
        jid: "{{ item.ansible_job_id }}"
      register: async_results
      until: async_results.finished
      retries: 720  # 对应async的7200秒,每10秒重试一次,720*10=7200
      delay: 10
      loop: "{{ async_out.results }}"

    - name: configure-firstnet on a server
      command: python3 configure_firstnet.pyc {{item.key}} {{item.value.version}} {{item.value.netconf}}
      with_dict: "{{ input.hosts }}"

关键说明

  • 第一个任务用poll:0启动所有异步任务,不会等待任务执行,立即返回每个任务的ansible_job_id并注册到async_out中,此时所有任务在后台并行执行。
  • 第二个任务通过async_status模块,遍历所有任务ID轮询状态,until: async_results.finished确保只有当任务完成时才停止轮询,retries和delay控制轮询的次数和间隔,确保覆盖异步任务的超时时间。
  • 注意修正with_dict的取值:原json中的主机信息在hosts字段下,所以应该用{{ input.hosts }}而非{{ input }},否则会遍历整个json的顶级键(如hosts),导致执行错误。

内容的提问来源于stack exchange,提问作者Akash-BLR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:05:47