I have the following roles
structure:
$ tree roles
roles
├── user
│ └── tasks
│ └── main.yaml
└── validation
└── tasks
└── main.yaml
My goal is to include the validation
role into multiple roles and avoid using a when
condition, into every task.
validation/tasks/main.yaml
---
- name: Test model
ansible.builtin.command: grep 'Debian' /proc/device-tree/model
changed_when: false
register: model
- name: Set fact
ansible.builtin.set_fact:
debian: true
when: model.rc == 0
user/tasks/main.yaml
---
- name: Perform validation
ansible.builtin.include_role:
name: validation
- name: Get user info
ansible.builtin.user:
name: user
state: present
register: user_info
when: debian | default(false)
playbook.yaml
---
- name: Deployment
hosts: cluster
become: true
gather_facts: true
roles:
- role: user
When I run the playbook, everything works as expected. My goal is to avoid adding inside each task that when
condition.
Is there a way to create a handler which will perform automatically a validation for each role task? The above example is very limited, the actual playbook contains many roles, with each task being required to be validated.
My end-result should be:
roles:
- role: user
- role: os
- role: reset
...
Where each role task would automatically perform a validation during execution. Thank you for your help.
You may try using when condition in role modifying playbook.yaml like this using any variable you may need in when condition:
---
- name: Deployment
hosts: cluster
become: true
gather_facts: true
roles:
- role: user
when: ansible_os_family == "Debian"
For more information check ansible documentation here: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html#conditionals-with-roles
Also if you need this, in playbook.yaml you may set any variables needed for a role to run.
The validation is not needed. Use Ansible variable ansible_os_family instead. See gather_facts . For example,
- hosts: localhost
gather_facts: true
tasks:
- debug:
var: ansible_os_family
gives
ansible_os_family: Debian
You want to perform a role for multiple operating systems (or families of OS). In this case, you have to decide where to place the conditions.
a) If you want to use the role
keyword you have to place the conditions inside the roles because the facts will be gathered after the roles are loaded. In other words, the variable ansible_os_family won't be available before a role is loaded.
roles:
- role: user
- role: os
- role: reset
For example, create role user
shell> tree roles/
roles/
└── user
└── tasks
├── Debian.yml
├── FreeBSD.yml
└── main.yml
shell> cat roles/user/tasks/main.yml
- include_tasks: "{{ ansible_os_family }}.yml"
shell> cat roles/user/tasks/Debian.yml
- debug:
msg: Manage users for Debian
shell> cat roles/user/tasks/FreeBSD.yml
- debug:
msg: Manage users for FreeBSD
Then, the playbook
- hosts: localhost,test_11
gather_facts: true
roles:
- user
gives
PLAY [localhost,test_11] ************************************************************************************************************* TASK [Gathering Facts] *************************************************************************************************************** ok: [localhost] ok: [test_11] TASK [user: include_tasks] ********************************************************************************************************** included: /export/scratch/tmp7/test-178/roles/user/tasks/Debian.yml for localhost included: /export/scratch/tmp7/test-178/roles/user/tasks/FreeBSD.yml for test_11 TASK [user: debug] ****************************************************************************************************************** ok: [localhost] => msg: Manage users for Debian TASK [user: debug] ****************************************************************************************************************** ok: [test_11] => msg: Manage users for FreeBSD PLAY RECAP *************************************************************************************************************************** localhost: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 test_11: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
b) If you want to use the module include_role
the situation is more flexible. For example, you can create roles for particular OS families
shell> tree roles/
roles/
├── user_Debian
│ └── tasks
│ └── main.yml
├── user_default
│ └── tasks
│ └── main.yml
├── user_FreeBSD
│ └── tasks
│ └── main.yml
└── user_RedHat
└── tasks
└── main.yml
shell> cat roles/user_Debian/tasks/main.yml
- debug:
msg: "Manage users for {{ ansible_os_family }}"
Declare the variables, for example in group_vars/all
shell> cat group_vars/all/role_user_family.yml
roles_user_family:
Debian: user_Debian
FreeBSD: user_FreeBSD
RedHat: user_RedHat
default: user_default
role_user_family: "{{ roles_user_family[ansible_os_family]|
default(roles_user_family.default) }}"
Then, the playbook
- hosts: localhost,test_11
gather_facts: true
tasks:
- include_role:
name: "{{ role_user_family }}"
gives
PLAY [localhost,test_11] ********************************************************************* TASK [Gathering Facts] *********************************************************************** ok: [localhost] ok: [test_11] TASK [include_role: {{ role_user_family }}] ************************************************* TASK [user_Debian: debug] ******************************************************************* ok: [localhost] => msg: Manage users for Debian TASK [user_FreeBSD: debug] ****************************************************************** ok: [test_11] => msg: Manage users for FreeBSD PLAY RECAP *********************************************************************************** localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 test_11: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Notes:
See available platforms
See other distribution facts, for example
shell> ansible test_host -m setup | grep ansible_distr
"ansible_distribution": "Ubuntu",
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/os-release",
"ansible_distribution_file_variety": "Debian",
"ansible_distribution_major_version": "20",
"ansible_distribution_release": "focal",
"ansible_distribution_version": "20.04",
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.