<p>I couldn't find it in Ansible, so I wrote something to help a couple of weeks ago:</p>

<pre><code>import fcntl
import json
import os
import platform
import subprocess
import socket
import struct
import re
from random import randint
import time
from ansible.module_utils.basic import *

def get_interface_info_for_ip(ip):

  ifconfig_process = subprocess.Popen(['/sbin/ifconfig'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  ifconfig_stdout_lines, ifconfig_stderr_lines = ifconfig_process.communicate()

  for ifconfig_stdout_line in ifconfig_stdout_lines.split('\n'):
    if 'mtu' in ifconfig_stdout_line.split():
      current_ifdesc = ''
      current_mtu = ''
      current_ip = ''
      current_netmask = ''
      current_mac = ''
      ifdesc_line_match = re.match(r'(?P&lt;ifdesc&gt;[a-zA-Z0-9]+):.+mtu\s+(?P&lt;mtu&gt;[0-9]+)', ifconfig_stdout_line )
      if ifdesc_line_match:
        current_ifdesc = ifdesc_line_match.groupdict()['ifdesc']
        current_mtu = ifdesc_line_match.groupdict()['mtu']

    if 'inet' in ifconfig_stdout_line.split():
      inet_line_match = re.match(r'\s+inet\s+(?P&lt;ip&gt;[0-9.]+)\s+netmask\s+(?P&lt;netmask&gt;[0-9.]+)', ifconfig_stdout_line)
      if inet_line_match:
         current_ip = inet_line_match.groupdict()['ip']
         current_netmask = inet_line_match.groupdict()['netmask']

    if 'ether' in ifconfig_stdout_line.split():
      ether_line_match = re.match(r'\s+ether\s+(?P&lt;mac&gt;[0-9a-f:]+)', ifconfig_stdout_line)
      if ether_line_match:
         current_mac = ether_line_match.groupdict()['mac']

    if current_ifdesc and current_mtu and current_ip and current_netmask and current_mac and current_ip == ip:
      return current_ifdesc, current_mtu, current_ip, current_netmask, current_mac

def main(argv=None):
    if argv is None:
      argv = sys.argv

    module = AnsibleModule(
        argument_spec = dict(
           silo_ip = dict(required=True),
        )
    )
    my_ip = module.params['ip']
    ifdesc, mtu, ip, netmask, mac = get_interface_info_for_ip(my_ip)

    module.exit_json(changed=True, ifdesc=ifdesc, ip=ip, mac=mac, netmask=netmask, mtu=mtu)

if __name__ == '__main__':
    main()
</code></pre>

<p>Call the file <code>get_ip_facts</code>, put it in your library path and call it with:</p>

<pre><code>name: get facts for ip address
get_ip_facts: ip={{ whatever_your_ip_is }}
</code></pre>

CC BY-SA 3.0
2017-06-07T11:52:39.653Z
That's looks interesting, but `ifconfig` removed from CentOS. They offer to use `ip`. I'll try to adopt your solution.
Alexander Tolkachev
CC BY-SA 3.0
2017-06-06T21:41:31.700Z
2017-06-07T02:59:47.890Z
2017-06-07T02:59:47.890Z
Peter Turner
<p>Peter's module not working in CentOS and I write my own module:</p>

<pre><code>#!/usr/bin/python
# encoding: utf-8

import subprocess
from ansible.module_utils.basic import *
from netaddr import IPNetwork

def get_priv_interface_info_for_ip(ip):
    network_config = subprocess.Popen(["/usr/sbin/ip", "-o", "addr", "show"], stdout=subprocess.PIPE)
    result = network_config.stdout.read()
    interface = ""
    network = ''
    ip_addr = ip
    for str in result.split("\n"):
        if 'inet ' in str:
            if ip in str:
                interface = str[3:str.find(" ", 3)]
                network = IPNetwork(str[str.find("net", 3) + 4:str.find("/", 3) + 3]).cidr

    return interface, ip_addr, network

def get_pub_interface_info_for_ip(ip):
    network_config = subprocess.Popen(["/usr/sbin/ip", "-o", "addr", "show"], stdout=subprocess.PIPE)
    result = network_config.stdout.read()
    interface = ''
    network = ''
    ip_addr = ''
    for str in result.split("\n"):
        if 'inet ' in str:
            if ip not in str and '127.0.0.1' not in str:
                print str
                interface = str[3:str.find(" ", 3)]
                network = IPNetwork(str[str.find("net", 3) + 4:str.find("/", 3) + 3]).cidr
                ip_addr = str[str.find("net", 3) + 4:str.find("/", 3)]

    return interface, ip_addr, network

def main(argv=None):
    if argv is None:
        argv = sys.argv

    fields = {"ip": {"required": True, "type": "str"}}
    module = AnsibleModule(argument_spec=fields)
    my_ip = module.params['ip']
    ifname_priv, ip_priv, network_priv = get_priv_interface_info_for_ip(my_ip)
    ifname_pub, ip_pub, network_pub = get_pub_interface_info_for_ip(my_ip)


    module.exit_json(changed=True, ifname_priv=ifname_priv, ip_priv=my_ip, network_priv=str(network_priv), ifname_pub=ifname_pub, ip_pub=ip_pub, network_pub=str(network_pub))


if __name__ == '__main__':
    main()
</code></pre>

<p>It works for servers with two network interfaces and provide information about public and private network interfaces.</p>

<p>Actual version of this module could be found in <a href="https://github.com/ATolkachev/ansible/blob/master/library/get_ip_facts.py" rel="nofollow noreferrer">my GitHub</a>.</p>

CC BY-SA 3.0
2017-06-07T15:39:23.013Z
2018-01-16T15:14:14.513Z
2018-01-16T15:14:14.513Z
Alexander Tolkachev
<p>I plan to reconfigure <code>iptables</code> on our servers (mostly CentOS 7, some CentOS 6) with different network configurations, some on 1Gbit interface, some on 10Gbit, some with VLANs and some with configured LACP.</p>

<p>I want to use Ansible, but couldn't find how to detect what inteface has private address. Private address we could get from inventory as <code>ansible_ssh_host</code>.</p>

<p>Is there any Ansible module that could help? Or I should write shell/Python script?</p>

<p>I checked all solutions on StackOverflow and ServerFault but haven't found anything.</p>

<ansible><linux>
How to detect what interface has private IP in Ansible
Alexander Tolkachev
# How to detect what interface has private IP in Ansible

(Asked by: username_0 on 2017-06-06)

I plan to reconfigure `iptables` on our servers (mostly CentOS 7, some CentOS 6) with different network configurations, some on 1Gbit interface, some on 10Gbit, some with VLANs and some with configured LACP.

I want to use Ansible, but couldn't find how to detect what inteface has private address. Private address we could get from inventory as `ansible_ssh_host`.

Is there any Ansible module that could help? Or I should write shell/Python script?

I checked all solutions on StackOverflow and ServerFault but haven't found anything.

**Tags:** ansible, linux


---

## 2 answers

### Answer by username_0 on 2017-06-07. Score: 4 | Accepted answer

Peter's module not working in CentOS and I write my own module:
#!/usr/bin/python
# encoding: utf-8

import subprocess
from ansible.module_utils.basic import *
from netaddr import IPNetwork

def get_priv_interface_info_for_ip(ip):
    network_config = subprocess.Popen(["/usr/sbin/ip", "-o", "addr", "show"], stdout=subprocess.PIPE)
    result = network_config.stdout.read()
    interface = ""
    network = ''
    ip_addr = ip
    for str in result.split("\n"):
        if 'inet ' in str:
            if ip in str:
                interface = str[3:str.find(" ", 3)]
                network = IPNetwork(str[str.find("net", 3) + 4:str.find("/", 3) + 3]).cidr

    return interface, ip_addr, network

def get_pub_interface_info_for_ip(ip):
    network_config = subprocess.Popen(["/usr/sbin/ip", "-o", "addr", "show"], stdout=subprocess.PIPE)
    result = network_config.stdout.read()
    interface = ''
    network = ''
    ip_addr = ''
    for str in result.split("\n"):
        if 'inet ' in str:
            if ip not in str and '127.0.0.1' not in str:
                print str
                interface = str[3:str.find(" ", 3)]
                network = IPNetwork(str[str.find("net", 3) + 4:str.find("/", 3) + 3]).cidr
                ip_addr = str[str.find("net", 3) + 4:str.find("/", 3)]

    return interface, ip_addr, network

def main(argv=None):
    if argv is None:
        argv = sys.argv

    fields = {"ip": {"required": True, "type": "str"}}
    module = AnsibleModule(argument_spec=fields)
    my_ip = module.params['ip']
    ifname_priv, ip_priv, network_priv = get_priv_interface_info_for_ip(my_ip)
    ifname_pub, ip_pub, network_pub = get_pub_interface_info_for_ip(my_ip)


    module.exit_json(changed=True, ifname_priv=ifname_priv, ip_priv=my_ip, network_priv=str(network_priv), ifname_pub=ifname_pub, ip_pub=ip_pub, network_pub=str(network_pub))


if __name__ == '__main__':
    main()

It works for servers with two network interfaces and provide information about public and private network interfaces.
Actual version of this module could be found in my GitHub.


---

### Answer by username_1 on 2017-06-06. Score: 2

I couldn't find it in Ansible, so I wrote something to help a couple of weeks ago:
import fcntl
import json
import os
import platform
import subprocess
import socket
import struct
import re
from random import randint
import time
from ansible.module_utils.basic import *

def get_interface_info_for_ip(ip):

  ifconfig_process = subprocess.Popen(['/sbin/ifconfig'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  ifconfig_stdout_lines, ifconfig_stderr_lines = ifconfig_process.communicate()

  for ifconfig_stdout_line in ifconfig_stdout_lines.split('\n'):
    if 'mtu' in ifconfig_stdout_line.split():
      current_ifdesc = ''
      current_mtu = ''
      current_ip = ''
      current_netmask = ''
      current_mac = ''
      ifdesc_line_match = re.match(r'(?P[a-zA-Z0-9]+):.+mtu\s+(?P[0-9]+)', ifconfig_stdout_line )
      if ifdesc_line_match:
        current_ifdesc = ifdesc_line_match.groupdict()['ifdesc']
        current_mtu = ifdesc_line_match.groupdict()['mtu']

    if 'inet' in ifconfig_stdout_line.split():
      inet_line_match = re.match(r'\s+inet\s+(?P[0-9.]+)\s+netmask\s+(?P[0-9.]+)', ifconfig_stdout_line)
      if inet_line_match:
         current_ip = inet_line_match.groupdict()['ip']
         current_netmask = inet_line_match.groupdict()['netmask']

    if 'ether' in ifconfig_stdout_line.split():
      ether_line_match = re.match(r'\s+ether\s+(?P[0-9a-f:]+)', ifconfig_stdout_line)
      if ether_line_match:
         current_mac = ether_line_match.groupdict()['mac']

    if current_ifdesc and current_mtu and current_ip and current_netmask and current_mac and current_ip == ip:
      return current_ifdesc, current_mtu, current_ip, current_netmask, current_mac

def main(argv=None):
    if argv is None:
      argv = sys.argv

    module = AnsibleModule(
        argument_spec = dict(
           silo_ip = dict(required=True),
        )
    )
    my_ip = module.params['ip']
    ifdesc, mtu, ip, netmask, mac = get_interface_info_for_ip(my_ip)

    module.exit_json(changed=True, ifdesc=ifdesc, ip=ip, mac=mac, netmask=netmask, mtu=mtu)

if __name__ == '__main__':
    main()

Call the file get_ip_facts, put it in your library path and call it with:
name: get facts for ip address
get_ip_facts: ip={{ whatever_your_ip_is }}

> **Comments:**
> **username_0**: That's looks interesting, but `ifconfig` removed from CentOS. They offer to use `ip`. I'll try to adopt your solution.  

---

