I am trying to split my Ansible role variables into multiple files - as per this answer, it should be possible to create a vars/main
directory, and all the .yml files in that directory should be automatically loaded.
However, this does not seem to happen in my case.
My directory structure:
vars
└── main
├── gce_settings.yml
├── vsphere_settings.yml
└── vsphere_zone.yml
However, when I try to use a variable defined inside vsphere_settings.yml, Ansible complains that the variable is undefined:
{"msg": "The task includes an option with an undefined variable. The error was: 'vsphere_user' is undefined
If I move the variable declaration into vars/main.yml
, everything works as expected. But, of course, I would prefer to separate my variables into multiple files.
I was unable to find any reference to this "feature" in the official Ansible documentation, and I do not know how I could troubleshoot it. Can anyone point me in the right direction?
My ansible version:
ansible 2.8.5
on Ubuntu 16.04
And before you ask: yes, I did make sure that main.yml
was not present when trying to load vars/main/*.yml
...
TL;DR version: it is a bug in ansible, caused by the presence of empty .yml files in vars/main
. There is a PR out for it already. See
here .
The actual result (as mentioned in the comments) actually depends on the order the files are processed (by default, it looks like my Ansible processes them in alphabetical order - but this might depend on the version, or the underlying OS):
ERROR! failed to combine variables, expected dicts but got a 'NoneType' and a 'AnsibleMapping'
More details: since I have no idea how to troubleshoot this in Ansible itself, I went to the code and started to add print
statements to see what is happening.
In my case, I had some empty .yml files in the vars/main
directory (files that I was planning to populate later on. Well... it looks like when the code encounters such an empty file, it destroys the entire dictionary that it has built so far.
Either I'm missing something very important, or this is a bug... Steps to reproduce:
vars/main
directory, and populate it with some .yml files ansible# tree roles
roles
+-- test
+-- tasks
¦ +-- main.yml
+-- vars
+-- main
+-- correct_vars.yml
4 directories, 2 files
ansible# cat roles/test/vars/main/correct_vars.yml myname: bogd
ansible# ansible-playbook -i inventory.yml test.yml
...
ok: [localhost] => {
"myname": "bogd" }
...
ansible# echo > roles/test/vars/main/emptyfile.yml
ansible# ansible-playbook -i inventory.yml test.yml
... ok: [localhost] => {
"myname": "VARIABLE IS NOT DEFINED!" }
...
Later edit: yep, it's a bug... See here.