Ansible - read inventory hosts and variables to gr

2019-01-31 21:09发布

问题:

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.

回答1:

- 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.



回答2:

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 }}"


回答3:

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'] }}"


回答4:

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!



回答5:

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"


回答6:

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