I would like to loop on a set of tasks which are executed on different hosts.
For example:
- action 1 on host A
- action 2 on host B
- action 3 on host C
repeated for each element of my variable TestName
I would like to loop on a set of tasks which are executed on different hosts.
For example:
Please, tell us more about TestName
. Is it:
It can be difficult to see how many ways other people might interpret a statement made when you’re thinking of a particular scenario. In this case there are too many nuances left out, and community.general.read_my_mind
is still not even on the roadmap.
A more complete description (or better, actual example(s)) of TestName
would get you better responses.
… and those strings are names of actions? or hosts?
These strings are labels which are used by action1/action2/action3 as functional parameters.
Can you please show examples?
Can you show us what you’ve tried that hasn’t worked?
It’s really hard to give specific answers to vaguely general problem descriptions, and bringing in even more general terms doesn’t add clarity. Ansible supports action plugins: somehow I don’t think that’s what you mean by “actions”. Ansible doesn’t support functional programming (except in a few accidental cases via Jinja2), and I don’t think that’s what you mean by “functional parameters” either.
Sorry to sound impatient in a public forum. We really do want to help you solve your problem, but you’ve got to help us help you.
Hi @utoddl ,
My variable is defined in group_vars/all as below:
test_format:
- svsGlissando_10000
- svsGlissando_20000
- svsGlissando_30000
- svsGlissando_40000
I currently have a central playbook wich imports another playbook multiple times with different values of test_name
.
- import_playbook: ../common/launch_test_retrieve_logs.yml
vars:
var_file: "{{ var_file }}"
test_name: "svsGlissando_10000"
when: test_name in test_format
- import_playbook: ../common/launch_test_retrieve_logs.yml
vars:
var_file: "{{ var_file }}"
test_name: "svsGlissando_20000"
when: test_name in test_format
- import_playbook: ../common/launch_test_retrieve_logs.yml
vars:
var_file: "{{ var_file }}"
test_name: "svsGlissando_30000"
when: test_name in test_format
I have this same block hundrerds of time in my main playbook which I would like to avoid
Playbook launch_test_retrieve_logs.yml
also uses import_playbook but on different playbooks which are executed on different hosts
- import_playbook: launch_test.yml
- import_playbook: retrieve_apache_logs.yml
when: webserver == 'apache'
- import_playbook: restart_jmeter_worker.yml
launch_test.yml
has for hosts jmeter-controller
and launch jmeter based on configuration files which use test_name
retrieve_apache_logs.yml
has for hosts web-apache
retrieves logs files and store them in a path which use test_name
restart_jmeter_worker.yml
has for hosts jmeter-workers
This behavior is working fine but is not very elegant as for each new value of test_format I add in the variable I also must create a new block in my main playbook.
Now you’re talkin’! This is beautiful.
Well, as a request for help, it’s beautiful compared to your first attempt. I wouldn’t have guessed this structure in a million years based on the initial description.
As an example of “How To Ansible”, it’s not so beautiful. The big problem — and understand, I’ve only been looking at this for a little while so I could be missing some subtleties — everything seems to be “up a level” above where it ought to be. I’m guessing that your playbooks should probably be roles, and your roles (if you have any) should probably be task files within those roles. Because what you want to do is something like this:
# N.B. This won't work!
- import_playbook: ../common/launch_test_retrieve_logs.yml
vars:
var_file: "{{ var_file }}"
loop: '{{ test_format }}'
loop_control:
loop_var: test_name
But that won’t work, because you can’t loop over “PlaybookInclude” – an internal name apparently for what import_playbook
is/does. At least, that’s in the error message. I tried it anyway.
Rather, what might accomplish your goal is more like:
---
# tests-playbook.yml
- name: Tests playbook
hosts: localhost
gather_facts: false
vars:
test_format:
- svsGlissando_10000
- svsGlissando_20000
- svsGlissando_30000
- svsGlissando_40000
- svsTremolo_10000
- svsTremolo_20000
tasks:
- name: Include the glissando test roles
ansible.builtin.include_role:
name: glissando_tests
tasks_from: main.yml
loop: '{{ test_format }}'
when: test_name is search("Glissando")
loop_control:
loop_var: test_name
- name: Include the tremolo test roles
ansible.builtin.include_role:
name: tremolo_tests
tasks_from: main.yml
loop: '{{ test_format }}'
when: test_name is search("Tremolo")
loop_control:
loop_var: test_name
You’ve got more going on than this example solves, but I’m pretty sure your playbooks should be roles. Restructuring everything is not going to be trivial, but I expect it will be worth it. You’re basically shifting from a code-driven flow to a data-driven flow. That’s not trivial, but it is possible with roles; with playbooks – not so much.
Feel free to follow-up with additional questions, which I’m sure will pop up as you dig into the details.
Picking up on the “Glissando” part and totally overlooking the whole medical imaging, .svs
thing, I naively extended your test_format
list in a musical direction. It was only an example anyway, but I feel kind of silly.