Variables in defaults/main.yml of a role are accessible from other roles. What if we have same {{ VAR }} names in several roles? Just wanted to check if this case is intended.

Hi,

I stumbled onto little mind game with ansible today : D .

I have three roles that are tagged.

  • hosts: vagrant
    sudo: yes
    roles:
  • {role: ansible_users, tags: users}
  • {role: ansible_nginx, tags: nginx}
  • {role: ansible_mysql, tags: mysql}

I have defaults/main.yml for “ansible_users” and “ansible_mysql” in their respective places.

This is “ansible_users” defaults:


users:

  • user: detlic
    webdir:
  • woodpecker
  • aligator
  • user: keder
    webdir:

This is “ansible_mysql” defaults:


users:

  • user: detlic
    db:
  • aligatordb
  • woodpeckerdb
  • user: jazavac
    db:
  • badgerdb
  • ddaybdb

I have left NGINX role without “defaults”. How I understand things is that NGINX will inherit “defaults” vars from other roles and use them where it can. But in this case {{ VARS }} are named the same in both USER and MYSQL roles.

NGINX role is before MYSQL from whoom it should inherit vars? In my test case it inherits it from the LAST role in the list. So in this case it is MYSQL. If I remove MYSQL role from a list then everything is fine.

Another thing is if I leave MYSQL role present BUT use TAGS and play roles with jsut USERS and NGINX tags, still NGINX inherits “defaults” from MYSQL.

Can someone comment on this.

It’s entirely intended. For instance, you might have a role that applies a particular configuration to machines that live in a particular datacenter, and one of the things that sets might be the port to use for the database
server. That port variable would then be available to other roles.

While this sounds scary at first, Ansible contains safeguards to make sure the variables used in one role are absolutely used there and not clobbered by another. Thus they have guaranteed scope to that role.

As such, if you define a variable “port” in two places, each role is guaranteed to be able to read the local value.

Hi,

That is 100% clear. But in this case one role does not have its own defaults and inherits defaults from the last role in a list regardles if that role is played or not.

Defaults load into inventory scope.

What I said applies to things in vars/

Thing is that I wanted to point out if I tag my roles, and run a play, is it intended to inherit vars from a role that is not in that particular play although it exists in playbook, but it is excluded in particular run because of tags.

Yes.

Tags apply only to the tasks therein, not the variables themselves.

Hello,

I guess I havent described good enough. variables get inherited from other roles if they are stored in defaults.

And if I run playbook with tags, I dont want variables to be inherited from the role that is not called with tags in the particular play.

Is that current behaviour? Or vars are inherited from every role in a play regarding if they are actually called with a tag in specific play or not.

You’ve described it good enough, I’m saying it’s meant to be that way.

I have also mentioned above about the protections in place on “vars”, but because “defaults” are inventory scope (so inventory can override them) they do not apply to defaults.

Namespace your variables by prefixing them with the role name will make this basically go away.