Consider a large inventory file full of hosts, some of them only have private IP addresses, but some of them have public IPs as well. The goal is to identify which hosts have a public IP and print it in a debug message.
The process involves running a playbook with a custom filter plugin to examine every host. If a public IP exists on a host, the print a debug message to identify the host.
Filter Plugin
Unfortunately, there’s no built-in way to filter public IP addresses in Ansible, because determining whether an IP address is public or private requires comparing it with various IP ranges, and Ansible facts don’t provide this functionality directly.
However, it’s possible to create a custom Ansible filter plugin to perform this task. Ansible filter plugins manipulate data inside the playbook during the run.
Here is the code for a plugin that filters out public IP addresses:
from ansible.errors import AnsibleFilterError
import ipaddress
def filter_public_ips(ip_list):
public_ips = []
for ip in ip_list:
try:
ip_obj = ipaddress.ip_address(ip)
if ip_obj.is_global:
public_ips.append(ip)
except ValueError as e:
raise AnsibleFilterError("Invalid IP address: {}: {}".format(ip, e))
return public_ips
class FilterModule(object):
def filters(self):
return {"filter_public_ips": filter_public_ips}
For the plugin to work, it needs to be placed in directory named filter_plugins
,
for example:
├── ansible.cfg
├── filter_plugins
│ └── ip_filter.py
├── inventory.yaml
└── site.yaml
Ansible Playbook
To use the filter plugin, the playbook will first read the
ansible_all_ipv4_addresses
variable to obtain all IP addresses
available on the host, and then apply the filter plugin on it:
---
- name: Get public IP
hosts: all
gather_facts: yes
tasks:
- name: Get public IP addresses.
set_fact:
public_ips: "{{ ansible_all_ipv4_addresses | filter_public_ips }}"
- name: Display public IP addresses.
debug:
msg: "{{ public_ips }}"
when: public_ips | length > 0
The playbook will print out all available public IP addresses during execution on the console output.