I am making an Ansible task that adds UFW rules. There are sometimes a lot of rules to be added and they are added sequentially (which is expected behaviour of course).
But I don't care about the order of the rules as they don't overlap (they are more like whitelisting from a deny in, deny out, deny forward defaults).
So I thought about using the async/poll features of Ansible to make the loop execution async, as in this stackexchange devops thread.
But is seems using such async does not work for loops, or at least for my loop. If I set poll to 0, the rules are added sequentially as before and not faster. If I set poll to a positive number, it runs even slower than before.
A code snippet of the rule-adding code:
- name: configure | rules
ufw:
rule: "{{ item.rule }}"
interface: "{{ item.interface | default('') }}"
direction: "{{ item.direction | default('in') }}"
from_ip: "{{ item.from_ip | default('any') }}"
to_ip: "{{ item.to_ip | default('any') }}"
from_port: "{{ item.from_port | default('') }}"
to_port: "{{ item.to_port | default('') }}"
protocol: "{{ item.protocol | default('any') }}"
route: "{{ item.route | default(omit) }}"
log: "{{ item.log | default(false) }}"
comment: "{{ item.comment | default(omit) }}"
with_items: "{{ ufw_rules }}"
register: _create_instances
async: 1000
poll: 0
notify: reload ufw
tags:
- ufw-configure-rules
- name: Wait for creation to finish
async_status:
jid: "{{ item.ansible_job_id }}"
register: _jobs
until: _jobs.finished
delay: 5 # Check every 5 seconds. Adjust as you like.
retries: 10 # Retry up to 10 times. Adjust as needed.
with_items: "{{ _create_instances.results }}"
The result is my loop runs item by item, not faster.
About my configuration:
2.5.1
I could generate an ufw rules files or iptables, but my goal in the beginning is interacting with UFW through ansible API.
Consider dividing tasks into smaller groups. For example:
- name: configure | rules
ufw:
.
.
.
with_items: "{{ ufw_rules_set1 }}"
.
.
.
- name: configure next | rules
ufw:
.
.
.
with_items: "{{ ufw_rules_set2 }}"
.
.
.
Then async is going to work and you encounter about 2x speedup. Of course the more stages the more speedup but at some point you reach maximum and dividing further will make you worse off.