Wrong variable resolution with multiple groups

I recently filed this issue and would like to discuss it here.

https://github.com/ansible/ansible/issues/6048

My mental model is that a group represents a collection of hosts that I would like to treat in some similar fashion. When I apply actions to a group, my intuition says that only the variables that match the specified group should be valid; variables would be defined and expressed according to a set theoretic basis. It’s surprising to me that when groups are at the same ‘depth’, the behavior is undefined. This feels like the implementation bleeding out onto the user’s experience. Groups and the combination of groups should be well defined and I argue should follow the logic of sets.

Thoughts?

Hi Frank,

“When I apply actions to a group, my intuition says that only the variables that match the specified group should be valid; variables would be defined and expressed according to a set theoretic basis.”

Perhaps this is the misconception.

I imagine you have

hosts: group_a

and are curious why variables from group_b are coming in?

When you select hosts with a host specifier, you might do

“hosts:webservers”

but the host might not just be a webserver, it might also be in Phoenix Arizona and be a “dell9000” type of computer.

We want to get variables from all of those groups, both “role-affinity” and “geographic-affinity” and “hardware-affininity”.

The host spec only picks the host, it doesn’t define the role.

I see, so the hosts specifier is merely a selector and does not imply which set of group_vars are applied.

This seems like a useful feature, perhaps a “group_filter” attribute?

My use case is that I’m attempting to setup multiple products. Say I’ve got product X and product Y. Sometimes I’d like to install X locally, sometimes Y. Sometimes I’d like to deploy X to some machines. I was using a group to represent a product. Perhaps I should use a role here? Consider also that some components might be shared across both products.

Here’s the hierarchy of variables I’d like to have:

  • Product
  • Environment
  • Component

I’d like to set the Product from the command line, along with the Environment.

I can see how the Environment = the inventory. I can also see how the Component = a role. Is it possible to have a hierarchy of roles? Perhaps that’s all I need to define a Product?

Also, nitpick, if multiple groups at the same depth is undefined, what’s the point of defining group_vars at the same depth since they will be unreliable? Or does this only apply to duplicate variables? If so, maybe ansible should report a warning when this condition arises.

Thanks,
-Frank

Yep, sounds like these variables should be brought in by a role to get what you want.

When this happens, those variables will be made available to other roles in the same play, but not in future plays.

You could also use “include_vars” inside a task, but roles are really a good abstraction here.

The idiom I’ve usually used even before “roles” were first class things were “the goal of plays is to map roles to hosts”.

Thanks for your advice.

Could you help me understand how this is different from the example used on the Best Practices page. Under the “Operating System and Distribution Variance” section, we have group_vars/all and group_vars/CentOS. How is my example different from this? Seeing this is probably what got me off on the wrong path.

It’s not necessarily the wrong path for many folks. In many cases, all is a great place for defaults.

If you have a variable like “port” it’s usually better to name it something like “foo_port”.

However if yo have a variable that you don’t want used expect in certain situations, perhaps it doesn’t need to exist in the variable tree.

I think the best way to think about it is roles are applied at a given point in time (make x a foo), but inventory describes things that are true about the system regardless of what you are applying to it at a given point in time.