Search code examples
ip-addressansiblehostnameinventory

Ansible - Zabbix - Inventory host hostname ipaddress - error


Ansible 1.9.2 / 1.9.4

CentOS 6.7

I'm trying to find the IP address of a given hostname which is stored in the inventory file. If you see the my playbook, I got the IP of the hostname which I'm trying to find (see the first -debug section) but that's when I used "with_items" and passed "{{ groups['zabbix_server'] }}" as an item.

But now I'm trying to find the IP without using the hostname[item].... way i.e. directly using groups['zabbix_server'] way. How can I get the IP address of the host which is listed in hosts inventory file under zabbix_server directly? i.e. without using "with_items" line/feature in Ansible.

What I'm missing here to get these errors. I tried some online similar blogs/posts but those didn't help. Using [].[] or ['something].['somethingelse'] way didn't help either and for that I get:

Failed to template msg="IP is= {{ hostvars[groups['zabbix_server']].[ansible_default_ipv4.address] }}": template error while templating string: expected name or number

or If I use this way:

IP is= {{ hostvars[groups['zabbix_server']]['ansible_default_ipv4']['address'] }}"

I get this error:

... => One or more undefined variables: 'HostVars' object has no element ['zabbix.dev-white.projectname.jenkins]

Inventory file hosts contains:

[zabbix_server]
zabbix.dev-white.projectname.jenkins

My playbook file contains:

- debug: msg="Zabbix server= {{ item }} and its IP is= {{ hostvars[item].ansible_default_ipv4.address }}"
  with_items:
    - "{{ groups['zabbix_server'] }}"
  tags:
    - lilupandut

- debug: msg="Zabbix server= {{ item }} and its IP is= {{ hostvars[groups['zabbix_server']][ansible_default_ipv4.address] }}"
  with_items:
    - "{{ groups['zabbix_server'] }}"
  tags:
    - lilupandut

#- debug: msg="Zabbix server= {{ item }} and its IP is= {{ groups['zabbix_server'][ansible_default_ipv4.address] }}"
#  with_items:
#    - "{{ groups['zabbix_server'] }}"
#  tags:
#    - lilupandut

If I run the above playbook, I get the following output (valid output from the first -debug section) and an error (for the 2nd -debug section where I'm trying to use direct way of getting to the IP address i.e. not using hostvars[item]).

$ ansible-playbook zabbix-setup.yml -i hosts -u koba --private-key ${DEPLOYER_KEY_FILE} -t lilupandut

PLAY [zabbix_server] **********************************************************

GATHERING FACTS ***************************************************************
ok: [zabbix.dev-white.projectname.jenkins]

TASK: [zabbix_install | debug msg="Zabbix server= {{ item }} and its IP is= {{ hostvars[item].ansible_default_ipv4.address }}"] ***
ok: [zabbix.dev-white.projectname.jenkins] => (item=zabbix.dev-white.projectname.jenkins) => {
    "item": "zabbix.dev-white.projectname.jenkins",
    "msg": "Zabbix server= zabbix.dev-white.projectname.jenkins and its IP is= 10.130.64.18"
}

TASK: [zabbix_install | debug msg="Zabbix server= {{ item }} and its IP is= {{ groups['zabbix_server'][ansible_default_ipv4.address] }}"] ***
fatal: [zabbix.dev-white.projectname.jenkins] => One or more undefined variables: 'HostVars' object has no element [zabbix.dev-white.projectname.jenkins]

FATAL: all hosts have already failed -- aborting

If I comment out the middle -debug section and un-comment the last -debug statement, then I get close to what I'm looking for "IP address" but it still error out.

This time the error / output comes as:

projectname: [zabbix_install | debug msg="Zabbix server= {{ item }} and its IP is= {{ groups['zabbix_server'][ansible_default_ipv4.address] }}"] ***
fatal: [zabbix.dev-white.projectname.jenkins] => One or more undefined variables: 'list' object has no attribute '10.130.64.18'

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/confman/zabbix-setup.retry

zabbix.dev-white.projectname.jenkins : ok=2    changed=0    unreachable=1    failed=0

Solution

  • It's not clear to my why you do not want to use the item of the list you use. All your examples have the with_items loop, so you also can use item in all examples-

    Let's have a look at this task of yours:

    - debug: msg="Zabbix server= {{ item }} and its IP is= {{ hostvars[groups['zabbix_server']][ansible_default_ipv4.address] }}"
      with_items:
        - "{{ groups['zabbix_server'] }}"
      tags:
        - lilupandut
    

    So you're looping over groups['zabbix_server'] which is a list of hosts. item then would refer to each item of that list. What is the point of not using item in this case then, where you're looping over a list?

    In your task then you attempt to use hostvars[groups['zabbix_server']][ansible_default_ipv4.address]. hostvars is a hash, groups['zabbix_server'] is a list. You can not use a list as an hash key and that is why you get an error like this:

    I get this error: ... => One or more undefined variables: 'HostVars' object has no element ['zabbix.dev-white.projectname.jenkins]

    As the error message attempts to explain, it is trying to look up a hash element with the key ['zabbix.dev-white.projectname.jenkins'].

    So as said, it's not really clear to me what you try to archive. Using item would be the way to get to the correct element of the loop.

    hostvars[item]
    

    Because item holds the value zabbix.dev-white.projectname.jenkins.

    If you'd have no loop involved at all you could use the first host of the zabbix_server group like this:

    hostvars[groups['zabbix_server'][0]]
    

    In words again: groups['zabbix_server'] is a list [0] accesses the first item of that list. But if you're in a loop anyway, there is actually no point in doing this.

    hostvars[groups['zabbix_server'][0]]['ansible_default_ipv4']['address']
    

    is the same as

    hostvars[item]['ansible_default_ipv4']['address']