mlz7
mlz7

Reputation: 2157

Looking for clarification regarding ansible variable precedence

I have the following ansible setup:

ansible_test/playbooks/roles/main/main.yml

- name: hello world
  hosts: all
  
  tasks:
  - name: hello!
    shell: echo "test"

  - name: display config
    debug:
      msg: "testvar is {{ hostvars['localhost']['testvar'] }}"

ansible_test/playbooks/inventory/hosts

[main]
localhost

[main:vars]
testvar=99

ansible-test/playbooks/inventory/group_vars/all/main.yml

testvar: 77

Now, when I modify the hosts file to the following:

[main]
localhost testvar=88

[main:vars]
testvar=99

I get an output of "testvar is 88". However, when I remove this, I get "testvar is 77" instead of the expected "testvar is 99".

When I add "testvar: 101" to a file: ansible_test/playbooks/inventory/host_vars/localhost.yml, I get an output of "testvar is 101".

I am running the command:

/usr/bin/ansible-playbook -i playbooks/inventory/hosts playbooks/roles/main/main.yml --connection=local -vvvv

Why is this? Shouldn't this host-group definition still take precedence over group_vars?

enter image description here

Upvotes: 3

Views: 895

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39294

Looks to me like your example makes all the sense based on the documentation about variable precedence:

Ansible does apply variable precedence, and you might have a use for it. Here is the order of precedence from least to greatest (the last listed variables override all other variables):

  1. command line values (for example, -u my_user, these are not variables)
  2. role defaults (defined in role/defaults/main.yml) 1
  3. inventory file or script group vars 2
  4. inventory group_vars/all 3
  5. playbook group_vars/all 3
  6. inventory group_vars/* 3
  7. playbook group_vars/* 3
  8. inventory file or script host vars 2
  9. inventory host_vars/* 3
  10. playbook host_vars/* 3
  11. host facts / cached set_facts 4
  12. play vars
  13. play vars_prompt
  14. play vars_files
  15. role vars (defined in role/vars/main.yml)
  16. block vars (only for tasks in block)
  17. task vars (only for the task)
  18. include_vars
  19. set_facts / registered vars
  20. role (and include_role) params
  21. include params
  22. extra vars (for example, -e "user=my_user")(always win precedence)

Where you can see that:

  • inventory file or script group vars is 3
  • inventory group_vars/* is 4
  • inventory file or script host vars is 8
  • inventory host_vars/* is 9

So in you first trial, you have

  • inventory file or script group vars is 3 => 99
  • inventory group_vars/* is 4 => 77
  • inventory file or script host vars is 8 => 88

So, 88 wins.


Then you remove 88

  • inventory file or script group vars is 3 => 99
  • inventory group_vars/* is 4 => 77

So, 77 wins.


And then you add one:

  • inventory file or script group vars is 3 => 99
  • inventory group_vars/* is 4 => 77
  • inventory host_vars/* is 9 => 101

So 101 wins.

Upvotes: 4

Related Questions