In this post, I will show an example on how to manage multi-threading in an Ansible playbook.
The playbook will perform the following steps:
- Connect on the Service-Now API. Use the CMDB table and retrieve a server list. This server list will contain some attributes. You will have to adapt with your own value. In this example the Service-Now attributes will be: name, sys_id and snow_iloip.
- The next step will perform a call to the HP iLO API using the specific Ansible module on each list entries. Each call will be launched as a new thread and will not wait the end to run the next call.
- The next step will wait all the call have been finished and collecting the step output
- Finally we display the job output in two different ways
--- - hosts: localhost gather_facts: no # uncomment if the host where the playbook is run required a proxy to reach the internet # vars: # proxysettings: # http_proxy: http://10.20.30.40:8008/ # https_proxy: http://10.20.30.40:8008/ tasks: - name: Get all server from Service Now CMDB # uncomment if the host where the playbook is run required a proxy to reach the internet # environment: "{{proxysettings}}" uri: url: https://yourcustom.service-now.com/cmdb_ci_server.do?JSONv2&sysparm_action=getRecords&sysparm_query=active return_content: yes headers: Content-Type: "application/json" user: "snow_username" password: "snow_password" status_code: 200 method: GET register: exp_output - name: Call the HP iLO API using the Ansible module called hpilo_facts. We use the attribute called snow_iloip. Adapt with your own Service Now attribute hpilo_facts: host: "{{ item.snow_iloip }}" login: myilouseraccount password: myilopassword # 30 seconds is the average time to run this task async: 30 # fire the task and "forget". When used in a loop, you can parallelize the tasks poll: 0 loop: "{{ exp_output.json.records }}" loop_control: label: "{{ item.name }} {{ item.sys_id }}" register: async_loop - name: Wait. Collecting data... async_status: jid: "{{item.ansible_job_id}}" mode: status ignore_errors: yes # number of retries if the ansible job is not finished retries: 10 # delay in seconds between retries delay: 5 loop: "{{async_loop.results}}" loop_control: label: "{{ item.ansible_job_id }}" register: async_loop_jobs until: async_loop_jobs.finished - name: Display Firmware info when it is defined debug: msg: "{{ item.ansible_facts.hw_health.firmware_information }}" when: item.ansible_facts.hw_health.firmware_information is defined loop: "{{ async_loop_jobs.results }}" loop_control: label: "HP iLO data for {{ item.item.item.name }} (iloip from Snow: {{ item.item.item.snow_iloip }} and serial from iLO: {{ item.ansible_facts.hw_system_serial }})" - name: Display all infos when firmware info is not available debug: msg: "{{ item.ansible_facts }}" when: item.ansible_facts.hw_health.firmware_information is not defined loop: "{{ async_loop_jobs.results }}" loop_control: label: "HP iLO data for {{ item.item.item.name }} (iloip from Snow: {{ item.item.item.snow_iloip }} and serial from iLO: {{ item.ansible_facts.hw_system_serial }})"
Ansible – Manage multi-threading in playbooks