Short answer: Instead of creating the items one by one; complexity O(mn) where m is the number of remote hosts and n is the number of items (files, directories, links, ...), create, transfer, and unpack an archive(s); complexity O(m). As a hint, see the comparison below (each set repeated 3 times)
- m=2 n=10 (16.68s, 16.37s, 16.59s) (example 3; 10 directories)
- m=2 n=20 (33.82s, 34.95s, 33.95s) (no example; 20 directories)
- m=2 n=1 (7.06s, 6.93s, 6.46s) (example 4; 1 directory and 1 archive)
- m=1 n=10 (15.33s, 15.03s, 14.89s) (example 5; 10 directories)
- m=1 n=20 (28.77s, 29.21s, 29.83s) (no example; 20 directories)
- m=1 n=1 (6.27s, 5.99s, 6.26s) (example 6; 1 directory and 1 archive)
(The remote directories were always deleted before the test.)
Test serial/fork and different matrix of hosts/items on your own.
Details:
- Create data for testing
Given the simplified list of files for testing
my_files:
- value: X/d0
- value: X/d1
- value: X/d2
- value: X/d3
- value: X/d4
- value: X/d5
- value: X/d6
- value: X/d7
- {value: X/d8, mode: "0700"}
- {value: X/d9, mode: "0755"}
Declare the directory for the files and the path for the archive. For example,
tar_file: /tmp/tar_files.gz
some_dir: /tmp/test_files
Create the files and the archive on the localhost
- name: Create local files
file:
state: directory
path: "{{ some_dir }}/{{ item.value }}"
mode: "{{ item.mode|default('0755') }}"
loop: "{{ my_files }}"
delegate_to: localhost
run_once: true
when: create_local_files|d(false)|bool
- name: Create local tar
archive:
path: "{{ some_dir }}/*"
dest: "{{ tar_file }}"
delegate_to: localhost
run_once: true
when: create_local_tar|d(false)|bool
gives
shell> tree /tmp/test_files/
/tmp/test_files/
└── X
├── d0
├── d1
├── d2
├── d3
├── d4
├── d5
├── d6
├── d7
├── d8
└── d9
11 directories, 0 files
shell> tar tvf /tmp/tar_files.gz
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d5/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d2/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d1/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d3/
drwx------ admin/admin 0 2022-12-11 16:20 X/d8/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d9/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d0/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d7/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d4/
drwxr-xr-x admin/admin 0 2022-12-11 16:20 X/d6/
The above tasks are idempotent
shell> ansible-playbook pb.yml -e create_local_files=true
shell> ansible-playbook pb.yml -e create_local_tar=true
- Create the playbook for testing (2 remote hosts, 10 directories)
- hosts: test_11,test_13
vars:
tar_file: /tmp/tar_files.gz
some_dir: /tmp/test_files
my_files:
- value: X/d0
- value: X/d1
- value: X/d2
- value: X/d3
- value: X/d4
- value: X/d5
- value: X/d6
- value: X/d7
- {value: X/d8, mode: "0700"}
- {value: X/d9, mode: "0755"}
tasks:
- name: Create local files
file:
state: directory
path: "{{ some_dir }}/{{ item.value }}"
mode: "{{ item.mode|default('0755') }}"
loop: "{{ my_files }}"
delegate_to: localhost
run_once: true
when: create_local_files|d(false)|bool
- name: Create local tar
archive:
path: "{{ some_dir }}/*"
dest: "{{ tar_file }}"
delegate_to: localhost
run_once: true
when: create_local_tar|d(false)|bool
- name: Unpack remote files
block:
- file:
state: directory
path: "{{ some_dir }}"
- unarchive:
src: "{{ tar_file }}"
dest: "{{ some_dir }}"
when: unpack_remote_files|d(false)|bool
- name: Create remote files
file:
state: directory
path: "{{ some_dir }}/{{ item.value }}"
mode: "{{ item.mode | default('0755') }}"
loop: "{{ my_files }}"
when: create_remote_files|d(false)|bool
- Create remote files one by one. Profile the tasks
shell> ANSIBLE_STDOUT_CALLBACK=ansible.posix.profile_tasks ansible-playbook pb.yml -e create_remote_files=true
Sunday 11 December 2022 20:47:32 +0100 (0:00:00.036) 0:00:00.036 *******
Sunday 11 December 2022 20:47:32 +0100 (0:00:00.083) 0:00:00.120 *******
Sunday 11 December 2022 20:47:32 +0100 (0:00:00.037) 0:00:00.158 *******
Sunday 11 December 2022 20:47:32 +0100 (0:00:00.049) 0:00:00.208 *******
Sunday 11 December 2022 20:47:32 +0100 (0:00:00.052) 0:00:00.261 *******
Sunday 11 December 2022 20:47:49 +0100 (0:00:16.682) 0:00:16.943 *******
===============================================================================
Create remote files ------------------------------------------------------------------ 16.68s
Create local files -------------------------------------------------------------------- 0.08s
unarchive ----------------------------------------------------------------------------- 0.05s
file ---------------------------------------------------------------------------------- 0.05s
Create local tar ---------------------------------------------------------------------- 0.04s
shell> ssh admin@test_11 ls -la /tmp/test_files/X
total 14
drwxr-xr-x 12 root wheel 12 Dec 11 19:47 .
drwxr-xr-x 3 root wheel 3 Dec 11 19:47 ..
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d0
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d1
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d2
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d3
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d4
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d5
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d6
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d7
drwx------ 2 root wheel 2 Dec 11 19:47 d8
drwxr-xr-x 2 root wheel 2 Dec 11 19:47 d9
shell> ssh admin@test_13 ls -la /tmp/test_files/X
...
The directories were created in 16.68s (repeated 2 more times in 16.37s and 16.59s).
- Unarchive remote files. Profile the tasks
(remove the remote files /tmp/test_files)
shell> ANSIBLE_STDOUT_CALLBACK=ansible.posix.profile_tasks ansible-playbook pb.yml -e unpack_remote_files=true
Sunday 11 December 2022 20:53:26 +0100 (0:00:00.034) 0:00:00.034 *******
Sunday 11 December 2022 20:53:26 +0100 (0:00:00.082) 0:00:00.116 *******
Sunday 11 December 2022 20:53:26 +0100 (0:00:00.038) 0:00:00.155 *******
Sunday 11 December 2022 20:53:28 +0100 (0:00:02.084) 0:00:02.239 *******
Sunday 11 December 2022 20:53:33 +0100 (0:00:04.979) 0:00:07.219 *******
Sunday 11 December 2022 20:53:33 +0100 (0:00:00.111) 0:00:07.331 *******
===============================================================================
unarchive ----------------------------------------------------------------------------- 4.98s
file ---------------------------------------------------------------------------------- 2.08s
Create remote files ------------------------------------------------------------------- 0.11s
Create local files -------------------------------------------------------------------- 0.08s
Create local tar ---------------------------------------------------------------------- 0.04s
The directories were created and unarchived in 7.06s (2.08s + 4.98s) (repeated 2 more times in 6.93s (2.04s + 4.89s) and 6.46s (1.76s + 4.70s)).
- Create remote files one by one. Single remote host
- hosts: test_11
Profile the tasks.
The directories were created in 15.33s (repeated 2 more times in 15.03s and 14.89s).
- Unarchive remote files. Single remote host
- hosts: test_11
Profile the tasks.
The directories were created and unarchived in 6.27s (1.93s + 4.34s) (repeated 2 more times in 5.99s (1.59s + 4.40s) and 6.26s (1.91s + 4.35s)).