Reputation: 353
I'm currently using a conditional "when" statement to call roles from my playbook.
My playbook:
---
- hosts: all
connection: local
gather_facts: no
tasks:
roles:
- role: my_role_one
when: deviceType == "roleOneDevice"
- role: my_role_two
when: deviceType == "roleTwoDevice"
Each role has the same tasks associated with it.
Role 1:
$ tree my_role_one/
my_role_one/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ ├── install_certs.yml
│ ├── main.yml
│ ├── renew_certs.yml
│ └── revoke_certs.yml
├── templates
└── vars
└── main.yml
Role 2:
tree my_role_two/
my_role_two/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ ├── install_certs.yml
│ ├── main.yml
│ ├── renew_certs.yml
│ └── revoke_certs.yml
├── templates
└── vars
└── main.yml
This is main.yml
from the my_role_one
role:
---
# main tasks to execute
- name: Renew SSL Certs
import_tasks: renew_certs.yml
tags:
- renew
when: deviceType == "roleOneDevice"
- name: Revoke SSL Certs
import_tasks: revoke_certs.yml
tags:
- revoke
when: deviceType == "roleOneDevice"
- name: Install SSL Certs
import_tasks: install_certs.yml
tags:
- install
when: deviceType == "roleOneDevice"
When I run the playbook I pass in an inline variable deviceType
which the when
conditional acts upon. However, when the playbook runs I see the log output of both roles. I only want the output of the tasks associated with the appropriate role to print to the screen.
Current output:
ansible-playbook lemur-staging-ssl-certs.yml -i hosts --limit "lab-hub[0]" -e deviceType=roleOneDevice -t "renew"
PLAY [all]
TASK [my_role_one : fail]
skipping: [device_one.mgt.net]
TASK [my_role_one : Delete newDevices.txt file.]
changed: [device_one.mgt.net]
TASK [my_role_one : Log in to Lemur Stage Env.]
ok: [device_one.mgt.net -> 127.0.0.1]
TASK [my_role_one : Getting current certificate data.]
ok: [device_one.mgt.net -> 127.0.0.1]
TASK [my_role_one : Set currentCertSN and currentCertID vars.]
ok: [device_one.mgt.net]
TASK [my_role_one : Writing devices with no certs to newDevices.txt.]
changed: [device_one.mgt.net]
TASK [my_role_one : Set newDevices var.]
ok: [device_one.mgt.net]
TASK [my_role_one : Creating new certificates.]
skipping: [device_one.mgt.net] => (item=device_one.mgt.net)
TASK [my_role_one : Set newCertData var for newly created cert (CER, ID, SN).] skipping: [device_one.mgt.net]
TASK [my_role_one : Reissuing certificates.]
skipping: [device_one.mgt.net]
TASK [my_role_one : Set newCertData var with reissued cert data (CER, ID, SN).]
skipping: [device_one.mgt.net]
TASK [my_role_one : Revoking old certificates.]
skipping: [device_one.mgt.net]
TASK [my_role_two : fail]
skipping: [device_one.mgt.net]
TASK [my_role_two : Delete newDevices.txt file.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Log in to Lemur Stage Env.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Getting current certificate data.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Set currentCertSN and currentCertID vars.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Writing devices with no certs to newDevices.txt.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Set newDevices var.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Creating new certificates.]
skipping: [device_one.mgt.net] => (item=device_one.mgt.net)
TASK [my_role_two : Set newCertData var for newly created cert (CER, ID, SN).] skipping: [device_one.mgt.net]
TASK [my_role_two : Reissuing certificates.]
skipping: [device_one.mgt.net]
TASK [my_role_two : Set newCertData var with reissued cert data (CER, ID, SN).]
skipping: [device_one.mgt.net]
TASK [my_role_two : Revoking old certificates.]
skipping: [device_one.mgt.net]
PLAY RECAP device_one.mgt.net : ok=6 changed=2 unreachable=0 failed=0 skipped=18 rescued=0 ignored=0
You can see I passed "roleOneDevice" as the deviceType
so I'm expecting to see log output for only my_role_one
but in the output, you see logs from the my_role_two
role.
Upvotes: 0
Views: 82
Reputation: 1524
You have different options for complexity, but basically I would use the include_role
module.
With both variants you can remove the conditions when: deviceType == "roleOneDevice"
inside your roles.
Instead of two roles you define two tasks with the include_role
module.
---
- hosts: all
connection: local
gather_facts: no
tasks:
- name: Run role my_role_one
include_role:
name: my_role_one
when: deviceType == "roleOneDevice"
- name: Run role my_role_two
include_role:
name: my_role_two
when: deviceType == "roleTwoDevice"
For the not executed task of the include_role
you will see a single skipped, but not for every single task of the role.
TASK [Run role my_role_two] ********************************************************************************************
skipping: [localhost]
You can define a variable depending on your device type, with the name of the role to be executed (run_role
). Then you define only one task that includes the role with the name defined in the run_role
variable. To be on the safe side there is a condition that the variable run_role
is really defined.
---
- hosts: all
connection: local
gather_facts: no
vars:
role_for_device:
"roleOneDevice": my_role_one
"roleTwoDevice": my_role_two
pre_tasks:
- name: Set run_role.
set_fact:
run_role: "{{ role_for_device[deviceType] }}"
when: deviceType in role_for_device
tasks:
- name: Run device specific role
include_role:
name: "{{ run_role }}"
when: run_role is defined
With this variant you don't see a skipped task anymore, because no task exists that needs to be skipped. Only if deviceType
contains a value for which no key exists in the variable role_for_device
, the two tasks are displayed as skipped.
The task Set run_role. does not necessarily have to be defined as pre_task
, this can also be at tasks
. Only the order must be correct, first set_fact
, then include_role
.
Upvotes: 3