# Determining distribution specific facts/paths/etc

**URL:** <https://forum.ansible.com/t/determining-distribution-specific-facts-paths-etc/35997>\
**Category:** Ansible Project\
**Created:** [November 15, 2021, 4:43pm UTC](https://forum.ansible.com/t/determining-distribution-specific-facts-paths-etc/35997 "2021-11-15T16:43:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![opoplawski](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/opoplawski/32/2112_2.png) [@opoplawski](https://forum.ansible.com/u/opoplawski)\
**Post date:** [November 15, 2021, 4:43pm UTC](https://forum.ansible.com/t/determining-distribution-specific-facts-paths-etc/35997/1 "2021-11-15T16:43:36Z")

</div>

I’ve found myself writing a lot of tasks like:

- name: “RedHat: Set facts”  
set\_fact: path\_lib\_security=“/usr/lib64/security”  
when: ansible\_os\_family == ‘RedHat’ or ansible\_os\_family == ‘SHMZ’

- name: “Debian: Set facts”  
set\_fact: path\_lib\_security=“/lib/x86\_64-linux-gnu/security”  
when: ansible\_os\_family == ‘Debian’

- name: “EL8+: Set facts”  
set\_fact: pam\_kwallet=“pam\_kwallet5.so”  
when: ansible\_distribution\_major\_version|int \>= 8

- name: “Not EL8+: Set facts”  
set\_fact: pam\_kwallet=“pam\_kwallet.so”  
when: ansible\_distribution\_major\_version|int \< 8  
tags: always

- name: “Check if pam\_kwallet is installed”  
stat:  
path: “{{ path\_lib\_security }}/{{ pam\_kwallet }}”  
register: kwallet

Lately, I’ve started to think that this would be better served by a lookup plugin, e.g. (this is very crude and a different set of facts):

# python 3 headers, required if submitting to Ansible

from **future** import (absolute\_import, division, print\_function)  
**metaclass** = type

DOCUMENTATION = “”"  
lookup: distro\_facts  
author: Orion Poplawski \<[orion@nwra.com](mailto:orion@nwra.com)  
version\_added: “0.1”  
short\_description: Lookup distribution dependent facts  
description:

- Return distribution dependent facts  
options:  
\_terms:  
description: Fact name  
required: True  
notes:
- Need to have run setup  
“”"  
from ansible.errors import AnsibleError, AnsibleParserError  
from ansible.module\_utils.\_text import to\_native, to\_text  
from ansible.plugins.lookup import LookupBase  
from ansible.utils.display import Display

display = Display()

FACTS = {  
‘polkit\_user’: {  
‘RedHat’: ‘polkitd’,  
‘Debian’: ‘root’,  
},  
‘polkit\_rules\_dir’: {  
‘RedHat’: ‘/etc/polkit-1/rules.d’,  
‘Debian’: ‘/etc/polkit-1/localauthority/20-org.d’,  
},  
}

class LookupModule(LookupBase):

def run(self, terms, variables=None, \*\*kwargs):

# lookups in general are expected to both take a list as input and output a list

# this is done so they work with the looping construct ‘with\_’.

ret =   
for term in terms:

ret.append(FACTS[term][variables[‘ansible\_facts’][‘os\_family’]])

return ret

and thus:

- name: “Configure polkit admins”  
copy:  
src: 05-libvirt-admin.rules  
dest: “{{ lookup(‘distro\_facts’, ‘polkit\_rules\_dir’) }}/”  
owner: “{{ lookup(‘distro\_facts’, ‘polkit\_user’) }}”  
mode: 0600

I’m curious to get other people’s perspective on this. Perhaps there are already implementations of this out there? Would anyone like to collaborate on this? Is there a community collection where this should live? Other better approaches?

Thanks,  
Orion

---

<div class="post-metadata">

**Author:** ![racke](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/racke/32/4767_2.png) [@racke](https://forum.ansible.com/u/racke)\
**Post date:** [November 15, 2021, 6:03pm UTC](https://forum.ansible.com/t/determining-distribution-specific-facts-paths-etc/35997/2 "2021-11-15T18:03:52Z")

</div>

> I've found myself writing a lot of tasks like:
> 
> - name:"RedHat: Set facts"  
> set\_fact:path\_lib\_security="/usr/lib64/security"  
> when:ansible\_os\_family == 'RedHat'or ansible\_os\_family == 'SHMZ'
> 
> - name:"Debian: Set facts"  
> set\_fact:path\_lib\_security="/lib/x86\_64-linux-gnu/security"  
> when:ansible\_os\_family == 'Debian'
> 
> - name:"EL8+: Set facts"  
> set\_fact:pam\_kwallet="pam\_kwallet5.so"  
> when:ansible\_distribution\_major\_version|int \>= 8
> 
> - name:"Not EL8+: Set facts"  
> set\_fact:pam\_kwallet="pam\_kwallet.so"  
> when:ansible\_distribution\_major\_version|int \< 8  
> tags:always
> 
> - name:"Check if pam\_kwallet is installed"  
> stat:  
> path:"{{ path\_lib\_security }}/{{ pam\_kwallet }}"  
> register:kwallet
> 
> Lately, I've started to think that this would be better served by a lookup plugin, e.g. (this is very crude and a different set of facts):

I don't think the lookup plugin makes it any easier or user friendly. The common approach is to put the OS dependent variables in separate files and use

include\_vars, for example:

- name: Include variables depending on OS details  
include\_vars: "{{ item }}"  
with\_first\_found:  
- files:  
- "{{ ansible\_distribution }}-{{ ansible\_distribution\_major\_version }}.yml"  
- "{{ ansible\_distribution }}.yml"  
- "{{ ansible\_os\_family }}.yml"  
- "defaults.yml"

The disadvantage of this approach that you need to repeat the values from Debian.yml in Debian-11.yml.

Regards

```
          Racke

```

---

<div class="post-metadata">

**Author:** ![opoplawski](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/opoplawski/32/2112_2.png) [@opoplawski](https://forum.ansible.com/u/opoplawski)\
**Post date:** [November 15, 2021, 6:06pm UTC](https://forum.ansible.com/t/determining-distribution-specific-facts-paths-etc/35997/3 "2021-11-15T18:06:01Z")

</div>

yeah, I do that as well. But I don't like having to repeat that in multiple  
roles.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [November 16, 2021, 4:05am UTC](https://forum.ansible.com/t/determining-distribution-specific-facts-paths-etc/35997/4 "2021-11-16T04:05:57Z")

</div>

Lookup filters run on the Ansible controller, not the remote host.

Splitting the data across multiple files doesn’t improve readability either.

This is somewhat easier to read. At least you don’t have to discern if or how multiple tasks are related, because this is only one task.
