5

I have a few tens of hosts that are a mix of CentOS 6 and 7. I recently started using Ansible to help manage them, but I'm still very much a newbie.

Like everybody, I have a periodic need to update packages on those machines, especially for security reasons. However, I don't want to update all packages on them, just specific ones -- which may vary from machine to machine, depending on its roles. I have used Ansible's yum command, with state=latest, and a list of specific packages, to update those hosts in the past, but only today did I notice that when running that against a host, if one of the listed packages is not installed on that machine it will then be installed.

What I need is a way to supply Ansible with a list of packages, and then for each host it will act upon: - if the package is present, update it to the latest version; - if the package is not present, do nothing.

Is there a practical way to do that?

Iba Popo
  • 51
  • 1
  • 1
  • 3
  • You will have to make a list of packages, and for each package check first if it's installed e.g. with `rpm -q package` (which exits with false if not), register that result in a variable and then use that to determine to perform the `yum` command or not (with a `when:` clause). I can't spell it out as I'm not that good either :) – wurtel May 19 '16 at 14:57
  • Thanks, @wurtel! Will try to make that work. If somebody else could provide a simple example of that at work, that'd still be much appreciated. – Iba Popo May 20 '16 at 13:15

3 Answers3

3

Since ansible 2.5 there is an option update_only for yum (and since ansible 2.1 only_upgrade for apt) which installs latest version only if it was already installed on the system. So, instead of collecting a list of packages in another task, you can add the option.

- name: Update subset of packages.
  yum:
    name: "{{ item }}"
    state: latest
    update_only: yes
  with_items:
    - package1
    - package2

I am myself was searching the web and this article was found before I got to the official documentation. So I think it worse to be added here.

Andrew Schulman
  • 8,811
  • 21
  • 32
  • 47
Dennis M.
  • 31
  • 1
2

If you only want to update a subset of the packages with available updates you might want to try @wurtel s attempt. You will need to register the installed packages like this:

- name: Get installed packages.
  command: rpm -qa --qf "%{NAME}\n"
  register: installed_packages

Then you can define a set theory filter and update all the packages defined in the list of packages which are allowed to update packages_to_update.

- name: Update subset of packages.
  yum:
    name: "{{ item }}"
    state: latest
  with_items:
  - {{ installed_packages | intersect(packages_to_update) }}
Henrik Pingel
  • 9,380
  • 2
  • 28
  • 39
  • Thank you, knowhy. But, if I understood correctly, I would need to know beforehand exactly which packages I want updated on which host or group of hosts, right? What I need is for this to be done dynamically -- one list of packages is provided and, for each host, only those packages in the list that are present in that host should be actioned. – Iba Popo Jun 03 '16 at 14:17
  • Why do you want to update only subset of the packages installed? – Henrik Pingel Jun 03 '16 at 17:14
  • Stability. We don't have the means to test all the updates, and we have a sensitive environment, so we only install the more important security ones. – Iba Popo Jun 06 '16 at 13:05
  • I still don't think it is a good idea, but I have added an attempted to do that. I guess `rpm` might update packages as dependencies even when they are not set. But not sure.I have no RHEL distro at hand so you are welcome to correct me if made mistakes. – Henrik Pingel Jun 06 '16 at 17:53
  • See https://stackoverflow.com/a/41551876/2897386 for a similar solution, but without relying on the rpm shell command. – DustWolf Aug 04 '20 at 07:48
1

This all seems a little complicated for a yum update?

why not just use a local command for this until Ansible gets around to allowing this option?

A simple playbook like this would do it.

---
- hosts: dev-systems
  remote_user: admin
  become: yes
  tasks:
    - name: Update installed packages.
      command: /usr/bin/yum update -y {{item}}
      with_items:
          - package1
          - package2
          - package3
          - package-etc

I just tested this and using two packages. one that needed an update and one that was not installed. End result was an updated package with out the other being installed.

Jake Amey
  • 11
  • 1