Ansible variable defined in group_vars/all not found
Asked Answered
S

4

15

Assume the Ansible structure:

.
├── group_vars
│   └── all
└── site.yml

Where all contains my_test_variable: yes, and site.yml is:

- hosts: all

  tasks:
    - name: Variable test
      debug: msg={{ my_test_variable }}

I'm using Vagrant to run it locally, so the command looks like:

$ ansible-playbook site.yml -i /path-to-vagrant/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory --private-key=/path-to-vagrant/.vagrant/machines/default/virtualbox/private_key -u vagrant

Vagrant's generated invertory file:

# Generated by Vagrant

default ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222

And the output:

PLAY: ***************************************************************************

TASK [setup] ********************************************************************
ok: [default]

TASK [Variable test] ************************************************************
fatal: [default]: FAILED! => {"msg": "ERROR! the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'my_test_variable' is undefined", "failed": true}

PLAY RECAP **********************************************************************
default                    : ok=1    changed=0    unreachable=0    failed=1 

I know this vagrant inventory is not inside any group - because there isn't any - but all groups inherit from all, right?

Why doesn't it work? What did I miss?


I'm Quite new to Ansible. Read a lot of the docs, couple of examples and even some SO questions like Ansible doesn't pick up group_vars without loading it manually -- not quite my problem -- and Cannot get ansible to recognize group variables -- close but not there either.


Edit

I'm following the recommended project structure from Ansible's doc, and in the variables doc entry they mention the global_vars/all:

Site wide defaults should be defined as a ‘group_vars/all’ setting.

Even though there is no direct reference on how to load these default values, I assume I don't have to explicitly add them (like suggested in the answer by @thiago-borges). Or do I?

The reason for this is that I intend to have group vars inheriting from all, like:

.
├── group_vars
│   └── all
│   └── production
│   └── staging
└── site.yml

And when I execute ansible-playbook for each, different files are loaded without I having to explicitly set them in the play file, eg:

ansible-playbook -i production site.yml


Edit 2

The issue was a bug on ansible. After an update it worked as documented.

Should I delete this question then?

Swingle answered 10/7, 2015 at 14:46 Comment(2)
This is very strange. It should work exactly like you are expecting it - and it does for me. Might it be the case you have another group_vars/all file relative to your inventory file? This file will be searched for relative to the playbook and relative to the inventory file but I experienced some strange behavior with precedence/merging when it exists in both locations.Wee
I would document it in an answer (linking to any bug report, if available) and mark it as the answer.Lungki
S
4

There was nothing wrong with the structure or the code it self. The reason for not working was a bug on ansible.

I couldn't find a bug report matching exactly this problem though, but I believe this issue Ansible incorrectly constructing paths when running a playbook in a subdirectory and this other issue I had reported myself might be related.

Currently running ansible from revision a1948dd1c151f01ce93d0b76745469a7065ef45e and it works fine:

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [default]

TASK [Variable test] ***********************************************************
ok: [default] => {
    "changed": false, 
    "msg": true
}

PLAY RECAP *********************************************************************
default                    : ok=2    changed=0    unreachable=0    failed=0 
Swingle answered 17/10, 2015 at 12:47 Comment(0)
K
5

From the Ansible's official guide:

In addition to storing variables directly in the INI file, host and group variables can be stored in individual files relative to the inventory file.

Since Vagrant generates its inventory file in ./.vagrant/provisioners/ansible/inventory/ you need to put a symlink on your group_vars into this directory.

Assuming, you have group_vars in the same directory as Vagrantfile and .vagrant:

cd ./.vagrant/provisioners/ansible/inventory; ln -sf ../../../../group_vars; cd -
Kaif answered 16/10, 2015 at 14:48 Comment(1)
I forgot to come back to this ticket, but the problem was a bug on ansible.Swingle
S
4

There was nothing wrong with the structure or the code it self. The reason for not working was a bug on ansible.

I couldn't find a bug report matching exactly this problem though, but I believe this issue Ansible incorrectly constructing paths when running a playbook in a subdirectory and this other issue I had reported myself might be related.

Currently running ansible from revision a1948dd1c151f01ce93d0b76745469a7065ef45e and it works fine:

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [default]

TASK [Variable test] ***********************************************************
ok: [default] => {
    "changed": false, 
    "msg": true
}

PLAY RECAP *********************************************************************
default                    : ok=2    changed=0    unreachable=0    failed=0 
Swingle answered 17/10, 2015 at 12:47 Comment(0)
H
2

On your site.yml, try setting the var_files configuration.

- hosts: all
  vars_files:
    - group_vars/all
  tasks:
    - name: Variable test
      debug: msg={{ my_test_variable }}
Huckaby answered 10/7, 2015 at 14:54 Comment(1)
Yes, it indeed works, but this is what I do not want to do: manually include the variable file. I'll edit my question explaining.Swingle
C
-1

Your structure should be :

| provisionning
├── inventory
├── playbook.yml
├── roles
|   └── [...]
├── group_vars
│   └── all
|       └── vars.yml
├── host_vars
|   └──site
|      └── vars.yml
Cheremkhovo answered 15/7, 2022 at 10:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.