30

I have a dummy doubt that keeps me stuck for a long time. I have a very banal inventory file with hosts and variables:

[lb]
10.112.84.122

[tomcat]
10.112.84.124

[jboss5]
10.112.84.122

...

[tests:children]
lb
tomcat
jboss5

[default:children]
tests

[tests:vars]
data_base_user=NETWIN-4.3
data_base_password=NETWIN
data_base_encrypted_password=
data_base_host=10.112.69.48
data_base_port=1521
data_base_service=ssdenwdb
data_base_url=jdbc:oracle:thin:@10.112.69.48:1521/ssdenwdb

The problem is that I need to access all these hosts and variables, in the inventory file, from the group_vars/all file.

I've tried the following manners to access the host IP:

{{ lb }}
"{{ hostvars[lb] }}"
"{{ hostvars['lb'] }}"
{{ hostvars[lb] }}

To access a host variable I tried:

"{{ hostvars[tests].['data_base_host'] }}"

All of them are wrong!!! Can anyone help me find out the best practice to access hosts and variables, not from a playbook but from a variables file?

EDIT:

Ok. Let's clarify.

Problem: Use a host declared in the inventory file in a variable file, let's say: group_vars/all.

Example: I have a DB host with IP:10.112.83.37.

Inventory file:

[db]
10.112.83.37

In the group:vars/all file I want to use that IP to build a variable.

group_vars/all file:

data_base_url=jdbc:oracle:thin:@{{ db }}:1521/ssdenwdb

In a template I use the variable built in the group_vars/all file.

Template file:

oracle_url = {{ data_base_url }}

The problem is that the {{ db }} variable in the group_vars/all file is not replaced by the DB host IP. The user can only edit the inventory file.

freginold
  • 3,946
  • 3
  • 13
  • 28
Tiago Sousa
  • 301
  • 1
  • 3
  • 5
  • I don't think you can. Variables can be accessed from actions and templates. I suppose you generate some config files from those variables ? So the place to take advantage of them is in templates. Can you elaborate on why you need to "access" them from group_vars.all ? – leucos Feb 20 '14 at 13:24
  • Thanks for your reply. Ok, i want to have a central file where i put all the variables i need. The inventory file only contains the hosts IP, all the rest are in the group_vars.all file. But some of these variables (in the group_vars.all file) contain the IP of some host and that's why i need to access the host' IP in the inventory file. – Tiago Sousa Feb 20 '14 at 14:08
  • Just to complete the explanation, my goal is to enable any user, that wants to configure the system, to only add the hosts IPs in the inventory file. All the rest, namely all the other variables, are built in the group_vars.all file. Thanks. – Tiago Sousa Feb 20 '14 at 14:21

7 Answers7

31
- name: host
   debug: msg="{{ item }}" 
   with_items:
    - "{{ groups['tests'] }}"

This piece of code will give the message:

'10.112.84.122'
'10.112.84.124'

as groups['tests'] basically return a list of unique ip addresses ['10.112.84.122','10.112.84.124'] whereas groups['tomcat'][0] returns 10.112.84.124.

kunicmarko20
  • 2,095
  • 2
  • 15
  • 25
eldos
  • 3,132
  • 3
  • 29
  • 32
21

If you want to programmatically access the inventory entries to include them in a task for example. You can refer to it like this:

{{ hostvars.tomcat }}

This returns you a structure with all variables related with that host. If you want just an IP address (or hostname), you can refer to it like this:

{{ hostvars.jboss5.ansible_ssh_host }}

Here is a list of variables which you can refer to: click. Moreover, you can declare a variable and set it with for example result of some step in a playbook.

- name: Change owner and group of some file
  file: path=/tmp/my-file owner=new-owner group=new-group
  register: chown_result

Then if you play this step on tomcat, you can access it from jboss5 like this:

- name: Print out the result of chown
  debug: msg="{{ hostvars.tomcat.chown_result }}"
wpodgorski
  • 785
  • 9
  • 12
  • Above didn't work for me. i had to use `{{ groups['database'][0] }}` to get first IP address of database hosts group. – syodage Aug 18 '16 at 21:06
  • 2
    In newer ansible versions (2.x IIRC) it's just called `ansible_host` instead of `ansible_ssh_host`. – sjas May 04 '17 at 08:12
17

Just in case if the problem is still there, You can refer to ansible inventory through ‘hostvars’, ‘group_names’, and ‘groups’ ansible variables.

Example:

To be able to get ip addresses of all servers within group "mygroup", use the below construction:

- debug: msg="{{ hostvars[item]['ansible_eth0']['ipv4']['address'] }}" 
  with_items:
     - "{{ groups['mygroup'] }}"
slm
  • 15,396
  • 12
  • 109
  • 124
odzhu
  • 173
  • 1
  • 7
3

Considering your previous example:

inventory file:

