Answers: <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>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-07T11:52:39.653Z
Answers: That's looks interesting, but `ifconfig` removed from CentOS. They offer to use `ip`. I'll try to adopt your solution.
Answers: Alexander Tolkachev
Answers: CC BY-SA 3.0
Answers: 2017-06-06T21:41:31.700Z
Answers: 2017-06-07T02:59:47.890Z
Answers: 2017-06-07T02:59:47.890Z
Answers: Peter Turner
Answers: <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>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-07T15:39:23.013Z
Answers: 2018-01-16T15:14:14.513Z
Answers: 2018-01-16T15:14:14.513Z
Answers: Alexander Tolkachev
Body: <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>
  
Tags: <ansible><linux>
Title: How to detect what interface has private IP in Ansible
UserDisplayName: Alexander Tolkachev
ThreadText: # 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
  
  username_1'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](https://github.com/ATolkachev/ansible/blob/master/library/get_ip_facts.py).
  
  
  ---
  
  ### 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<ifdesc>[a-zA-Z0-9]+):.+mtu\s+(?P<mtu>[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<ip>[0-9.]+)\s+netmask\s+(?P<netmask>[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<mac>[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.  
  
  ---
  
  