Variable not defined error

Hi there —

I have a variable called pbis_require_membership_of defined in group_vars/all.yaml, and it is overridden for a particular host under role/vars/hostname, however neither of the values are being used at runtime and the module errors with pbis_require_membership_of’ is undefined

`

(ansible)[ansible@ansible-server code]$ grep -R pbis_require_membership_of group_vars/

group_vars/all/all.yaml:pbis_require_membership_of: ‘“DOMAIN\teaminfra” “DOMAIN\LinuxAdmins”’

(ansible)[ansible@ansible-server code]$ grep -R pbis_require_membership_of roles/linux-pbis/vars/hostname

pbis_require_membership_of: ‘“DOMAIN\teaminfra” “DOMAIN\LinuxAdmins” “DOMAIN\StorageAdmins”’

`

However, the following occurs when I try to reference it at runtime:

`

TASK [linux-pbis : debug pbis_require_membership_of] ******************************************************************************************************************************************************************************

task path: roles/linux-pbis/tasks/main.yaml:62

ok: [hostname] => {

“pbis_require_membership_of”: “VARIABLE IS NOT DEFINED!”

}

TASK [linux-pbis : copy temp config file] ******************************************************************************************************************************************************************************

task path: roles/linux-pbis/tasks/reconfig_pbis.yaml:1

fatal: [hostname]: FAILED! => {“failed”: true, “msg”: “The conditional check ‘require_membership_of.stdout != pbis_require_membership_of’ failed. The error was: error while evaluating conditional (require_membership_of.stdout != pbis_require_membership_of): ‘pbis_require_membership_of’ is undefined\n\nThe error appears to have been in ‘roles/linux-pbis/tasks/reconfig_pbis.yaml’: line 1, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: copy temp config file\n ^ here\n”}

to retry, use: --limit @playbooks/linux/linux_pbis.retry

`

I’ve recently updated from Ansible 2.1 to the latest (using git pull), which may or may not have been when this issue started.

Any thoughts on why this variable is not getting set correctly?

Hello Elliott,

I have written a bit of code that may be helpful to you. You may find it here: https://github.com/gahan-corporation/ansible-development/tree/master/work/elliott-barrare

Hope it helps. Best of luck to you!

I would also say that best practice would be to put host specific vars within host_vars/hostname as opposed to within roles.

With roles I put my default vars within defaults and anything static within my role which will not change goes within the vars folder.

If there are host or group specific vars, put them in host_vars or group_vars this way if someone else has to read your code they do not need to dig in the depths of roles to figure out where the vars were defined.

Kind Regards

That is excellent advice, sir. I hope you don’t mind I’ve updated the readme to include it: https://github.com/gahan-corporation/ansible-development/tree/master/work/elliott-barrare

Thanks!

Thanks for all the advice, guys (I’m just getting back to this since last month). Unfortunately nothing seems to be working.

It appears that none of our variables seem to be getting set. I’ve tried various different locations and names for the group_vars file, including group_vars/all/all.yaml, group_vars/all/all.yml, group_vars/all.yaml and group_vars/all.yml and none of them seem to work. The following variables are set in each file, but neither are getting loaded:

`

My hunch is that you directory structure is not correct so Ansible can't find the files.

In the same directory as you inventory file, output of these commands would help track it down.
tree -L 3
ansible --version

But also your original message you wrote this
"I've recently updated from Ansible 2.1 to the latest (using git pull), which
may or may not have been when this issue started."

It you didn't remove 2.1 completely before you install from source you may have a combination of the two, and that will give you some strange behaviors.

My hunch is that you directory structure is not correct so Ansible can’t
find the files.

Yeah, that’s what I was thinking too, but unless that changed between versions I don’t know why it would suddenly stop working.

In the same directory as you inventory file, output of these commands
would help track it down.
tree -L 3

`

$ tree -L 3

.

├── ansible.cfg

├── cache

│ ├── server1

│ └── server2

├── examples

│ └── group_vars

│ ├── all

│ └── win

├── filter_plugins

├── group_vars

│ ├── all

│ │ └── all.yaml

│ ├── all.yaml

│ ├── all.yml

│ ├── linux

│ │ └── linux.yaml

│ ├── vagrant_linux.yaml

│ ├── vagrant_win.yaml

│ ├── win

│ │ ├── secure.yaml

