Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Optimizing Ansible Execution: Asynchronous Modes and Performance Tuning

Tech May 12 3

Command-Line Options for Asynchronous Execution

  • -B SECONDS or --background SECONDS: Run tasks asynchronously, failing after specified seconds (default: N/A)
  • -P POLL_INTERVAL or --poll POLL_INTERVAL: Set poll interval when using -B (default: 15 seconds)
  • -f FORKS or --forks FORKS: Specify number of parallel processes (default: 5)

Analyzing Execution Flow with Verbose Output

Use ansible -vvv to inspect task execution. Below is a simplified trace of starting httpd on host 192.168.100.61:

# Configuration loading and handler execution
Using /etc/ansible/ansible.cfg
META: ran handlers

# First task: Gather facts via setup module
Using module: /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py

# Establish SSH connection and retrieve home directory
<192.168.100.61> ESTABLISH SSH CONNECTION
<192.168.100.61> SSH: EXEC ssh ...
<192.168.100.61> (0, '/root\n', '')

# Create remote temporary directory
<192.168.100.61> ESTABLISH SSH CONNECTION
<192.168.100.61> SSH: EXEC ssh ... 'mkdir -p ...'
<192.168.100.61> (0, 'ansible-tmp-...', '')

# Transfer task file via SFTP
<192.168.100.61> PUT /tmp/tmpY5vJGX TO /root/.ansible/tmp/.../setup.py
<192.168.100.61> (0, 'sftp> put ...', '')

# Set execute permissions
<192.168.100.61> ESTABLISH SSH CONNECTION
<192.168.100.61> SSH: EXEC ssh ... 'chmod u+x ...'
<192.168.100.61> (0, '', '')

# Execute task and clean up
<192.168.100.61> ESTABLISH SSH CONNECTION
<192.168.100.61> SSH: EXEC ssh ... '/usr/bin/python ...; rm -rf ...'
<192.168.100.61> (0, '\r\n{...}', 'Connection closed.')

# Second task: Service management via service module
Using module: /usr/lib/python2.7/site-packages/ansible/modules/system/service.py
... (similar connection/task flow) ...

Execution Pattern Summary

  1. Load configuration and inventory data
  2. Execute initial fact-gathering task:
    • Establish SSH connection
    • Create/transfer temporary module file
    • Execute module and return data
  3. Execute primary tasks (same connection pattern as step 2)
  4. Proceed to subsequent tasks

In multi-host executions:

  • Tasks run in parallel across hosts (number controlled by -f)
  • Default synchronous mode: Ansible occupies shell until all hosts complete all tasks
  • Asynchronous mode (-B): Tasks run in background with periodic status checks

Asynchronous Execution Details

  • Without polling (-P 0): Tasks fire-and-forget, shell returns immediately
  • With polling (-P >0): Shell occupied until all background tasks complete

Example async command:

ansible servers -B200 -P 0 -m yum -a "name=dos2unix" -o -f 6

Output:

host1 | SUCCESS => {"ansible_job_id": "...", ...}
host2 | SUCCESS => {"ansible_job_id": "...", ...}

Performance Comparison Examples

# Synchronous (~10s)
ansible group -m command -a "sleep 5" -o

# Async with 5 forks, poll=1 (~10s)
ansible group -B200 -P 1 -m command -a "sleep 5" -o -f 5

# Async with 6 forks, poll=1 (~5-6s)
ansible group -B200 -P 1 -m command -a "sleep 5" -o -f 6

# Async with 5 forks, poll=10 (~20s)
ansible group -B200 -P 10 -m command -a "sleep 5" -o -f 5

Use Cases for Async Mode

Recommended:

  • Long-running tasks risking SSH timeout
  • No dependent tasks
  • Require immediate shell return

Not recommended:

  • Tasks with dependencies
  • Resource-locking operations (e.g., package managers)

Handling Async Dependencies

- name: Install package asynchronously
  yum:
    name: nginx
    state: installed
  async: 1000
  poll: 0
  register: install_task

- name: Verify installation completion
  async_status:
    jid: "{{ install_task.ansible_job_id }}"
  register: task_result
  until: task_result.finished
  retries: 30

Accelerating Execution with -t

Store results in directory for faster subsequent runs:

time ansible group -B200 -P 0 -m yum -a "name=dos2unix" -o -f 6 -t /tmp/results

Subsequent executions show improved speed even without -t.

Optimization Techniques

1. SSH Persistent Connections Add to ansible.cfg:

[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=5d

Requirements:

  • OpenSSH ≥5.6 on control node
  • Creates persistent sockets in ~/.ansible/cp/

2. Pipelining Enable in ansible.cfg:

[defaults]
pipelining = True

Requirements on managed nodes:

  • Disable requiretty in /etc/sudoers

3. Execution Strategy Use free strategy for host-level parallelism:

- hosts: all
  strategy: free
  tasks:
    - ...

4. Fact Caching Configure in ansible.cfg:

[defaults]
gathering = smart
fact_caching_timeout = 86400
fact_caching = jsonfile
fact_caching_connection = /path/to/cache

View cached facts:

cat /path/to/cache/hostname | python -m json.tool

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.