0

I have several Debian servers I use ansible on. One of the tasks is to install some packages. The behaviour is different from machine to machine, specifically when rerunning the playbook, some machines reinstall the package, while some other do not.

The relevant playbook portion:

  - name: install logstash on debian
    apt: deb=/tmp/logstash.deb
    when: ansible_os_family == "Debian"

The verbose output for both machines is:

TASK: [install logstash on debian] ********************************************
changed: [eu5.example.com] => {"changed": true, "stderr": "", "stdout": "(Reading database ... 45337 files and directories currently installed.)\nPreparing to unpack /tmp/logstash.deb ...\nUnpacking logstash (1:2.0.0-beta3-1) over (1:2.0.0-beta3-1) ...\nSetting up logstash (1:2.0.0-beta3-1) ...\nProcessing triggers for systemd (215-17+deb8u2) ...\n"}

TASK: [install logstash on debian] ********************************************
ok: [eu2.example.com] => {"changed": false, "stderr": "", "stdout": ""}

What is the mechanism which triggers the changed state? Since on both machines logstash is already installed (at the same level, from the same package), there are two possible cases:

  • either the aptcommand should run everytime, whether the package is installed or not (in that case eu5's behaviour is OK, eu2's is not)
  • or check if the package is installed and skip is so (in which case the OK/not OK behaviours above are switched)

A direct install:

[root@eu2:~]# dpkg -i /tmp/logstash.deb
(Reading database ... 232343 files and directories currently installed.)
Preparing to unpack /tmp/logstash.deb ...
Unpacking logstash (1:2.0.0-beta3-1) over (1:2.0.0-beta3-1) ...
Setting up logstash (1:2.0.0-beta3-1) ...
Processing triggers for systemd (227-2) ...

This suggests that the package will be reinstalled everytime (and therefore something is wrong with the behaviour of ansible on eu2). If this is indeed the case: is there a way to conditionally install only when the package is not installed yet? (some previous answers suggest that there is no such mechanism built-in in dpkg)

Community
  • 1
  • 1
WoJ
  • 27,165
  • 48
  • 180
  • 345
  • Looking into the module code, it seems that it will first query available packages and only "change" (install) if the package is not found or found in a previous version. Is the output of `dpkg -i /tmp/logstash.deb` the same between eu2 and eu5? – Allan Denot Oct 23 '15 at 02:35
  • @AllanDenot: the output is the same in both cases (the one I posted in my question). Per your comment, there should be no change after a first install (so the behaviour of `eu2` would be the correct one) – WoJ Oct 23 '15 at 15:17

1 Answers1

1

The apt module should return changed: True whenever a package is installed, upgraded, or removed. I doubt the bug is in Ansible, since this is one of the most commonly used modules and the edge cases have probably all been hit by someone at this point. Still, you probably want to get around it and move on. You could do something like this:

- command: dpkg -s logstash
  register: logstash_available
  ignore_errors: True
- name: install logstash on debian
  apt: deb=/tmp/logstash.deb
  when: logstash_available.rc != 0
Dan
  • 1,925
  • 3
  • 22
  • 28