│ │ └── win.yaml

│ └── workstations

│ ├── secure.yaml

│ └── workstations.yaml

├── host_vars

│ ├── hostname.yaml

│ └── vagrant2.yaml

├── inventory

│ ├── centos_templates

│ ├── production

│ │ ├── generated

│ │ └── production

│ ├── test

│ ├── vagrant

│ └── workstations

├── library

├── playbooks

│ ├── linux

│ │ ├── linux_ansible_control_machine.yaml

│ │ ├── linux_ftp.yaml

│ │ ├── linux_jump.yaml

│ │ ├── linux_nameservers.yaml

│ │ ├── linux_os_hardening.yaml

│ │ ├── linux_pbis.retry

│ │ ├── linux_pbis.yaml

│ │ ├── linux.retry

│ │ ├── linux_set_root_password.yaml

│ │ ├── linux_utility.yaml

│ │ ├── linux_webservers.yaml

│ │ ├── linux.yaml

│ │ └── templates

│ ├── testing

│ │ ├── dumpall.j2

│ │ ├── dump_vars.yaml

│ │ └── vagrant.yaml

│ ├── win

│ │ └── win_servers.yaml

│ └── workstations

│ └── win_workstations.yaml

├── README.md

├── roles

│ ├── linux-ansible-user

│ │ ├── defaults

│ │ ├── files

│ │ ├── handlers

│ │ ├── meta

│ │ ├── tasks

│ │ ├── templates

│ │ └── vars

│ ├── linux-common

│ │ ├── defaults

│ │ ├── files

│ │ ├── handlers

│ │ ├── tasks

│ │ ├── templates

│ │ └── vars

│ ├── linux-pbis

│ │ ├── defaults

│ │ ├── files

│ │ ├── meta

│ │ ├── tasks

│ │ ├── templates

│ │ └── vars

│ ├── linux-sendmail-client

│ │ ├── defaults

│ │ ├── files

│ │ ├── handlers

│ │ ├── meta

│ │ ├── tasks

│ │ ├── templates

│ │ └── vars

│ ├── linux-set-root-password

│ │ └── tasks

│ ├── linux-sudoers

│ │ ├── defaults

│ │ ├── files

│ │ ├── handlers

│ │ ├── meta

│ │ ├── tasks

│ │ ├── templates

│ │ └── vars

├── scripts

│ ├── ad_kerberos

│ ├── Gemfile

│ ├── Gemfile.lock

│ └── windows-servers.rb

├── site.retry

├── site.yaml

└── Vagrantfile

`

I have removed a lot of unnecessary output from the above, but it should still show the required hierarchy. The group_vars/all.y{,a}ml are an exact copy of group_vars/all/all.yaml and were created only for testing.

ansible --version

`

$ ansible --version

ansible 2.3.0 (devel 92a568c816) last updated 2017/01/20 13:14:32 (GMT -600)

config file =

configured module search path = Default w/o overrides

