1
votes

Ansible 2.7.9 is not using host_vars

Ive setup a very simple setup with 3 hosts, mainly for testing purposes . I have hosts :

- ansible1 (this is where I store the code)
- ansible2
- ansible3

My inventory :

[ansible@ansible1 ~]$ cat /etc/ansible/hosts
[common]
ansible1
ansible2
ansible3

My cfg looks like that :

[ansible@ansible1 ~]$ cat /etc/ansible/ansible.cfg
[defaults]
roles_path = /etc/ansible/roles
inventory  = /etc/ansible/hosts
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
pipelining = False
[accelerate]
[selinux]
[colors]

I have defined a master playbook called common which calls common :

[ansible@ansible1 ~]$ ls /etc/ansible/roles/
common  common.retry  common.yml
[ansible@ansible1 ~]$ cat /etc/ansible/roles/common.yml
--- # Playbook for webservers
- hosts: common
  roles:
    - common
[ansible@ansible1 ~]$

The task/main.yml :

[ansible@ansible1 ~]$ cat /etc/ansible/roles/common/tasks/main.yml
- name: test ansible1
  lineinfile:
    dest: /tmp/ansible.txt
    create: yes
    line: "{{ myvar }}"
- name: set ansible2
  lineinfile:
    dest: /tmp/ansible2.txt
    create: yes
    line: "hi"
[ansible@ansible1 ~]$

[ansible@ansible1 ~]$ cat /etc/ansible/roles/common/vars/main.yml
copyright_msg: "Copyrighta 2019"
myvar: "value of myvar from common/vars"

THen I placed some info at /etc/ansible/host_vars

[ansible@ansible1 ~]$ ls /etc/ansible/hosts_vars/
ansible2.yml
[ansible@ansible1 ~]$ cat /etc/ansible/hosts_vars/ansible2.yml
myvar: "myvar from host_vars"
[ansible@ansible1 ~]$

This works great with playbook :

[ansible@ansible1 ~]$ ansible-playbook /etc/ansible/roles/common.yml --limit ansible2

PLAY [common] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [ansible2]

TASK [common : test ansible1] **************************************************
changed: [ansible2]

TASK [common : set ansible2] ***************************************************
changed: [ansible2]

PLAY RECAP *********************************************************************
ansible2                   : ok=3    changed=2    unreachable=0    failed=0

I see the file with the content of myvar :

[root@ansible2 ~]# cat /tmp/ansible.txt
value of myvar from common/vars
[root@ansible2 ~]#

But then I dont understand why it is not taking the value from /etc/ansible/hosts_vars/ansible2.yml , in fact if I comment the line from /etc/ansible/roles/common/vars/main.yml it says undefined variable :

[ansible@ansible1 ansible]$ cat /etc/ansible/roles/common/vars/main.yml
copyright_msg: "Copyrighta 2019"
myvar: "value of myvar from common/vars"
2
Ansible 2.8.1: hosts_vars (plural) is now discarded as invalid. Only host_vars works.Teresa e Junior
Yes, it was just a typo, thanks :)Flechoide

2 Answers

2
votes

Ansible uses that priority for values from vars :

From least to most important
role defaults
inventory file or script group vars
inventory group_vars/all
playbook group_vars/all
inventory group_vars/*
playbook group_vars/*
inventory file or script host vars
inventory host_vars/*
playbook host_vars/*
host facts
play vars
play vars_prompt
play vars_files
role vars (defined in role/vars/main.yml)
block vars (only for tasks in block)
task vars (only for the task)
role (and include_role) params
include params
include_vars
set_facts / registered vars
extra vars (always win precedence)

So is better to forget about using roles/vars because it takes precedence over host_vars, so I should use instead roles/defaults, which has a lower priority .

1
votes

This is as expected the main.yml will get sourced automatically while executing the playbook. consider this file as global variables.

The reason ansible2.yml is not getting sourced is because ansible expects you to source that explicitly while executing.

You can use below code for that(generic).

---
- name: play
  hosts: "{{ hosts }}"
  tasks:
    - include_vars: "{{ hosts }}.yml"

trigger -->

ansible-playbook -i inventory --extra-vars "hosts=ansible2"