can't access to existing "ansible_eth1" fact

Hi,

I successfully managed to add a private IP address on my servers. I
can see both network interfaces eth0 and eth1 when I ask for the facts
of this server (I stuggled to death to find this command) :

$ ansible server -m setup -i production
        "ansible_eth0": {
            "active": true,
            "device": "eth0",
            "ipv4": {
                "address": "x.x.x.x",
                "netmask": "x.x.x.x",
                "network": "x.x.x.x"
            },
            "ipv6": [
                {
                    "address": "x::x:x:x:x",
                    "prefix": "64",
                    "scope": "link"
                }
            ],
            "macaddress": "x:x:x:x:x:x",
            "module": "e1000e",
            "mtu": 1500,
            "type": "ether"
        },
        "ansible_eth1": {
            "active": true,
            "device": "eth1",
            "ipv4": {
                "address": "x.x.x.x",
                "netmask": "x.x.x.x",
                "network": "x.x.x.x"
            },
            "ipv6": [
                {
                    "address": "x::x:x:x:x",
                    "prefix": "64",
                    "scope": "link"
                }
            ],
            "macaddress": "x:x:x:x:x:x",
            "module": "e1000e",
            "mtu": 9000,
            "type": "ether"
        },

But when I want to access the "ansible_eth1" fact from my playbook :
# dest file is /etc/hosts
# locally resolve private IPs
{% for host in groups['all'] %}
{{ hostvars[host]['ansible_eth1']['ipv4']['address'] }} {{ host }}
{% endfor %}

