# Scope gets polluted with variables from included roles even though private\_role\_vars = yes

**URL:** <https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972>\
**Category:** Ansible Project\
**Created:** [July 13, 2017, 11:00am UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972 "2017-07-13T11:00:08Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [July 13, 2017, 11:00am UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/1 "2017-07-13T11:00:08Z")

</div>

Hi!

Whenever I include a role using the meta dependencies tag I ended up with the scope of the included role in the current role, even though I set private\_role\_vars = yes

As an example, consider a project like this

`

├── ansible.cfg  
├── roles  
│ ├── some\_other\_role  
│ │ └── vars  
│ │ └── main.yml  
│ └── some\_role  
│ ├── defaults  
│ │ └── main.yml  
│ ├── meta  
│ │ └── main.yml  
│ └── tasks  
│ └── main.yml  
└── test.yml

`

the playbook test.yml simply includes ‘some\_role’

`

- hosts: all  
tasks:
- include\_role:  
name: some\_role

`

In some\_role meta definition I include a dependency (some\_role/meta/main.yml)

`

`

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [July 13, 2017, 1:24pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/2 "2017-07-13T13:24:29Z")

</div>

The private setting does not affect dependencies as those are  
specifically 'included' by the role. It is only mean to keep role vars  
from polluting the rest of the play.

---

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [July 13, 2017, 1:45pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/3 "2017-07-13T13:45:49Z")

</div>

Oh I see

I have changed the code and if I include the role by means of include\_role in the main tasks I get the expected result.

`

---

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [July 13, 2017, 1:47pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/4 "2017-07-13T13:47:56Z")

</div>

Funny thing is that if I refactor to explicitly include instead of meta dependencies I hit this bug, [https://github.com/ansible/ansible/issues/23609](https://github.com/ansible/ansible/issues/23609).

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [July 13, 2017, 1:53pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/5 "2017-07-13T13:53:54Z")

</div>

Actually, include\_role is currently bugged in that it does NOT expose  
the vars. So I would not rely on that behaviour.

---

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [July 13, 2017, 2:15pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/6 "2017-07-13T14:15:35Z")

</div>

But still, I think that a proper mechanism for role scoping should be implemented, if you try to reuse code odds are that you end up having several roles with several variables declared inside each job. Things like ‘path’ or ‘port’ are expected to be declared inside those roles, either by vars statements while including or inside the role.

Imagine the following scenario

`

vars (vars/main.yml)  
porrt:3000

metafile (meta/main.yml):  
dependencies:

- { role:nginx\_server }

task (tasks/main.yml):  
-include\_role:  
unicorn\_server  
args:  
listen: {{ port }}

`

In the dependency you don’t specify a role so an internal port variable is used (lets say port 80)

The second one has parameter that you set to port, but given that you misspelled it in the vars file you end up having an 80 here. This should be an ‘undefined variable’ because you should not bother with name clashing.

---

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [July 13, 2017, 5:11pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/7 "2017-07-13T17:11:02Z")

</div>

There is also a bigger issue in here. Variables are lazy evaluated ([https://github.com/ansible/ansible/issues/10374](https://github.com/ansible/ansible/issues/10374)).

So if for example you include a role and use a variable evaluation in its args, you have absolutely no way if ensuring what is going to be the value when that arg is used inside the role.

`  
roles/some\_role/tasks/main.yml:

---

<div class="post-metadata">

**Author:** ![Daniel\_C\_Schmidt](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@Daniel\_C\_Schmidt](https://forum.ansible.com/u/Daniel_C_Schmidt)\
**Post date:** [July 13, 2017, 6:49pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/8 "2017-07-13T18:49:50Z")

</div>

> That makes modules completely unusable, code cannot be reused in Ansible?

It’s not ideal, but a simple workaround is simply to prefix your role variables with the name of the role. For example, using the names “nginx\_port” and “unicorn\_port” instead of just “port”. It’s actually worked fine in practice; the trick is that Ansible’s flexibility tempts you to buck the convention.

---

<div class="post-metadata">

**Author:** ![Daniel\_C\_Schmidt](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@Daniel\_C\_Schmidt](https://forum.ansible.com/u/Daniel_C_Schmidt)\
**Post date:** [July 13, 2017, 7:32pm UTC](https://forum.ansible.com/t/scope-gets-polluted-with-variables-from-included-roles-even-though-private-role-vars-yes/24972/9 "2017-07-13T19:32:41Z")

</div>

Oh—just re-read the example. If that’s actually the case then it would be a bug, since task vars are supposed to have [higher precedence](http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable) than role vars. The example doesn’t work as-written, however, because the task should be called with “vars:” (not “args:”). Perhaps that’s the source of the problem?
