I am trying to avoid duplicating complex tasks when they vary by only one parameter. The following is a real example:
- name: add executables
action: copy src={{item}} dest=/{{item}} mode=750 group=wheel
with_items:
- usr/sbin/snmpd-smartctl-connector
- usr/sbin/snmpd-mdraid-connector
- usr/sbin/update-mdraid-cache
- usr/sbin/update-smartctl-cache
notify: restart snmpd
when: ansible_os_family=='RedHat'
- name: add executables
action: copy src={{item}} dest=/{{item}} mode=750 group=snmp
with_items:
- usr/sbin/snmpd-smartctl-connector
- usr/sbin/snmpd-mdraid-connector
- usr/sbin/update-mdraid-cache
- usr/sbin/update-smartctl-cache
notify: restart snmpd
when: ansible_os_family=='Debian'
What I want to say is:
- when ansible_os_family=='Debian', set variable snmp_group=snmp
- when ansible_os_family=='RedHat', set variable snmp_group=wheel
- write the task once, with group={{snmp_group}}
It seems there is no good way of doing this in ansible. Options are:
1. Write the tasks multiple times with conditions, as shown above
2. Split into two separate but almost identical roles in separate files. Use groups to select the correct role. That was your suggestion. I think it makes maintaining the logic harder because it's duplicated in different parts of the filesystem, and it puts the onus on the role user to select the correct role.
3. Set up vars from the playbook: this means the role is split into two parts which you must remember to invoke correctly. It's because playbooks have a feature (vars_files) that roles don't.
- hosts: xxx
vars_files:
- roles/snmp/vars/{{ansible_os_family}}.yml
roles:
- snmp
4. Use inline jinja2 conditionals in vars/main.yml. This seems like the least bad option here.
[roles/snmp/vars/main.yml]
5. Maybe write a parameterised role, and have two other roles snmp_redhat and snmp_debian which call it via 'meta', passing the correct value for snmp_group? Obscure, and in any case the meta roles can only be executed before the roles within the main role.