Ansible: updating select packages if installed without installing if not
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?
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.
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) }}
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.