There are probably better ways to do this, and I look forward to seeing them, but what I'm currently doing looks a lot like this. Taken from a custom fail2ban role I'm using:
The vars look like this. I have vars files for each {{ansible_os_family}}
and then overrides for any {{ansible_distribution}}_{{ansible_distribution_major_version}}
that might need them.
$ ls -l
lrwxrwxrwx. 1 error error 24 May 7 07:51 fail2ban_os_CentOS_6.yml -> fail2ban_os_RedHat_6.yml
lrwxrwxrwx. 1 error error 22 May 7 07:51 fail2ban_os_CentOS.yml -> fail2ban_os_RedHat.yml
-rw-rw-r--. 1 error error 64 May 7 07:51 fail2ban_os_Debian.yml
-rw-rw-r--. 1 error error 64 May 7 07:51 fail2ban_os_Fedora.yml
-rw-rw-r--. 1 error error 62 May 7 07:51 fail2ban_os_RedHat_6.yml
-rw-rw-r--. 1 error error 64 May 7 07:51 fail2ban_os_RedHat.yml
-rw-rw-r--. 1 error error 62 May 7 07:51 fail2ban_os_Ubuntu_14.yml
-rw-rw-r--. 1 error error 65 May 7 07:51 fail2ban_os_Ubuntu.yml
$ cat fail2ban_os_Ubuntu.yml
fail2ban_backend: systemd
fail2ban_banaction: iptables-multiport
$ cat fail2ban_os_Fedora.yml
fail2ban_backend: systemd
fail2ban_banaction: firewallcmd-ipset
To load these files, roles/fail2ban/tasks/main.yml
starts out like this:
---
- include_vars: fail2ban_os_{{ansible_os_family}}.yml
ignore_errors: True
- include_vars: fail2ban_os_{{ansible_distribution}}_{{ansible_distribution_major_version}}.yml
ignore_errors: True
Which means the variable files need not exist. Of course, if the variables needed are not defined somewhere, the later tasks will fail, and then you can go define whatever you missed.
To keep things consistent and maintainable, the general OS family vars files contain vars representing the most recent supported distros, and overrides for specific distro versions are for older distros.