[db]
10.112.83.37

group_vars/all

data_base_url=jdbc:oracle:thin:@{{ db }}:1521/ssdenwdb

template file:

oracle_url = {{ data_base_url }}

You might want to replace your group_vars/all with

data_base_url="jdbc:oracle:thin:@{{ groups['db'][0] }}:1521/ssdenwdb"
3

Yes the example by nixlike works very well.

Inventory:

[docker-host]
myhost1 user=barbara
myhost2 user=heather

playbook:

---

- hosts: localhost
  connection: local         

     tasks:    
        - name: loop debug inventory hostnames
          debug: 
            msg: "the docker host is {{ item }}"
          with_inventory_hostnames: docker-host
        - name: loop debug items
          debug: 
            msg: "the docker host is {{ hostvars[item]['user'] }}"
          with_items: "{{ groups['docker-host'] }}"

output:

ansible-playbook ansible/tests/vars-test-local.yml

PLAY [localhost]


TASK [setup] ******************************************************************* ok: [localhost]

TASK [loop debug inventory hostnames] ****************************************** ok: [localhost] => (item=myhost2) => { "item": "myhost2", "msg": "the docker host is myhost2" } ok: [localhost] => (item=myhost1) => { "item": "myhost1", "msg": "the docker host is myhost1" }

TASK [loop debug items] ******************************************************** ok: [localhost] => (item=myhost1) => { "item": "myhost1", "msg": "the docker host is barbara" } ok: [localhost] => (item=myhost2) => { "item": "myhost2", "msg": "the docker host is heather" }

PLAY RECAP ********************************************************************* localhost : ok=3 changed=0 unreachable=0
failed=0

thanks!

nettie
  • 628
  • 1
  • 11
  • 23
0

If you want to refer one host define under /etc/ansible/host in a task or role, the bellow link might help:

https://www.middlewareinventory.com/blog/ansible-get-ip-address/

onlyme
  • 3,776
  • 2
  • 23
  • 17
-1

If you want to have your vars in files under group_vars, just move them here. Vars can be in the inventory ([group:vars] section) but also (and foremost) in files under group_vars or hosts_vars.

For instance, with your example above, you can move your vars for group tests in the file group_vars/tests :

Inventory file :

[lb]
10.112.84.122

[tomcat]
10.112.84.124

[jboss5]
10.112.84.122

...

[tests:children]
lb
tomcat
jboss5

[default:children]
tests

group_vars/tests file :

data_base_user=NETWIN-4.3
data_base_password=NETWIN
data_base_encrypted_password=
data_base_host=10.112.69.48
data_base_port=1521
data_base_service=ssdenwdb
data_base_url=jdbc:oracle:thin:@10.112.69.48:1521/ssdenwdb
slm
  • 15,396
  • 12
  • 109
  • 124
leucos
  • 17,661
  • 1
  • 44
  • 34
  • Thanks for your reply. The problem with that approach is that i need to edit both files (inventory and group vars) when i want to change, for example, the IP of a host (remember that a have variables in the group vars that contains the IP of a host). One requirement that i have is that a user only has to edit the inventory file (adding the hosts IPs) to reconfigure the system or to install in other environment. – Tiago Sousa Feb 20 '14 at 15:01
  • Mmhh, okay, but the inventory file showned in your question already solves this, and don't see anything in tests:vars that uses information from above, so I'm having hard time figuring out what problem needs to be solved, sorry :( Could you write what you want in the end (even if it doesn't work), including an inventory file, a group_vars/all file an a small playbook (an action, a template) ? – leucos Feb 20 '14 at 15:41
  • inventory file: [db] 10.112.83.37 group_vars/all data_base_url=jdbc:oracle:thin:@{{ db }}:1521/ssdenwdb playbook: {{ data_base_url }} This is a very basic example but shows the need to use an inventory host in a variable in the group_vars/all. – Tiago Sousa Feb 20 '14 at 16:29
  • And users can only change inventory, not group_vars, right ? – leucos Feb 20 '14 at 16:35
  • And you will use these variables where ? Template ? Actions ? – leucos Feb 20 '14 at 16:58
  • Mostly in templates but also in actions. – Tiago Sousa Feb 20 '14 at 17:43
  • I started editing my first answer, but the more I write, the less I understand your problem. I just don't see the issue. You have vars, you just use them in templates. Period. I suggest you rework your question saying explicitely what you want to achieve, showing an small , eventually fake but consistent example of inventory + group_vars/all + template you'd like to have and explaining who can change what. Then I'd be glad to reply. Until then, I just can't. Whatever you want, it is feasible. I've never been stuck with ansible. The problem is really about explaining what you want in the end. – leucos Feb 20 '14 at 20:20
  • I was trying this. But variables not reading from group_vars/tests file... – PRIHLOP Feb 16 '17 at 12:19