Put the parameters into a dictionary.
- For example, let's start with the default
shell> cat group_vars/all/scripts.yml
scripts:
default:
script: /root/bin/default.sh
params: p1 p2 p3
timeout: 30
retries: 10
delay: 3
log: /tmp/ansible_script.log
Given the scripts at the controller
shell> tree files
files
├── default.sh
├── script_A.sh
├── script_B.sh
└── script_C.sh
shell> cat files/default.sh
#!/bin/sh
echo $1 $2 $3
echo finished > /tmp/ansible_script.log
exit 0
The playbook below
shell> cat pb.yml
- hosts: all
vars:
my_script: "{{ scripts[inventory_hostname]|d(scripts['default']) }}"
_script: "{{ my_script.script|d(scripts.default.script) }}"
_params: "{{ my_script.params|d(scripts.default.params) }}"
_timeout: "{{ my_script.timeout|d(scripts.default.timeout) }}"
_retries: "{{ my_script.retries|d(scripts.default.retries) }}"
_delay: "{{ my_script.delay|d(scripts.default.delay) }}"
_log: "{{ my_script.log|d(scripts.default.log) }}"
tasks:
- debug:
msg: |-
_script: {{ _script }}
_params: {{ _params }}
_timeout: {{ _timeout }}
_retries: {{ _retries }}
_delay: {{ _delay }}
_log: {{ _log }}
when: debug|d(false)|bool
- name: Copy script
block:
- file:
state: directory
path: "{{ _script|dirname }}"
mode: 0750
- copy:
src: "{{ _script|basename }}"
dest: "{{ _script }}"
mode: 0550
when: copy_script|d(false)|bool
- name: Run script
block:
- command:
cmd: "{{ _script }} {{ _params }}"
async: "{{ _timeout }}"
poll: 0
register: cmd_async
- debug:
var: cmd_async.ansible_job_id
when: debug|d(false)|bool
- name: Read log until finished
block:
- command:
cmd: "cat {{ _log }}"
register: cmd_log
until: cmd_log.stdout == 'finished'
retries: "{{ _retries }}"
delay: "{{ _delay }}"
- debug:
var: cmd_log.stdout
when: debug|d(false)|bool
when: read_log_fin|d(false)|bool
- name: Check async script
block:
- async_status:
jid: "{{ cmd_async.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: "{{ _retries }}"
delay: "{{ _delay }}"
- debug:
msg: >-
{{ job_result.start }}
{{ job_result.end }}
rc: {{ job_result.rc}}
when: debug|d(false)|bool
gives
shell> ansible-playbook pb.yml -e debug=true -e copy_script=true -e read_log_fin=true
PLAY [all] ***********************************************************************************
TASK [debug] *********************************************************************************
ok: [test_11] =>
msg: |-
_script: /root/bin/default.sh
_params: p1 p2 p3
_timeout: 30
_retries: 10
_delay: 3
_log: /tmp/ansible_script.log
ok: [test_12] =>
msg: |-
_script: /root/bin/default.sh
_params: p1 p2 p3
_timeout: 30
_retries: 10
_delay: 3
_log: /tmp/ansible_script.log
ok: [test_13] =>
msg: |-
_script: /root/bin/default.sh
_params: p1 p2 p3
_timeout: 30
_retries: 10
_delay: 3
_log: /tmp/ansible_script.log
TASK [file] **********************************************************************************
ok: [test_13]
ok: [test_12]
ok: [test_11]
TASK [copy] **********************************************************************************
ok: [test_12]
ok: [test_11]
ok: [test_13]
TASK [command] *******************************************************************************
changed: [test_12]
changed: [test_11]
changed: [test_13]
TASK [debug] *********************************************************************************
ok: [test_11] =>
cmd_async.ansible_job_id: '754707567219.90860'
ok: [test_12] =>
cmd_async.ansible_job_id: '148176661548.90862'
ok: [test_13] =>
cmd_async.ansible_job_id: '688240445475.90861'
TASK [command] *******************************************************************************
changed: [test_13]
changed: [test_11]
changed: [test_12]
TASK [debug] *********************************************************************************
ok: [test_11] =>
cmd_log.stdout: finished
ok: [test_12] =>
cmd_log.stdout: finished
ok: [test_13] =>
cmd_log.stdout: finished
TASK [async_status] **************************************************************************
changed: [test_12]
changed: [test_13]
changed: [test_11]
TASK [debug] *********************************************************************************
ok: [test_11] =>
msg: '2022-08-01 16:02:50.287027 2022-08-01 16:02:50.320177 rc: 0'
ok: [test_12] =>
msg: '2022-08-01 16:02:49.770331 2022-08-01 16:02:49.801347 rc: 0'
ok: [test_13] =>
msg: '2022-08-01 16:02:50.189800 2022-08-01 16:02:50.343773 rc: 0'
PLAY RECAP ***********************************************************************************
test_11: ok=9 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_12: ok=9 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_13: ok=9 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- It's not possible to display the intermediate log during the iteration. The callback plugin displays all results together after the iteration. You have to go outside Ansible if you want to observe the intermediate log. For example, fetch the log files
- name: Fetch log until finished
fetch:
dest: /tmp/ansible/
src: "{{ _log }}"
until: lookup('file', my_logfile) == 'finished'
retries: "{{ _retries }}"
delay: "{{ _delay }}"
vars:
my_logfile: "/tmp/ansible/{{ inventory_hostname}}/tmp/ansible_script.log"
when: fetch_log_fin|d(false)|bool
This creates the periodically updated files at the controller
shell> tree /tmp/ansible/
/tmp/ansible/
├── test_11
│ └── tmp
│ └── ansible_script.log
├── test_12
│ └── tmp
│ └── ansible_script.log
└── test_13
└── tmp
└── ansible_script.log
Display the files at the controller. For example, use watch
shell> watch cat /tmp/ansible/test_11/tmp/ansible_script.log
To test it, the script below writes $1 times to the log in $2 interval
shell> cat files/script_A.sh
#!/bin/sh
for i in $(seq 1 $1); do
echo step $i > /tmp/ansible_script.log
sleep $2
done
echo finished > /tmp/ansible_script.log
exit 0
Update the dictionary and let the host test_11 run the script
shell> cat group_vars/all/scripts.yml
scripts:
default:
script: /root/bin/default.sh
params: p1 p2 p3
timeout: 30
retries: 10
delay: 3
log: /tmp/ansible_script.log
test_11:
script: /root/bin/script_A.sh
params: 7 3
The playbook gives abridged. (Delete the fetched files before you run the playbook again. Otherwise, the task will be skipped on the last files.)
shell> ansible-playbook pb.yml -e debug=true -e fetch_log_fin=true
...
TASK [Fetch log until finished] **************************************************************
ok: [test_12]
FAILED - RETRYING: [test_11]: Fetch log until finished (10 retries left).
ok: [test_13]
FAILED - RETRYING: [test_11]: Fetch log until finished (9 retries left).
FAILED - RETRYING: [test_11]: Fetch log until finished (8 retries left).
FAILED - RETRYING: [test_11]: Fetch log until finished (7 retries left).
FAILED - RETRYING: [test_11]: Fetch log until finished (6 retries left).
changed: [test_11]
TASK [async_status] **************************************************************************
changed: [test_13]
changed: [test_12]
changed: [test_11]
TASK [debug] *********************************************************************************
ok: [test_11] =>
msg: '2022-08-01 18:00:13.304133 2022-08-01 18:00:34.768385 rc: 0'
ok: [test_12] =>
msg: '2022-08-01 18:00:13.413492 2022-08-01 18:00:13.480142 rc: 0'
ok: [test_13] =>
msg: '2022-08-01 18:00:13.537767 2022-08-01 18:00:13.731926 rc: 0'
PLAY RECAP ***********************************************************************************
test_11: ok=6 changed=3 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
test_12: ok=6 changed=2 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
test_13: ok=6 changed=2 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
The output will be approximately the same if you read the log
shell> ansible-playbook pb.yml -e debug=true -e read_log_fin=true
...
TASK [Read log until finished] ***************************************************************
FAILED - RETRYING: [test_11]: Read log until finished (10 retries left).
changed: [test_12]
changed: [test_13]
FAILED - RETRYING: [test_11]: Read log until finished (9 retries left).
FAILED - RETRYING: [test_11]: Read log until finished (8 retries left).
FAILED - RETRYING: [test_11]: Read log until finished (7 retries left).
FAILED - RETRYING: [test_11]: Read log until finished (6 retries left).
changed: [test_11]
TASK [debug] *********************************************************************************
ok: [test_11] =>
cmd_log.stdout: finished
ok: [test_12] =>
cmd_log.stdout: finished
ok: [test_13] =>
cmd_log.stdout: finished
Link to complete playbook pb.yml