I get the following error on every single server :
fatal: [server] => {'msg': "One or more undefined variables: 'dict
object' has no attribute 'ipv4'", 'failed': True}

This kind of code worked really good with eth0 ,as you can see in my
fully working iptables template extract :
{% for host in groups['all'] %}
# access from {{ host }}
- -A INPUT -p tcp -m tcp -s {{
hostvars[host]['ansible_eth0']['ipv4']['address'] }} --dport {{
some_port }} -j ACCEPT
{% endfor %}

What am I doing wrong ?
How can I debug this ? I thought "ansible server -m setup -i
production" would provide me the correct information, but I was wrong.

Thanks.
- --
Jean-Philippe Caruana

To gather more information, I decided to print the content of the
'ansible_eth1' key inside my generated hosts file... I don't know if
there is a more straightforward way to enter in debugging mode, still
I found interesting data.

I replaced
{{ hostvars[host]['ansible_eth1']['ipv4']['address'] }} {{ host }}
with
{{ hostvars[host]['ansible_eth1'] }} {{ host }}
in my template

and got this (formatted for your eyes) dict, the content of the
'ansible_eth1' key :
{
    'macaddress': 'x:x:x:x:x:x',
    'module': 'tg3',
    'mt': 9000,
    'device': 'eth1',
    'ipv4': {
        'netmask': 'x.x.x.x',
        'network': 'x.x.x.x',
        'address': 'x.x.x.x'
    },
    'ipv6': [
        {
            'scope': 'link',
            'prefix': '64',
            'address': 'x::x:x:x:x'
        }
    ],
    'active': True,
    'type': 'ether'
}

There is a 'ipv4' key and inside this there is a 'address' key !

Informations are exactly the same with "ansible server -m setup" (cf
my previous post), so I'm satisfied.
I have as many lines in the generated file as my servers in my
inventory, so I'm satisfied again.

So why can't I access to ansible_eth1.ipv4 from my template ?

Thanks for your input.
- --
Jean-Philippe Caruana

Le 06/11/2013 18:17, Jean-Philippe Caruana a �crit :

So why can't I access to ansible_eth1.ipv4 from my template ?

It seems to be quite a tough matter, so I opened an issue for this :
https://github.com/ansible/ansible/issues/4848

- --
Jean-Philippe Caruana

Have you narrowed this down by using --limit to exactly one host and made sure there is an ipv4 address for that host?

I’m guessing one host might not have an ipv4 address for that interface.

Hi,

Le 10/11/2013 22:32, Michael DeHaan a �crit :

Have you narrowed this down by using --limit to exactly one host and
made sure there is an ipv4 address for that host?

I'm guessing one host might not have an ipv4 address for that interface.

I tested on a single server, I have the fact ansible_eth1 with
ipv4.address and then I had the error when executing the playbook (see
my first email).
I used "ansible myserver.com -m setup -i inventory". Is it the same
effect as --limit ?

As seen in my debug test (printing {{ hostvars[host]['ansible_eth1'] }}
on every host) gave me the following dict for every server (I masually
checked, since I just have 8 servers for now) :

{
    'macaddress': 'x:x:x:x:x:x',
    'module': 'tg3',
    'mt': 9000,
    'device': 'eth1',
    'ipv4': {
        'netmask': 'x.x.x.x',
        'network': 'x.x.x.x',
        'address': 'x.x.x.x' # <- here :slight_smile:
    },
    'ipv6': [
        {
            'scope': 'link',
            'prefix': '64',
            'address': 'x::x:x:x:x'
        }
    ],
    'active': True,
    'type': 'ether'
}

When I ask for facts for one server, there is an ipv4 address on eth1.
I checked, and all my servers do have an ipv4 address on eth1, either
with ifconfig or with ansible facts.

I am getting the exact same issue as OP. I cloned the official ansible-examples and am trying to deploy the hadoop example. I get part the way through and then get the error:

TASK: [common | Create the hosts file for all machines] ***********************
fatal: [hadoop1] => {‘msg’: “One or more undefined variables: ‘dict object’ has no attribute u’ansible_eth0’”, ‘failed’: True}
fatal: [hadoop1] => {‘msg’: “One or more undefined variables: ‘dict object’ has no attribute u’ansible_eth0’”, ‘failed’: True}
fatal: [hadoop2] => {‘msg’: “One or more undefined variables: ‘dict object’ has no attribute u’ansible_eth0’”, ‘failed’: True}
fatal: [hadoop2] => {‘msg’: “One or more undefined variables: ‘dict object’ has no attribute u’ansible_eth0’”, ‘failed’: True}
fatal: [hadoop3] => {‘msg’: “One or more undefined variables: ‘dict object’ has no attribute u’ansible_eth0’”, ‘failed’: True}
fatal: [hadoop3] => {‘msg’: “One or more undefined variables: ‘dict object’ has no attribute u’ansible_eth0’”, ‘failed’: True}

When I do ansible -m setup all, I can see that ansible_eth0 exists and has a dict of data, including the address from hosts.j2. Any clue what is happening there?

For reference, here is my modified hosts file (as maybe there’s something wrong here?)

hadoop_master_primary ansible_ssh_host=centos6-hadoop01
hadoop_master_secondary ansible_ssh_host=centos6-hadoop02
hadoop1 ansible_ssh_host=centos6-hadoop03
hadoop2 ansible_ssh_host=centos6-hadoop04
hadoop3 ansible_ssh_host=centos6-hadoop05

[hadoop_all:children]
hadoop_masters
hadoop_slaves
qjournal_servers
zookeeper_servers

[hadoop_all:vars]
ansible_ssh_user=root

[hadoop_master_primary]
hadoop1

[hadoop_master_secondary]
hadoop2

[hadoop_masters:children]
hadoop_master_primary
hadoop_master_secondary

[hadoop_slaves]
hadoop1
hadoop2
hadoop3

[qjournal_servers]
hadoop1
hadoop2
hadoop3

[zookeeper_servers]
hadoop1 zoo_id=1
hadoop2 zoo_id=2
hadoop3 zoo_id=3

I am feeling less alone now...

I haven't tested it since newer releases of ansible went out : what is
your ansible version ?

Hi,

I am resurrecting this old message (of mine) : the issue https://github.com/ansible/ansible/issues/4848 has been closed as “you can’t do jinja2”, but I think this is an issue in gathering ansible_eth1 fact

any idea ?

Thanks

ansible server -m setup -i production, should provide you the correct info.

I suspect one of your hosts does not have an ipv4 address assigned to eth1.

Thanks, this is helpful.
As a matter of fact, one of my servers don’t have an ipv4 address assign to eth1, but does have an ansible_eth1 fact:

“ansible_eth1”: {
“active”: false,
“device”: “eth1”,

},

I think I can use the active flag to prevent my template from crashing for this server:

{% for host in groups[‘all’] %}
{% if hostvars[host][‘ansible_eth1’][‘active’] %}
{{ hostvars[host][‘ansible_eth1’][‘ipv4’][‘address’] }} {{ host }}
{% endif %}
{% endfor %}