Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ansible sub-role loads variables from parent role #19649

Closed
afunix opened this issue Dec 22, 2016 · 7 comments
Closed

Ansible sub-role loads variables from parent role #19649

afunix opened this issue Dec 22, 2016 · 7 comments
Assignees
Labels
affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug. module This issue/PR relates to a module. support:core This issue/PR relates to code supported by the Ansible Engineering Team. utilities Utilities category

Comments

@afunix
Copy link
Contributor

afunix commented Dec 22, 2016

ISSUE TYPE
  • Bug Report
COMPONENT NAME

include_vars

ANSIBLE VERSION
ansible 2.2.1.0 (stable-2.2 b1e44d1195) last updated 2016/12/21 09:59:48 (GMT -500)
  lib/ansible/modules/core: (detached HEAD 62dbe0debb) last updated 2016/12/21 10:00:23 (GMT -500)
  lib/ansible/modules/extras: (detached HEAD 17eebf2b4f) last updated 2016/12/21 10:00:23 (GMT -500)
  config file = 
  configured module search path = Default w/o overrides
CONFIGURATION
$  env | grep ANSIBLE
ANSIBLE_HOME=/Users/cqx874/ansible/ansible
OS / ENVIRONMENT

N/A

SUMMARY

include_vars documentation says that file parameter is relative, it will look for the file in vars/ subdirectory of a role or relative to playbook.

However when I use include_vars with with_first_found in sub-role variables are loaded from master role.

I have lots of roles which try to load variables based on ansible_distribution, ansible_os_family or ansible_system.
I also have lots of roles which depend on each other.
I need a way to load variables relative to the role itself, just like documentation states.

STEPS TO REPRODUCE

playbook.yml:

- hosts: 127.0.0.1
  connection: local
  roles:
    - master

roles/master/meta/main.yml:

---
dependencies:
    - { role: slave }

roles/slave/tasks/main.yml:

---
- include_vars:
    file: "{{item}}"
  with_first_found:
    - test_master.yml
    - test_slave.yml

- debug:
    var: variable

roles/master/vars/test_master.yml:

---
variable: master

roles/slave/vars/test_slave.yml:

---
variable: slave
EXPECTED RESULTS

Expected variable to be slave as there is no test_master.yml in role/slave/vars, so sensible should load test_slave.yml according to documentation.

ACTUAL RESULTS

variable is master.

$ ansible-playbook playbook.yml -vvv
No config file found; using defaults
 [WARNING]: Host file not found: /etc/ansible/hosts

 [WARNING]: provided hosts list is empty, only localhost is available


PLAYBOOK: playbook.yml *********************************************************
1 plays in playbook.yml

PLAY [127.0.0.1] ***************************************************************