`

But also your original message you wrote this
“I’ve recently updated from Ansible 2.1 to the latest (using git pull),
which
may or may not have been when this issue started.”

It you didn’t remove 2.1 completely before you install from source you
may have a combination of the two, and that will give you some strange
behaviors.

Unfortunately I don’t think that’s the case. I moved our ansible_source directory aside and cloned the ansible repo again from scratch — there should not be any conflicts.

Thanks for the reply, and any additional help!

My hunch is that you directory structure is not correct so Ansible can't
find the files.

Yeah, that's what I was thinking too, but unless that changed between
versions I don't know why it would suddenly stop working.

So this did work at some point?
If so did it stop after you upgraded, if thats the case does it work if you downgrade to the last working version?

In the same directory as you inventory file, output of these commands
would help track it down.
tree -L 3

$ tree -L 3
.

├── ansible.cfg
├── group_vars
├── host_vars
├── inventory
│ ├── centos_templates
│ ├── production
│ │ ├── generated
│ │ └── production
│ ├── test
│ ├── vagrant
│ └── workstations
├── playbooks
│ ├── linux
│ │ ├── linux_ansible_control_machine.yaml
│ │ ├── linux_ftp.yaml
│ │ ├── linux_jump.yaml
│ │ ├── linux_nameservers.yaml
│ │ ├── linux_os_hardening.yaml
│ │ ├── linux_pbis.retry
│ │ ├── linux_pbis.yaml
│ │ ├── linux.retry
│ │ ├── linux_set_root_password.yaml
│ │ ├── linux_utility.yaml
│ │ ├── linux_webservers.yaml
│ │ ├── linux.yaml
│ │ └── templates
│ ├── testing
│ │ ├── dumpall.j2
│ │ ├── dump_vars.yaml
│ │ └── vagrant.yaml
│ ├── win
│ │ └── win_servers.yaml
│ └── workstations
│ └── win_workstations.yaml
├── site.yaml

I think I see what could be a problem.
I guess you are running ansible-playbook from the directory ansible.cfg is in, and running someting like this?

ansible-playbook -i inventory/<sonething> playbooks/linux/linux.yaml

The reason I ask is that host_vars and group_vars must be in the same directory as the inventory or playbooks[1]

And here they are on the top level, so only site.yml is able to use host_vars and group_vars in your layout.

If you move the playbook you have problem with to the same level as site.yml, does it work?

$ ansible --version

ansible 2.3.0 (devel 92a568c816) last updated 2017/01/20 13:14:32 (GMT -600)
config file =
configured module search path = Default w/o overrides

Did you run this the the ansible directory, it should have displayed the path to ansible.cfg in "config file", but yours is empty.

[1] https://docs.ansible.com/ansible/intro_inventory.html#splitting-out-host-and-group-specific-data

So this did work at some point?
If so did it stop after you upgraded, if thats the case does it work if
you downgrade to the last working version?

It did work at some point, and I believe it stopped working immediately after the upgrade.

Good point, I forgot I can simply check out an older version from Git to force an older version of Ansible. I will try that in a bit if other options don’t work.

In the same directory as you inventory file, output of these commands
would help track it down.
tree -L 3

$ tree -L 3
.

├── ansible.cfg
├── group_vars
├── host_vars
├── inventory

├── site.yaml

I think I see what could be a problem.
I guess you are running ansible-playbook from the directory ansible.cfg
is in, and running someting like this?

ansible-playbook -i inventory/ playbooks/linux/linux.yaml

That is correct, but I am also specifying -l and --tags to limit scope for testing.

The reason I ask is that host_vars and group_vars must be in the same
directory as the inventory or playbooks[1]

And here they are on the top level, so only site.yml is able to use
host_vars and group_vars in your layout.

If you move the playbook you have problem with to the same level as
site.yml, does it work?

Aha! That indeed fixes it. I guess we were relying on some deprecated functionality that disappeared when we upgraded.

I have now moved playbooks/linux/linux.yaml to ./linux.yaml for testing, but this is obviously not a great long-term solution (we have a lot of playbook files, and we like to organize them with directories). I have tried moving the host_vars and group_vars directories underneath the ./playbooks and ./inventory directories respectively, but neither of those locations work either (probably because each contains a sub-directory that contains the .yaml files themselves)

What is the recommended directory structure for this type of setup, allowing us to keep an organized subdirectory structure?

$ ansible --version

ansible 2.3.0 (devel 92a568c816) last updated 2017/01/20 13:14:32 (GMT -600)
config file =
configured module search path = Default w/o overrides

Did you run this the the ansible directory, it should have displayed the
path to ansible.cfg in “config file”, but yours is empty.

It looks like I ran this from a subdirectory before. When I run from the ansible directory the “config file” value is displayed correctly.

If you move the playbook you have problem with to the same level as
site.yml, does it work?

Aha! That indeed fixes it. I guess we were relying on some deprecated
functionality that disappeared when we upgraded.

I have now moved playbooks/linux/linux.yaml to ./linux.yaml for testing,
but this is obviously not a great long-term solution (we have a lot of
playbook files, and we like to organize them with directories). I have
tried moving the host_vars and group_vars directories underneath the
./playbooks and ./inventory directories respectively, but neither of those
locations work either (probably because each contains a sub-directory that
contains the .yaml files themselves)

Yes, they need to be on the same level as the yaml file.

What is the recommended directory structure for this type of setup,
allowing us to keep an organized subdirectory structure?

Ansible was not designed for you layout, there is an alternate layout in the best practice
https://docs.ansible.com/ansible/playbooks_best_practices.html#alternative-directory-layout

Since Ansible follow symlinks, you could just make some links to host_vars and group_vars and keep the layout as-is.