Issue 1:
ISSUE TYPE

Bug Report

COMPONENT NAME

vars_plugins

ANSIBLE VERSION

$ dpkg -l ansible
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii ansible 2.2.0.0-1ppa all A radically simple IT automation

$ ansible --version
ansible 2.2.0.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides

SUMMARY

Working on creating a vars plugin and discovered that in 2.2.0.0, the plugin is not getting any group vars. Downgrading to 2.1.0.0, and the plugin can get data via host.get_group_vars(). I think this is potentially related to #15493

STEPS TO REPRODUCE

Simple single host inventory with the following group_vars/all

test:
- a

Create the following simple vars_plugin at vars_plugins in the root of my working directory:

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

class VarsModule(object):

"""
Loads variables for groups and / or hosts

"""

def __init__(self, inventory):
self.inventory = inventory
self.inventory_basedir = inventory.basedir()

def append_test(self, groupvars):
results = {}
if 'test' in groupvars:
results.update({'test_plugin': 'yes'})

return results

def get_host_vars(self, host, vault_password=None):
""" Get host specific variables. """
return self.append_test(host.get_group_vars())

And update ansible.cfg with

[defaults]
...
vars_plugins = vars_plugins

Then I test with the following command:

ansible -m debug -a "var=hostvars[inventory_hostname]" all

EXPECTED RESULTS

I expect the vars_plugin to add what I wanted like so:

$ ansible -m debug -a "var=hostvars[inventory_hostname]" all -vvvv
Using /vagrant/test/ansible.cfg as config file
Loaded callback minimal of type stdout, v2.0
test1.vagrant | SUCCESS => {
"hostvars[inventory_hostname]": {
"ansible_check_mode": false,
"ansible_version": {
"full": "2.1.0.0",
"major": 2,
"minor": 1,
"revision": 0,
"string": "2.1.0.0"
},
"group_names": [
"ungrouped"
],
"groups": {
"all": [
"test1.vagrant"
],
"ungrouped": [
"test1.vagrant"
]
},
"inventory_dir": "/vagrant/test/inventory/vagrant",
"inventory_file": null,
"inventory_hostname": "test1.vagrant",
"inventory_hostname_short": "test1",
"omit": "__omit_place_holder__c1b35db14631b948fefe0c3827f517cea304164c",
"playbook_dir": ".",
"test": [
"a"
],
"test_plugin": "yes"
}
}

I downgraded from 2.2 step by step down to 2.1 and found all versions after 2.1.0.0 have this issue.

ACTUAL RESULTS

$ ansible -m debug -a "var=hostvars[inventory_hostname]" all -vvvv
Using /vagrant/test/ansible.cfg as config file
Loading callback plugin minimal of type stdout, v2.0 from /usr/lib/python2.7/dist-packages/ansible/plugins/callback/__init__.pyc
test1.vagrant | SUCCESS => {
"hostvars[inventory_hostname]": {
"ansible_check_mode": false,
"ansible_version": {
"full": "2.2.0.0",
"major": 2,
"minor": 2,
"revision": 0,
"string": "2.2.0.0"
},
"group_names": [
"ungrouped"
],
"groups": {
"all": [
"test1.vagrant"
],
"ungrouped": [
"test1.vagrant"
]
},
"inventory_dir": "/vagrant/test/inventory/vagrant",
"inventory_file": null,
"inventory_hostname": "test1.vagrant",
"inventory_hostname_short": "test1",
"omit": "__omit_place_holder__857b85a3093a239f7cbe078c9c82877e33561bcd",
"playbook_dir": ".",
"test": [
"a"
]
}
}

Issue 2:
ISSUE TYPE

Feature Idea

COMPONENT NAME

ansible 2.5.0
config file = /home/conductor/playbooks/ansible.cfg
configured module search path = ['/home/conductor/playbooks/plugins/modules']
ansible python module location = /home/conductor/env/lib/python3.5/site-packages/ansible
executable location = /home/conductor/env/bin/ansible
python version = 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609]

CONFIGURATION

CACHE_PLUGIN(/home/conductor/playbooks/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/conductor/playbooks/ansible.cfg) = ~/.ansible/facts
CACHE_PLUGIN_TIMEOUT(/home/conductor/playbooks/ansible.cfg) = 86400
DEFAULT_DEBUG(/home/conductor/playbooks/ansible.cfg) = False
DEFAULT_GATHERING(/home/conductor/playbooks/ansible.cfg) = smart
DEFAULT_JINJA2_EXTENSIONS(/home/conductor/playbooks/ansible.cfg) = jinja2.ext.do,jinja2.ext.i18n
INJECT_FACTS_AS_VARS(/home/conductor/playbooks/ansible.cfg) = False
MERGE_MULTIPLE_CLI_TAGS(/home/conductor/playbooks/ansible.cfg) = True
RETRY_FILES_ENABLED(/home/conductor/playbooks/ansible.cfg) = False

OS / ENVIRONMENT

N/A

SUMMARY

I'm trying to use the modern role include syntax to mix tasks and roles import in a playbook but switching to "classic manner" to the "import_include" syntax cause undefined variables issues.

When using the classic syntax, the role's defaults are visible inside the playbook file and other roles. When using import_roles, the role's defaults are visible only inside the role that declare them.

STEPS TO REPRODUCE

- hosts: localhost
tasks:
- import_role: { name: myrole }
- debug:
msg: "myrole default: {{ myrole_default }}"

file: roles/myrole/defaults/main.yaml

myrole_default: "hello"

EXPECTED RESULTS

TASK [debug] *****************************************************************************************
ok: [localhost] => {
"msg": "myrole default: hello"
}

ACTUAL RESULTS

TASK [debug] *****************************************************************************************
task path: /Users/jddupas/Projects/python/playbooks/playbook.yaml:4
fatal: [localhost]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'myrole_default' is undefined\n\nThe error appears to have been in '/Users/jddupas/Projects/python/playbooks/playbook.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n - import_role: { name: myrole }\n - debug:\n ^ here\n"
}

Note: When using the classic syntax, it works fine (but I can't mix tasks and roles as I need):

- hosts: localhost
roles:
- myrole
tasks:
- debug:
msg: "myrole default: {{ myrole_default }}"