TASK [setup] *******************************************************************
Using module file /Users/cqx874/ansible/ansible/lib/ansible/modules/core/system/setup.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: cqx874
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo ~/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997 `" && echo ansible-tmp-1482438409.93-219791886340997="` echo ~/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997 `" ) && sleep 0'
<127.0.0.1> PUT /var/folders/9h/p9701fj55yx6rld3m4d1w7qm0000gn/T/tmpTL11wC TO /Users/cqx874/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997/setup.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/cqx874/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997/ /Users/cqx874/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997/setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python /Users/cqx874/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997/setup.py; rm -rf "/Users/cqx874/.ansible/tmp/ansible-tmp-1482438409.93-219791886340997/" > /dev/null 2>&1 && sleep 0'
ok: [127.0.0.1]

TASK [slave : include_vars] ****************************************************
task path: /Users/cqx874/ansible/bugs/XXXXX-vars-subroles/roles/slave/tasks/main.yml:2
ok: [127.0.0.1] => (item=/Users/cqx874/ansible/bugs/XXXXX-vars-subroles/roles/master/vars/test_master.yml) => {
    "ansible_facts": {
        "variable": "master"
    }, 
    "invocation": {
        "module_args": {
            "file": "/Users/cqx874/ansible/bugs/XXXXX-vars-subroles/roles/master/vars/test_master.yml"
        }, 
        "module_name": "include_vars"
    }, 
    "item": "/Users/cqx874/ansible/bugs/XXXXX-vars-subroles/roles/master/vars/test_master.yml"
}

TASK [slave : debug] ***********************************************************
task path: /Users/cqx874/ansible/bugs/XXXXX-vars-subroles/roles/slave/tasks/main.yml:8
ok: [127.0.0.1] => {
    "variable": "master"
}

PLAY RECAP *********************************************************************
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   
@ansibot
Copy link
Contributor

ansibot commented Dec 22, 2016

@ansibot ansibot added affects_2.2 This issue/PR affects Ansible v2.2 bug_report module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. labels Dec 22, 2016
@jimi-c jimi-c removed the plugin label Jan 4, 2017
@abadger abadger removed the needs_triage Needs a first human triage before being processed. label Jan 4, 2017
yabhinav pushed a commit to yabhinav/ansible-role-common that referenced this issue Feb 27, 2017
fix issues when using role as dependencies
ansible/ansible#19649
@yabhinav
Copy link

+1

I am facing similar issue when running a dependency role declare in meta/main.yml, where both roles has include_vars to load distribution specific variables.

- name: Gather OS Specific Variables
  include_vars: "{{ item }}"
  with_first_found:
    - "{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml"
    - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml"
    - "{{ ansible_distribution }}.yml"
    - "{{ ansible_os_family }}.yml"
    - "default.yml"
>>> Working on ansible version : latest
 'source ~/.bashrc && workon ansible_latest && ansible-playbook /etc/ansible/roles/role_under_test/playbooks/test.yml && deactivate ; (exit $?)'

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [yabhinav.common : Gather OS Specific Variables] **************************
ok: [localhost] => (item=/etc/ansible/roles/yabhinav.common/vars/CentOS-7.yml)

TASK [yabhinav.common : Ensure NTP Synchronised] *******************************
ok: [localhost]

TASK [role_under_test : Gather OS Specific Variables] **************************
ok: [localhost] => (item=/etc/ansible/roles/role_under_test/vars/RedHat.yml)

TASK [role_under_test : Install IPA Client Packages] ***************************
changed: [localhost] => (item=[u'ipa-client', u'ipa-admintools', u'sssd-ipa', u'sssd-ldap', u'ipa-python', u'libipa_hbac', u'python-libipa_hbac', u'python-iniparse'])

As you can see above dependency role yabhinav.common has CentOS-7.yml and role_under_test has RedHat.yml in their relative vars folders. But for CentOS 6 both roles will lead from RedHat.yml

'source ~/.bashrc && workon ansible_latest && ansible-playbook /etc/ansible/roles/role_under_test/playbooks/test.yml && deactivate ; (exit $?)'
/root/.virtualenvs/ansible_latest/lib/python2.6/site-packages/cryptography/__init__.py:26: DeprecationWarning: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of cryptography will drop support for Python 2.6
  DeprecationWarning

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [yabhinav.common : Gather OS Specific Variables] **************************
ok: [localhost] => (item=/etc/ansible/roles/role_under_test/vars/RedHat.yml)

TASK [yabhinav.common : Install Common Packages] *******************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "'common_pkgs' is undefined"}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=1   

And as you can see the yabhinav.common/tasks/main.yml is loading variables from /etc/ansible/roles/role_under_test/vars/RedHat.yml instead of /etc/ansible/roles/yabhinav.common/vars/RedHat.yml and hence next task fails with undefined error

Even using relative path in the file names doesnt work

- name: Gather OS Specific Variables
  include_vars: "{{ item }}"
  with_first_found:
    - "../vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml"
    - "../vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml"
    - "../vars/{{ ansible_distribution }}.yml"
    - "../vars/{{ ansible_os_family }}.yml"
    - "../vars/default.yml"

This bug exist in all previous and latest ansible versions and needs an immediate path...

reproduced in ansible versions 2.0.0.0, 2.1.0.0, 2.2.0.0 and 2.2.1.0

@afunix
Copy link
Contributor Author

afunix commented Feb 28, 2017

So I worked around the issue adding paths to with_first_found:

- name: Load variables specific for OS family
  include_vars: "{{item}}"
  with_first_found:
    - files:
        - "{{ansible_distribution}}-{{ansible_distribution_version}}.yml"
        - "{{ansible_distribution}}-{{ansible_distribution_major_version}}.yml"
        - "{{ansible_distribution}}.yml"
        - "{{ansible_os_family}}.yml"
        - "{{ansible_system}}.yml"
      paths:
        - "../myrole/vars"

Not convenient, but works. Still waiting for a fix.

yabhinav pushed a commit to yabhinav/ansible-role-common that referenced this issue Feb 28, 2017
@yabhinav
Copy link

yabhinav commented Feb 28, 2017

@afunix Thanks for the work around!!

I would suggest a slightly better improvement :
*if using ansible-galaxy and installing role , rolename would be .
*if running the role from GitHub src code , role name would be

custom-role-name can be differently set in ansible galaxy but by default it will be same as gitHub-role-name, but still considering the . prefix its better we use {{role_path}} or {{role_path|basename}}

- name: Gather OS Specific Variables
  include_vars: "{{ item }}"
  with_first_found:
    - files:
        - "{{ansible_distribution}}-{{ansible_distribution_version}}.yml"
        - "{{ansible_distribution}}-{{ansible_distribution_major_version}}.yml"
        - "{{ansible_distribution}}.yml"
        - "{{ansible_os_family}}.yml"
        - "{{ansible_system}}.yml"
      paths:
        - "{{ role_path }}/vars"

I also notice that I have name my var Redhat.yml which is sometimes picket as RedHat.yml and sometimes ignored by inlcude_vars, so is it really case sensitive or case-insensistive

PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [role_under_test : Gather OS Specific Variables] **************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "No file was found when using with_first_found. Use the 'skip: true' option to allow this task to be skipped if no files are found"}
PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1   
PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [role_under_test : Gather OS Specific Variables] **************************
ok: [localhost] => (item=/etc/ansible/roles/role_under_test/vars/RedHat.yml)

Although this has nothing to with current bug.

yabhinav pushed a commit to yabhinav/ansible-role-ipaserver that referenced this issue Mar 5, 2017
@ansibot ansibot added the support:core This issue/PR relates to code supported by the Ansible Engineering Team. label Jun 29, 2017
@ansibot
Copy link
Contributor

ansibot commented Jul 19, 2017

hxpro added a commit to hxpro/ansible-role-phpfpm that referenced this issue Jan 25, 2018
@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 1, 2018
@ansibot ansibot added the utilities Utilities category label Feb 18, 2019
@samdoran
Copy link
Contributor

samdoran commented Aug 21, 2020

This is working as intended as described in the documentation. Adding paths: vars/ is the recommend way to get the desired behavior.

We should probably improve the documentation to describe the behavior more explicitly, possibly adding an example to the first_found lookup for this case specifically.

@s-hertel
Copy link
Contributor

Closing as per above

@ansible ansible locked and limited conversation to collaborators Sep 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug. module This issue/PR relates to a module. support:core This issue/PR relates to code supported by the Ansible Engineering Team. utilities Utilities category
Projects
None yet
Development

No branches or pull requests

8 participants