I am starting with ansible and will use it, among others, to install packages on several Linux distros.
I see in the docs that the yum
and apt
commands are separated - what would be the easiest way to unify them and use something like this:
- name: install the latest version of Apache
unified_install: name=httpd state=latest
instead of
- name: install the latest version of Apache on CentOS
yum: name=httpd state=latest
when: ansible_os_family == "RedHat"
- name: install the latest version of Apache on Debian
apt: pkg=httpd state=latest
when: ansible_os_family == "Debian"
I understand that the two package managers are different, but they still have a set of common basic usages. Other orchestators (salt for instance) have a single install command.
Update: As of Ansible 2.0, there is now a generic & abstracted
package
moduleUsage Examples:
Now when the package name is the same across different OS families, it's as simple as:
When the package name differs across OS families, you can handle it with distribution or OS family specific vars files:
Then, for each OS that you must handle differently... create a vars file:
EDIT:
Since Michael DeHaan (creator of Ansible) has chosen not to abstract out the package manager modules like Chef does,If you are still using an older version of Ansible (Ansible < 2.0), unfortunately you'll need to handle doing this in all of your playbooks and roles. IMHO this pushes a lot of unnecessary repetitive work onto playbook & role authors... but it's the way it currently is. Note that I'm not saying we should try to abstract package managers away while still trying to support all of their specific options and commands, but just have an easy way to install a package that is package manager agnostic. I'm also not saying that we should all jump on the Smart Package Manager bandwagon, but that some sort of package installation abstraction layer in your configuration management tool is very useful to simplify cross-platform playbooks/cookbooks. The Smart project looks interesting, but it is quite ambitious to unify package management across distros and platforms without much adoption yet... it'll be interesting to see whether it is successful. The real issue is just that package names sometimes tend to be different across distros, so we still have to do case statements or
when:
statements to handle the differences.The way I've been dealing with it is to follow this
tasks
directory structure in a playbook or role:And then have this in my
main.yml
:This in
foo.yml
(for package 'foo'):Then for the different package managers:
Apt:
Yum:
Homebrew:
Note that this is awfully repetitive and not D.R.Y., and although some things might be different on the different platforms and will have to be handled, generally I think this is verbose and unwieldy when compared to Chef's:
And yes, there is the argument that some package names are different across distros. And although there is currently a lack of easily accessible data, I'd venture to guess that most popular package names are common across distros and could be installed via an abstracted package manager module. Special cases would need to be handled anyway, and would already require extra work making things less D.R.Y. If in doubt, check pkgs.org.
You can abstract out package managers via facts
All you need is some logic that sets
ansible_pkg_mgr
toapt
oryum
etc.Ansible are also working on doing what you want in a future module.
From Ansible 2.0 there is the new
Package
-modul.http://docs.ansible.com/ansible/package_module.html
You can then use it like your proposal:
You still have to consider name differences.
Check out Ansible's documentation on Conditional Imports.
One task to ensure that apache is running even if the service names is different across each OS.
You do not want to do that because certain package names differ between distros. For example on RHEL-related distros the popular web server package is named
httpd
, where as on Debian-related distros it's namedapache2
. Similarly with a huge list of other system and supporting libraries.There might be a set of common basic parameters, but then there's also a number of more advanced parameters that are different between package managers. And you don't want to be in an ambiguous situation where for some commands you use one syntax and for other commands you use another syntax.
The answers above all seem to link to broken pages. This looks like the correct URL: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html