Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Package Management

106 views
Skip to first unread message

KSS

unread,
Aug 19, 2014, 4:22:34 AM8/19/14
to ansible...@googlegroups.com
Hi,  I need to install some packages across different Linux distros (mainly CentOS/Redhat and Ubuntu right now). However, since there isn't a unified package manager (at least not bundled with core), I'm trying to find the best way to do this.

I understand that we can use something like 'when: ansible_os_family == "RedHat"' or the like, but when we have 400 CentOS hosts and 200 Ubuntu hosts, that's a lot of "skipping" messages (I'm aware these can also be suppressed in the main config file). We have playbooks that run against certain groups of hosts (these groups can contain multiple distros), so I'm not sure that using group_by is the best option either as, from my understanding, I'd have to have a 'group_by' in each of those playbooks and for each distro.

For example, we have an 'ntp' role which basically just installs the ntp package, drops in the ntp config using template and ensures it's started (we have similar roles for snmp, ssmtp etc.).

I came across a previous post with an answer from Michael DeHaan suggesting using the following action (although Michael does state that it's a bad idea), however, this no longer appears to work;

Using task;

 ---
##
# Install and configure NTPD

    - name: Gather OS Specific Variables
      include_vars: "{{ item }}"
      with_first_found:
         - "../vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml"
         - "../vars/{{ ansible_distribution }}.yml"
         - "../vars/{{ ansible_os_family }}.yml"
         - "../vars/defaults.yml"

    - name: Ensure NTP is Installed
      action: "{{ ansible_pkg_mgr }} name=ntp state=present"
      tags: ntp

    - name: Copy NTP Configuration File
      template: src=../templates/ntp.conf.j2 dest=/etc/ntp.conf
      notify:
         - restart ntpd
      tags: ntp

    - name: Start NTPD
      service: name="{{ ntp_service }}" state=started enabled=true
      tags: ntp

Results in;

TASK: [ntp | Ensure NTP is Installed] *****************************************
<XX.XX.XX.XX> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO XX.XX.XX.XX
<XX.XX.XX.XX> REMOTE_MODULE {{ ansible_pkg_mgr }} name=ntp state=present
fatal: [XX.XX.XX.XX] => module {{ not found in /usr/share/ansible/system:/usr/share/ansible/commands:/usr/share/ansible/messaging:/usr/share/ansible/cloud:/usr/share/ansible/notification:/usr/share/ansible/net_infrastructure:/usr/share/ansible/inventory:/usr/share/ansible/utilities:/usr/share/ansible/internal:/usr/share/ansible/files:/usr/share/ansible/packaging:/usr/share/ansible/database:/usr/share/ansible/source_control:/usr/share/ansible/network:/usr/share/ansible/web_infrastructure:/usr/share/ansible/monitoring:/usr/share/ansible

FATAL: all hosts have already failed -- aborting
----------------

Ansible Version: 1.6.10
OS: CentOS6.5

We have a few hundred servers for which puppet is used for config management and a hundred or so being managed using Salt (different departments hence the different tools), and the unified package managers seem to work well in those tools. Are there any plans to have a module in Ansible, even if it's just a simple wrapper to call the appropriate module, yum or apt or whatever, so these kind of playbooks look a bit better and make it easier where multiple distros are used. So, for example, in this case I'd just need something like;

 - name: Ensure NTP is Installed
   pkg: name=ntp state=present
   tags: ntp

...and the 'pkg' module works out the correct package module to call. I know the individual package modules do more than just install and remove packages but I feel, and maybe I'm the only one, that something like this would make things simpler and cleaner looking.

Anyway, does anyone have any recommendations to achieve this in the mean time?

Thanks.

Michael DeHaan

unread,
Aug 19, 2014, 8:14:18 AM8/19/14
to ansible...@googlegroups.com
"I understand that we can use something like 'when: ansible_os_family == "RedHat"' or the like, but when we have 400 CentOS hosts and 200 Ubuntu hosts, that's a lot of "skipping" messages"

Use this module:


- hosts: all
  tasks:
   - group_by: key=os-{{ ansible_os_family }}

- hosts: os-RedHat
  tasks:
     - # Red Hat things

Also be sure to use "with_items" where possible to group package installs into a minimum of transactions, which will save considerable install time.





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/90fc7427-cca3-434f-9c95-04b1e740281f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

KSS

unread,
Aug 19, 2014, 8:48:57 AM8/19/14
to ansible...@googlegroups.com
Hi Michael,

Yep, I know of the group_by module, but the way I understand it, this would require me to have a separate task for each distro that has a different package manager. Also since we have things arranged into roles which are called by playbooks split by, let's say, 'departments', I'd have to add the group_by for each distro into each playbook and move the tasks into those playbooks (rather than calling a role, unless I also split the roles by OS which makes things even less cleaner).

At the moment, my playbooks just look like this, as an example;

- hosts: 
    - prod-servers

  roles: 
    - common
    - ntp
    - snmp
    - nfs_client

I've found a library written by someone that does what I was hoping here:- https://github.com/mantiz/ansible-library-pkgmgr  but I didn't really want to go down the route of using libraries that may not be supported or become unusable in future versions of ansible.

Not sure if there is another way to do this?

Lucas, Sascha

unread,
Aug 19, 2014, 9:16:48 AM8/19/14
to ansible...@googlegroups.com
Hi,

From: KSS
Date: Tue, 19. Aug 2014 10:23

> However, since there isn't a unified package manager (at least not bundled with core), I'm trying to find the best way to do this.

I user dynamic groups and group variables to abstract the differences: put files Ubuntu / Suse / Linux / SunOS / AIX / what_ever in group_vars/*. Example:

Ubuntu:
nrpe_package: nagios-nrpe-server
nrpe_service: nagios-nrpe-server

Suse:
nrpe_package: nagios-nrpe
nrpe_service: nrpe

Then the play looks like:

- hosts: all
gather_facts: yes
sudo: true
tasks:
# create useful groups
- group_by: key={{ ansible_system }}
- group_by: key={{ ansible_distribution }}
# manage nrpe
- action: "{{ ansible_pkg_mgr }} name={{ nrpe_package }} state=installed"
- service: name={{ nrpe_service }} enabled=yes state=started
- template: src=common/etc/nagios/nrpe.cfg dest={{ nrpe_prefix }}nrpe.cfg owner=root group=root mode=0644 backup=yes
notify: restart nrpe
handlers:
- name: restart nrpe
service: name={{ nrpe_service }} state=restarted

HTH, Sascha.

Aufsichtsratsvorsitzender: Herbert Vogel
Geschäftsführung: Michael Krüger
Sitz der Gesellschaft: Halle/Saale
Registergericht: Amtsgericht Stendal | Handelsregister-Nr. HRB 208414
UST-ID-Nr. DE 158253683

Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte Informationen. Wenn Sie nicht der richtige Empfänger sind oder diese E-Mail irrtümlich erhalten haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser Mail oder des Inhalts dieser Mail sind nicht gestattet. Diese Kommunikation per E-Mail ist nicht gegen den Zugriff durch Dritte geschützt. Die GISA GmbH haftet ausdrücklich nicht für den Inhalt und die Vollständigkeit von E-Mails und den gegebenenfalls daraus entstehenden Schaden. Sollte trotz der bestehenden Viren-Schutzprogramme durch diese E-Mail ein Virus in Ihr System gelangen, so haftet die GISA GmbH - soweit gesetzlich zulässig - nicht für die hieraus entstehenden Schäden.

KSS

unread,
Aug 19, 2014, 10:23:58 AM8/19/14
to ansible...@googlegroups.com
Hi,

>> - action: "{{ ansible_pkg_mgr }} name={{ nrpe_package }} state=installed" 

This doesn't work for me, see original post, it results in an error (using ansible version 1.6.10). And from previous posts, it seems it's not recommended to use this method.

EDIT: just tried this using 1.7 and it does work again. Just a bit cautious of using this approach against the advice from Michael regarding using {{ ansible_pkg_mgr }} in this way


On Tuesday, 19 August 2014 09:22:34 UTC+1, KSS wrote:

Michael DeHaan

unread,
Aug 19, 2014, 11:23:29 AM8/19/14
to ansible...@googlegroups.com
This is a very common misconception.

Not only do packages change by distro, but also how you manage the package.

For instance, think of how Apache is managed very very differently between Ubuntu and RHEL.

This is the least of anyone's concerns so dealing with the idea that the OSes is different as soon is possible is the correct way of handling this.

Abstractions, in this case, are a lie.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

Michael DeHaan

unread,
Aug 19, 2014, 11:24:16 AM8/19/14
to ansible...@googlegroups.com
Yep, using {{ ansible_pkg_manager }} also won't take advantage of with_items optimizations in yum or apt, and will make things run much slower.

I am interested in what error you saw though.



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

KSS

unread,
Aug 20, 2014, 3:50:26 AM8/20/14
to ansible...@googlegroups.com
The error using 1.6.10 was as below (see original post);

TASK: [ntp | Ensure NTP is Installed] *****************************************
<XX.XX.XX.XX> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO XX.XX.XX.XX
<XX.XX.XX.XX> REMOTE_MODULE {{ ansible_pkg_mgr }} name=ntp state=present
fatal: [XX.XX.XX.XX] => module {{ not found in /usr/share/ansible/system:/usr/share/ansible/commands:/usr/share/ansible/messaging:/usr/share/ansible/cloud:/usr/share/ansible/notification:/usr/share/ansible/net_infrastructure:/usr/share/ansible/inventory:/usr/share/ansible/utilities:/usr/share/ansible/internal:/usr/share/ansible/files:/usr/share/ansible/packaging:/usr/share/ansible/database:/usr/share/ansible/source_control:/usr/share/ansible/network:/usr/share/ansible/web_infrastructure:/usr/share/ansible/monitoring:/usr/share/ansible

FATAL: all hosts have already failed -- aborting
----------------

It works as expected on 1.7.

But going back to the original question, it seems as though I'll have to just use  'when: ansible_os_family == "Whatever"' and suppress the skipping messages. It's a shame there isn't, and I get the vibe, isn't likely to be a unified package module for at least install/remove of packages (I realize there are differences in package names and location of config files between distros but most of the time these can easily be handled using OS specific var files). As an example, I do like the approach taken with this https://github.com/mantiz/ansible-library-pkgmgr and it would be good to have something like that. It seems the need for this has come up a few times before but maybe not enough to warrant a module or method to do this in a single task (when group_by can't be used).

Michael DeHaan

unread,
Aug 20, 2014, 9:07:48 AM8/20/14
to ansible...@googlegroups.com
"It works as expected on 1.7."

Ok, the latest stable ansible release is 1.7.1, so we should be good to go.  We are not going to be applying backports to any 1.6 releases.




Reply all
Reply to author
Forward
0 new messages