This is, as far as I can tell, one of the messier parts of Ansible. I've always thought that it should have a way to figure out what package manager is in use on its own, without requiring me to specify it.
In the meantime, I have lots of roles with tasks looking like this:
- name: Update OpenSSH on CentOS
yum: name=openssh state=latest enablerepo=cr
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int == 7
notify: restart sshd
- name: Update OpenSSH on RHEL
yum: name=openssh state=latest
when: ansible_distribution == 'RedHat' and ansible_distribution_major_version|int == 7
notify: restart sshd
- name: Update OpenSSH on Fedora
yum: name=openssh state=latest
when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int <= 21
notify: restart sshd
- name: Update OpenSSH on Fedora
dnf: name=openssh state=latest
when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int >= 22
notify: restart sshd
- name: Update OpenSSH on Debian/Ubuntu
apt: name=openssh-server state=latest
when: ansible_os_family == 'Debian'
notify: restart ssh
This gets a little unwieldy. However, it does have its advantages. If you inspect this carefully you'll notice that the CentOS version is different; it enables a repository while installing the package.
Of course there's a reason for doing it this way. On different systems you might even have different package names, so you may end up having to have different tasks for them anyway. But that's something you can shove in an OS-specific variable and then do something like:
- include_vars: common_os_{{ansible_distribution}}_{{ansible_distribution_major_version}}.yml
- name: Install minimum system administration packages
yum: name={{item}} state=present
with_items: common_packages_admin
when: ansible_os_family == 'RedHat'
- name: Install minimum system administration packages
apt: name={{item}} state=present
with_items: common_packages_admin
when: ansible_os_family == 'Debian'
But to extend this for dnf
will require a bunch of extra when:
logic, which is a lot of work for absolutely zero gain, since dnf's yum compatibility will take care of it. Here is a place where that hypothetical "automatically figure out what package manager to use" module would be useful.
But even if you had one, you'll still sometimes need to use individual package managers, because some of them have ... idiosyncrasies.
- name: Install salt-minion
yum: name=salt-minion state=latest
when: ansible_os_family == 'RedHat'
- name: Install salt-minion
apt: name=salt-minion state=latest update_cache=yes
when: ansible_os_family == 'Debian'
So, the best advice I can give you is: Wait until Ansible has a better way of dealing with package managers. Or write one...