1

An ansible-sensu-plugin-install role has been created in order to install sensu-plugins using this code:

- name: be sure sensu-plugins-{{ item.name }} is installed
  command: sensu-install -p {{ item.name }}:{{ item.version }}
  when: "'sensu-plugins-{{ item.name }} ({{ item.version }})' not in installed_plugins.stdout"
  with_items: "{{ sensu_plugin_install }}" 

There a two other roles that require sensu-plugins. The first role requires the mailer plugin:

sensu_plugin_install:
  - name: mailer
    version: 1.0.0

and the second one requires multiple plugins:

sensu_plugin_install:
  - name: cpu-checks
    version: 1.0.0
  - name: disk-checks
    version: 2.0.1
  - name: http
    version: 1.0.0
  - name: memory-checks
    version: 1.0.2
  - name: ntp
    version: 1.0.0

Role one and two have been included in one playbook.

Current outcome

Either the mailer defined in role one or the plugins defined in role two will be installed. Commenting out one of the sensu_plugin_install declarations will install plugins related to role one or two, e.g. only the mailer plugin will be installed:

TASK [030.sensu-plugin-install : be sure sensu-plugins-{{ item.name }} is
    installed] ***
    changed: [host.example.com] => (item={u'version': u'1.0.0', u'name':
    u'mailer'}) => {"changed": true, 

if the sensu_plugin_install of the second role has been commented out.

Expected outcome

The expected outcome is that all plugins will be installed, i.e. six in this case instead of one, i.e. mailer or five.

Discussion

It looks like that the arrays will not be merged as either one or five plugins will be installed instead of six and one of the two needs to be commented out in order to force the installation of a plugin.

One option to solve this issue is to merge these arrays, i.e. sensu_plugin_install + sensu_plugin_install. For example, in Puppet it is possible to merge arrays using hiera_array. How could this be done in Ansible?

Using Two different variables in order to solve the issue is not an option as the functionality of one role is used and it is not preferred to add another variable to this role if another role would like to install sensu plugins.

030
  • 5,731
  • 12
  • 61
  • 107
  • http://serverfault.com/q/685673/126632 – Michael Hampton Sep 27 '16 at 07:40
  • @MichaelHampton I would like to see that it is possible to do a kind of `sensu_plugin_install + sensu_plugin_install` instead of having two different variables. – 030 Sep 27 '16 at 07:48
  • 1
    I don't know of any way to do that. And it's probably not very clean to try. – Michael Hampton Sep 27 '16 at 07:49
  • @MichaelHampton In puppet one could do merge array and merge hash. – 030 Sep 27 '16 at 07:49
  • @techraf I have edited the question – 030 Sep 29 '16 at 08:13
  • @030 Unfortunately, it's even less clear now. I can't see why the task can't run twice: once for one `sensu_plugin_install` value (five plugins), the other time for another (one plugin). It's not a handler that gets executed once. – techraf Sep 29 '16 at 08:33
  • @techraf all three roles are included in the same playbook – 030 Sep 29 '16 at 08:37
  • I don't understand what you say. There is no term "to include a role" in Ansible vocabulary. – techraf Sep 29 '16 at 08:39
  • @techraf [This](https://github.com/030/ansible-sensu-server/blob/master/meta/main.yml#L18) is not including roles? – 030 Sep 29 '16 at 09:07
  • @030 No! You set/declared role as a dependency for another role. That's a far cry from **including** in a **playbook**. – techraf Sep 29 '16 at 09:18
  • Based on what do you conclude that it is a `far cry`? Are there any open related bugs for example and how would you solve this issue? – 030 Sep 29 '16 at 09:24
  • I already explained why the words you used were misleading. As for the problem itself, it is also not the one you are asking about. More than a question of combining two hashes, it is a problem of simultaneous access to variables with the same name defined in different roles as default values. Ansible wasn't designed to deal with such cases, it has strict variable precedence, and you probably won't get it solved unless you fork and rewrite the engine; or use hardcoded values for your roles; or move the variable assignment to a higher level, for example to the playbook. – techraf Sep 29 '16 at 13:10

2 Answers2

1

First of all I had to define two different variables rather than using the same one, e.g. sensu_plugin_install. After giving the second dict a different name like sensu_plugin_install_other, the two arrays were able to merge:

 with_items: "{{ sensu_plugin_install }} + {{ sensu_plugin_install_other }}"
030
  • 5,731
  • 12
  • 61
  • 107
0

Try this role from ansible galaxy https://galaxy.ansible.com/eugene0707/merge_custom_vars/

I did it some time ago for same reason. It can deep merge dictionaries from several vars files and set custom precedence of merging.

This role can work under Ansible 2.0+