# Installing packages on multiple Operating Systems

**URL:** <https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549>\
**Category:** Ansible Project\
**Tags:** ubuntu\
**Created:** [September 25, 2013, 12:21pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549 "2013-09-25T12:21:55Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Williams](https://avatars.discourse-cdn.com/v4/letter/a/da6949/32.png) [@Alex\_Williams](https://forum.ansible.com/u/Alex_Williams)\
**Post date:** [September 25, 2013, 12:21pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/1 "2013-09-25T12:21:55Z")

</div>

Hi,

I’m wondering if there’s a better way to install packages on multiple operating systems.

TL;DR: I’m looking for a method to abstract the OS differences to avoid duplicating files and templates all over the place.

Here’s what I’m currently doing:

> - name: Install OpenJDK  
> apt: pkg={{ item }} state=present

with\_items:

- openjdk-7-jdk

> tags:
> 
> - java  
> when: ansible\_distribution == ‘Ubuntu’

> - name: Install OpenJDK  
> yum: name=java-1.7.0-openjdk state=present  
> tags:
> - java  
> when: ansible\_distribution == ‘CentOS’

This works fine when you only have 1 task or 1 role, but I currently have 10 roles with multiple configurations, and each role has its own set of tasks, files, templates, etc.

I considered creating separate directories in each role, for each OS, but then handlers, templates and other files will need to be duplicated.

Is there a “package” module to replace “yum/apt” ? If not, can someone recommend a better approach? So far all the solutions I’ve found are only good as “examples”, but far from ideal in the real world.

Thanks

---

<div class="post-metadata">

**Author:** ![James\_Cammarata1](https://avatars.discourse-cdn.com/v4/letter/j/d26b3c/32.png) [@James\_Cammarata1](https://forum.ansible.com/u/James_Cammarata1)\
**Post date:** [September 25, 2013, 6:06pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/2 "2013-09-25T18:06:41Z")

</div>

I would recommend using the group\_by option, which can be used to group systems based on facts or other variables. So something like this:

- hosts: all  
tasks:

- name: group hosts by distribution  
group\_by: key=“{{ ansible\_distribution }}-{{ ansible\_distribution\_version }}”

- hosts: RedHat-6\*:CentOS-6\*:SL-6\*

tasks:

- name: Install OpenJDK  
yum: name=java-1.7.0-openjdk state=present  
tags:

- java

- hosts: Ubuntu-\*

tasks:

- name: Install OpenJDK  
apt: pkg=openjdk-7-jdk state=present

tags:

- java

---

<div class="post-metadata">

**Author:** ![Walid](https://avatars.discourse-cdn.com/v4/letter/w/ea5d25/32.png) [@Walid](https://forum.ansible.com/u/Walid)\
**Post date:** [September 25, 2013, 6:53pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/3 "2013-09-25T18:53:46Z")

</div>

Dear James,

This is very neat, related to this how do i use varaibles/facts for hosts, i tried the documentation example following in ansible, ansible-playbook but could not get it working

webservers:!{{excluded}}:&{{required}}

where should I define these variables, i tried to define them in the inventory hosts files, or pass them via the “-e” option both did not work for me.

regards

Walid

---

<div class="post-metadata">

**Author:** ![James\_Cammarata1](https://avatars.discourse-cdn.com/v4/letter/j/d26b3c/32.png) [@James\_Cammarata1](https://forum.ansible.com/u/James_Cammarata1)\
**Post date:** [September 25, 2013, 8:39pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/4 "2013-09-25T20:39:29Z")

</div>

Walid, this question came up the other day and I mentioned that it works correctly when setting the variable with -e. Could you post some samples of your inventory/playbook.

Also, if asking a new question it’s generally best to start a new thread, to avoid confusion and switching topics.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [September 25, 2013, 10:21pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/5 "2013-09-25T22:21:11Z")

</div>

you can use the {{ansible\_pkg\_manager}} variable to try to make it a single task, but then you have the problem of the package names not matching, so James’ solution is the best option.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 25, 2013, 11:54pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/6 "2013-09-25T23:54:11Z")

</div>

The host selector is there for selecting groups defined in inventory explicitly.

If you want to further pare down hosts, rather than doing the “-e” bits and making it more complex with {{ vars }}, it’s easier to just use --limit

ansible-playbook site.yml --limit pod6

Would run the whole playbook just on machines in pod6.

---

<div class="post-metadata">

**Author:** ![matt](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/matt/32/1267_2.png) [@matt](https://forum.ansible.com/u/matt)\
**Post date:** [September 26, 2013, 6:57am UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/7 "2013-09-26T06:57:26Z")

</div>

Can this be achieved in a single role, or would multiple roles be required, one for each OS?

---

<div class="post-metadata">

**Author:** ![James\_Cammarata1](https://avatars.discourse-cdn.com/v4/letter/j/d26b3c/32.png) [@James\_Cammarata1](https://forum.ansible.com/u/James_Cammarata1)\
**Post date:** [September 26, 2013, 7:06am UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/8 "2013-09-26T07:06:00Z")

</div>

This would need to be separate roles, since roles can’t contain hosts: entries.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 26, 2013, 12:23pm UTC](https://forum.ansible.com/t/installing-packages-on-multiple-operating-systems/13549/9 "2013-09-26T12:23:40Z")

</div>

You can just use the when statement in this case if you want to keep things in the same role.

when: ansible\_os\_family == ‘Debian’

etc
