I think I finally understood the question. I kept my original answer below which is still ok to skip a role
This is what I basically understand you want to do:
- determine a host you need to use based on a set of condition
- depending on the host that was chosen above, run a play or an other
- finally do some other tasks unconditionally
Here is a very basic yet fully functional example to achieve your requirement. I simplified it to a minimun set of tasks so it fits in a question. But you can add your roles back with the exact same concepts and inject your real tasks to select your targets.
The key in the playbook is to use the add_host
module to push the needed host in the needed group to the in-memory inventory. For this example, any host will used the local
connection so that it fakes a host but still uses localhost to run. Note that you could very well add several hosts in several groups.
I also added a basic check to make sure the value we pass for this fake host selection is inside a set of expected values. By default, the playbook uses host B
but your can change it by passing -e host_we_need=C
on the command line.
Enough talk: to the example ! To avoid some warnings, let's create a dummy inventory.yml
which contains the two groups we need but empty:
---
group_B:
group_C:
Then the playbook:
---
- name: Determine the hosts we need
hosts: localhost
gather_facts: false
tasks:
- name: dummy task to fake you choice
command: "echo {{ host_we_need | default('B') }}"
register: host_choice
- name: check condition to go on
vars:
allowed_hosts:
- B
- C
assert:
that:
- host_choice.stdout in allowed_hosts
fail_msg:
- "Found host value is: {{ host_choice.stdout }}"
- "It should be one of: {{ allowed_hosts | join(', ') }}"
- name: add the needed host to in-memory inventory
add_host:
name: "{{ host_choice.stdout }}"
groups:
- "group_{{ host_choice.stdout }}"
ansible_connection: local # This is for a fake host for test only.
- name: play tasks for group_B
hosts: group_B
gather_facts: false
tasks:
- debug:
msg: This a task for group_B
- name: play tasks for group_C
hosts: group_C
gather_facts: false
tasks:
- debug:
msg: This is a task for group_C
- name: whatever leftover tasks on localhost
hosts: localhost
gather_facts: false
tasks:
- debug:
msg: leftover localhost tasks
Gives (an example run for each situation)
$ ansible-playbook -i add inventory.yml playbook.yml
PLAY [Determine the hosts we need] **********************************
TASK [dummy task to fake you choice] ********************************
changed: [localhost]
TASK [check condition to go on] *************************************
ok: [localhost]
TASK [add the needed host to in-memory inventory] *******************
changed: [localhost]
PLAY [play tasks for group_B] ***************************************
TASK [debug] ********************************************************
ok: [B] => {
"msg": "This a task for group_B"
}
PLAY [play tasks for group_C] ***************************************
skipping: no hosts matched
PLAY [whatever leftover tasks on localhost] *************************
TASK [debug] ********************************************************
ok: [localhost] => {
"msg": "leftover localhost tasks"
}
PLAY RECAP **********************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook -i inventory.yml playbook.yml -e host_we_need=C
PLAY [Determine the hosts we need] **********************************
TASK [dummy task to fake you choice] ********************************
changed: [localhost]
TASK [check condition to go on] *************************************
ok: [localhost]
TASK [add the needed host to in-memory inventory] *******************
changed: [localhost]
PLAY [play tasks for group_B] ***************************************
skipping: no hosts matched
PLAY [play tasks for group_C] ***************************************
TASK [debug] ********************************************************
ok: [C] => {
"msg": "This is a task for group_C"
}
PLAY [whatever leftover tasks on localhost] *************************
TASK [debug] ********************************************************
ok: [localhost] => {
"msg": "leftover localhost tasks"
}
PLAY RECAP **********************************************************
C : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(original answer which does not exactly fulfill the requirement)
You can add the when
condition to your role.
- name: Play B
hosts: Host B
roles:
- role: my_b_role
when: my_condition | bool
The down side is that you need to add the condition to any role or task in your play.