13

On Ansible 2.2,

I have an Ansible hosts file:

[webserver]
aegir.dev

[hostmaster]
aegir.dev

I have two group_vars/ files:

# group_vars/webserver.yml
my_var:
  - vagrant

and

# group_vars/hostmaster.yml
my_var:
  - vagrant
  - aegir

and the playbook:

- hosts: webserver
  tasks:
    - debug: var=my_var

- hosts: hostmaster
  tasks:
    - debug: var=my_var

Output:

PLAY [webserver] ***************************************************************

TASK [setup] *******************************************************************
ok: [aegir.dev]

TASK [debug] *******************************************************************
ok: [aegir.dev] => {
    "my_var": [
        "vagrant",
        "aegir"
    ]
}

PLAY [hostmaster] **************************************************************

TASK [setup] *******************************************************************
ok: [aegir.dev]

TASK [debug] *******************************************************************
ok: [aegir.dev] => {
    "my_var": [
        "vagrant",
        "aegir"
    ]
}

Why both webserver and hostmaster use the variables from hostmaster.yml?

Probably I'm not using the group_vars correctly but how I can fix that?

EDIT

The real case scenario is that I have the same role running on two groups, one is webserver that actually contains 4 generic servers and the hostmaster group that is a webserver + extra configuration on the same role (the user aegir exists only on aegir.dev and not on the other 3 web-servers)

tvl
  • 369
  • 3
  • 4
  • 10
  • 1
    Looks broken by design to me. The main problem is, that Ansible has no proper scoping at all. It is the direct consequence of Ansible's idea to build a programming language on top of a JSON data structure. – ceving Jan 18 '17 at 13:59

2 Answers2

6

This is expected behaviour. See documentation:

Within any section, redefining a var will overwrite the previous instance. If multiple groups have the same variable, the last one loaded wins. If you define a variable twice in a play’s vars: section, the 2nd one wins.

Konstantin Suvorov
  • 3,996
  • 1
  • 12
  • 13
  • 2
    Thanks! That's true, but how I can overcome this problem? I don't want to assign them directly in the playbook (after every task) because it will make a mess... – tvl Nov 21 '16 at 15:13
  • You have to refactor your variables. But your question lacks use case details to give any advices... – Konstantin Suvorov Nov 21 '16 at 15:18
  • 1
    The real case scenario is that I have the same role running on two groups, one is `webserver` that actually contains 4 generic servers and the `hostmaster` group that is a webserver + extra configuration on the same role (the user aegir exists only on aegir.dev and not on the other 3 web-servers) – tvl Nov 21 '16 at 16:01
  • I'd split role into generic and hostmater. Or you can try to adopt something like [this](http://stackoverflow.com/a/40280199/2795592) in your role (define what users should be created, based on group names). – Konstantin Suvorov Nov 21 '16 at 16:38
4

This question is a bit old but the mentioned issue already exists, so I wrote my answer to one who needs the answer.

Actually, based on the documentation, Ansible focused on the Host and Task, so groups don’t really survive outside of inventory and host matching. To solve this problem, we need to add a prefix to variables of groups (like using namespacing to avoid conflicts).

# inventory/hosts.yml
webservers:
  hosts:
    host1:
    host2:
  vars:
    webserver_my_var: ...

hostmaster:
  hosts:
    host1:
  vars:
    hostmaster_my_var: ...

And in the playbook, you can use the variable safely.

# playbooks/main.yml
- hosts: webserver
  tasks:
    - debug: var=webserver_my_var | mandatory

- hosts: hostmaster
  tasks:
    - debug: var=hostmaster_my_var | mandatory

This way you will eliminate the problem safely.

Using the same variable name inside multiple groups has another problem. It's hard to guess the value of a variable by just looking at the inventory, you need to know the relation between groups and the order/precedence of one group to another and it is hard work and error-prone.

Ocean
  • 156
  • 1