16
votes

I have a host in 2 groups : pc and Servers I have 2 group_vars (pc and servers) with, in each the file packages.yml These files define the list of packages to be installed on pc hosts and on servers hosts

I have a role to install default package

The problem is : only the group_vars/pc/packages.yml is take into account by the role task, packages from group_vars/servers/packages.yml are not installed

Of course what I want is installation of packages defined for pc and servers

I do not know if it is a bug or a feature ...

Thanks for your help

here is the configuration :

# file: production
[pc]
armen
kerbel
kerzo

[servers]
kerbel

---
# packages on servers
packages:
  - lftp
  - mercurial

---
# packages on pc
packages:
  - keepassx
  - lm-sensors
  - hddtemp
2
It does not directly address your issue, this tool will create a graph so you can see how your host got assigned to a group willthames.github.io/2014/04/03/… - Mxx
What version of Ansible are you using? - Shahar
Latest ansible to date is 1.6.1 - Rico

2 Answers

7
votes

It's not a bug. According to the docs about variable precedence, you shouldn't define a variable in multiple places and try to keep it simple. Michael DeHaan (Ansible's lead dev) responded to a similar question on this topic:

Generally I find the purpose of plays though to bind hosts to roles, so the individual roles should contain the package lists.

I would use roles as it's a bit cleaner IMO.

If you really want (and this is NOT the recommended way), you can set the hash_behaviour option in ansible.cfg:

[defaults]
hash_behaviour = merge

This will cause the merging of two values when a hash (dict) is redefined, instead of replacing the old value with the new one. This does NOT work on lists, though, so you'll need to create a hash of lists, like:

group_vars/all/package.yml:

packages:
    all: [pkg1, pkg2]

group_vars/servers/package.yml:

packages:
    servers: [pkg3, pkg4]

Looping though that in the playbook is a bit more complex though.

7
votes

If you want to use such scheme. You should set the hash_behaviour option in ansible.cfg:

[defaults]
hash_behaviour = merge

In addition, you have to use dictionaries instead of lists. To prevent duplicates I recommend to use names as keys, for example:

group_vars/servers/packages.yml:

packages:
 package_name1:
 package_name2:

group_vars/pc/packages.yml:

packages:
 package_name3:
 package_name4:

And in a playbook task (| default({}) - for an absent "package" variable case):

- name: install host packages
  yum: name={{ item.key }} state=latest
  with_dict: packages | default({})