Search code examples
vagrantansible

Ansible variable defined in group_vars/all not found


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?


Solution

  • 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