Hierarchical overrides for playbooks

Hello,

First of all, I am coming from puppet. I have already done some experiments with ansible, and created a user management module, mainly to create the root Authkeys file. This was a little approach to see how overrides etc are handled by ansible.

The result was having the module executed twice, one for the general case and the other for the specific one. Because of this, I wondered whether it would be possible to have overrides correctly done.

I have read a thread asking for Ansible's hiera, and for what I understood, you proposed using lookups and external inventories. I see ansible has a different way to do stuff, but I don't understand how this sort of features would provide such flexibility.

I would be glad if someone could help me understand how to correctly structure Ansible code for my use case.

Hi Javier,

Perhaps you could start with explainig - for non-puppeteers here - what an ‘override’ exactly is, and show some basic high level example of what you try to accomplish?

Serge

My module is just a template that loops on an array, where elements
are users with groups belongings and sshkeys.

So, If I want to give access to all machines to sysadmins and
developers the devs ones, my playbook would be:

OK, I think I see it. There is no such thing as overriding playbooks. Playbooks are a series of plays that are a series of roles and tasks to execute, and tasks use variables.

The overriding here with ansible happens with variables in the inventory.

Given your case, you would define the variable user_groups in the inventory, as a group variable:

group_vars/all

No no, I meant overriding variables. In this case, the variable “user_groups” is an array of the groups that the role “users” has to install in each machine, and it doesn’t inherit from all the “sysadmin” group.

I need to know if there is something similar to achieve hierarchies of inheritance for variables. Or a big sample project. I need to understand how stuff is structured, because I find it like too linear atm, not allowing to specify that some machines have different properties makes harder to me to understand the abstraction layers.

I mean not being able to specify exceptions without having them be executed twice. (once for all and another for the specific case).

I understand is because of the knowledge I have and that I am accustomed to puppet, so any example on how to structure a big project would be really helpful. I aim to control everything with ansible, from users, configuration, installed programs, iptables rules, applications deployed, etc.

Thank you,

​Javier,​

No no, I meant overriding variables. In this case, the variable
"user_groups" is an array of the groups that the role "users" has to
install in each machine, and it doesn't inherit from all the "sysadmin"
group.

​You are confusing me,
- overriding variables happens within inventory groups, and as documented
- ​you talk about a "sysadmin group". Is this a /etc/group group or an
ansible group?

I need to know if there is something similar to achieve hierarchies of

inheritance for variables.

​Yes, that's what I was talking about. groups within the inventory have a ​
hierarch
​y: child groups override​ parent groups.

Check
    http://docs.ansible.com/intro_inventory.html
and the topic of variable precedence

http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable

(I'd agree the hierarchy of groups should be better documented though.)

Or a big sample project. I need to understand how stuff is structured,

because I find it like too linear atm, not allowing to specify that some
machines have different properties makes harder to me to understand the
abstraction layers.

​Basically you can define groups of groups, and the deeper the group, the
higher the level of importance.​

I mean not being able to specify exceptions without having them be
executed twice. (once for all and another for the specific case).

​You need to execute on the highest level group​, then modify variables on
child and/or grandchild groups.

I understand is because of the knowledge I have and that I am accustomed
to puppet, so any example on how to structure a big project would be really
helpful. I aim to control everything with ansible, from users,
configuration, installed programs, iptables rules, applications deployed,
etc.

​I'm actually not aware of extensive examples​

​of group hierarchy. Maybe a fellow list member can help here?

  Serge​

I think an example can be clearer, your play would look like this:

- hosts: all
  user: root
  roles:
    - users

now in group_vars/all you have

user_groups:
  - sysadmins

and in group_vars/dev you have

user_groups:
  - sysadmins
  - development

This is using the default strategy that overwrites, if you set it to
merge, you don't need to add the sysadmins in the devs file.

Hello,

First of all, I am coming from puppet. I have already done some
experiments with ansible, and created a user management module, mainly to
create the root Authkeys file. This was a little approach to see how
overrides etc are handled by ansible.

The result was having the module executed twice, one for the general case
and the other for the specific one. Because of this, I wondered whether it
would be possible to have overrides correctly done.

I have read a thread asking for Ansible's hiera, and for what I
understood, you proposed using lookups and external inventories. I see
ansible has a different way to do stuff, but I don't understand how this
sort of features would provide such flexibility.

Yeah, you don't want.

That is a confusing overdesigned hack to patch over something Puppet
couldn't do well originally, and something that Ansible was designed for
early on.

Ansible provides all the group and inventory management *out of the box*,
actually.

group_vars, host_vars, etc, all required without using an external tool.

One last questions. I learnt how to add new values (ex. devs can
access dev), but how may I selectively use merge or not strategy?

I mean, I want overrides on user_groups vars, but not in all of them.
In puppet it exists lookup_array, lookup_hash for merges, and
lookup_hiera for overriding.

For example,
--- groups_all
- users_groups:
  - sysadmin
--- groups_dev
- users_groups:
  - devs

lookup_hiera(users_groups) => ['devs']
lookup_array(users_groups) => ['devs', 'sysadmin']

So that I can choose to locally use some merge configs.

Thanks for the tips btw, I found strange the names but just because of
not being used to =)

you could always compose by env:

in group_vars/dev:

users: "{{devs|union(sysadmins)}}

in group_vars/prod:

users: "{{sysadmins}}"

The problem with that is that I have to say sysadmin...

wouldn't it be possible to have something like:

in group_vars/all:

groups: sysadmins

in group_vars/dev:

users: "{{devs|union(all)}}

in group_vars/prod:

users: "{{nsoc|union(all}}"

For example?

The idea is to specify "Merge this with the higher level result" or
"Substitute with this".

no, union takes a list, not a inventory file name

you can set global merge behavior but not make it per item, not sure
why specify the file works better than specify the list in the file

The idea is that if I want to merge top to bottom, makes no sense if I
have to put all the vars of the top file in the bottom file.

I will try to explore a little bit if this is something I can achieve somehow...