Use filters to inspect, validate, and manipulate variables containing networking information.
A number of filters and lookup plug-ins are available to collect and process network information for Ansible automation. These filters and plug-ins can be useful with fact gathering when you configure the network devices on your managed hosts.
The standard ansible.builtin.setup module, which automatically gathers facts at the start of many plays, collects a lot of network-related information from each managed host.
The ansible_facts['interfaces'] fact is a list of all the network interface names on the system.
You can use this list to examine the details of each of the network interfaces on the system.
For example, if enp11s0 is an interface on the system, then it has a fact called ansible_facts['enp11s0'], which is a dictionary containing information about the interface such as the MAC address, IPv4 and IPv6 addresses, kernel module, and so on.
The following facts are useful to remember:
Table 7.1. Selected Networking Facts
| Fact name | Description |
|---|---|
ansible_facts['dns']['nameservers']
| The DNS name servers used for name resolution by the managed host (included in the min subset). |
ansible_facts['domain']
| The domain for the managed host. |
ansible_facts['all_ipv4_addresses']
| All the IPv4 addresses configured on the managed host. |
ansible_facts['all_ipv6_addresses']
| All the IPv6 addresses configured on the managed host. |
ansible_facts['fqdn']
| The fully qualified domain name (DNS name) of the managed host. |
ansible_facts['hostname']
| The unqualified hostname; the string in the FQDN before the first period. |
The following playbook shows an example of using network facts:
---
- name: Set up web servers
hosts: web_servers
become: true
tasks:
- name: Configure web server status page
ansible.builtin.copy:
content: "Server: {{ ansible_facts['fqdn'] }} at {{ ansible_facts['default_ipv4']['address'] }}"
dest: /var/www/html/status.html
owner: apache
group: apache
mode: '0444'
- name: Ensure httpd is installed
ansible.builtin.yum:
name: httpd
state: installed
- name: Start and enable webserver
ansible.builtin.service:
name: httpd
state: started
enabled: true
- name: Notify root of server provisioning
community.general.mail:
subject: >
System {{ ansible_facts['hostname'] }} has
been successfully provisioned.You can validate and manipulate networking-related data stored in variables and facts with the ansible.utils.ipaddr filter.
The ansible.utils.ipaddr filter can validate the syntax of IP addresses, filter out bad data, convert from VLSM subnet masks to CIDR subnet prefix notation, perform subnet math, or find the next usable address in a network range.
Comprehensive documentation for this filter is available at "ipaddr filter", but this section explores some of its uses.
The ansible.utils.ipaddr filter needs the netaddr Python module, provided by the python3-netaddr package in Red Hat Enterprise Linux 8.
This Python module is installed by default in the ansible-automation-platform-22/ee-supported-rhel8 execution environment.
Ensure that the Python module is installed on your control node if you are using the ansible-playbook command, or if you are using the ansible-navigator command with the execution environment disabled.
In its simplest form, the ansible.utils.ipaddr filter with no arguments accepts a single value.
If the value is an IP address, then the filter returns the IP address.
If the value is not an IP address, then the filter returns false.
If the value is a list, then the filter returns the valid IP addresses but not the invalid ones. If all the items are invalid, then the filter returns an empty list.
{{ my_hosts_list | ansible.utils.ipaddr }}You can also pass arguments to the ansible.utils.ipaddr filter.
These arguments can make the filter return different information based on the data input.
The following subsections explore some options that you can use with the ansible.utils.ipaddr filter.
To better understand how they work, each of the following examples shows the output that results when that filter is used with a variation on the following task:
- name: Filter example
ansible.builtin.debug:
msg: "{{ listips | ansible.utils.ipaddr }}"The ipaddr filter in the msg line is replaced with a version that uses the appropriate option.
For example, the following version of the line retrieves the network masks of the given addresses.
msg: "{{ listips | ansible.utils.ipaddr('netmask') }}"The listips variable used to generate the examples contains the following list:
listips:
- 192.168.2.1
- 10.0.0.128/25
- 172.24.10.0/255.255.255.0
- 172.24.10.0/255.255.255.255
- ff02::1
- ::1
- 2001::1/64
- 2001::/64
- learn.spidernet.plhost
Outputs only valid individual IP addresses, in the correct CIDR prefix format for host addresses.
"msg": [
"192.168.2.1/32",
"172.24.11.0/32",
"ff02::1/128",
"::1/128",
"2001::1/64"
]net
Filters out values that are not valid network specifications, converting the netmask into a CIDR prefix if necessary.
"msg": [
"10.0.0.128/25",
"172.24.10.0/24",
"2001::/64"
]private
Displays input IP addresses or network ranges that are in ranges reserved by IANA to be private. This includes RFC 1918 address spaces and IPv6 site-local addresses at a minimum.
"msg": [
"192.168.2.1",
"10.0.0.128/25",
"172.24.10.0/255.255.255.0",
"172.24.10.0/255.255.255.255"
]public
Outputs addresses and networks in public (globally routable) address spaces, according to IANA. (This example has no IPv4 addresses in the public space.)
"msg": [
"2001::1/64",
"2001::/64"
]The ansible.utils.ipwrap filter puts brackets around the address part of items that appear to be IPv6 addresses.
The filter passes all other values unchanged.
This is useful in templates for certain configuration files that expect this syntax for IPv6 addresses.
"msg": [
"192.168.2.1",
"10.0.0.128/25",
"172.24.10.0/255.255.255.0",
"172.24.10.0/255.255.255.255",
"[ff02::1]",
"[::1]",
"[2001::1]/64",
"[2001::]/64",
"learn.spidernet.pl"
]Most of the filters in the preceding examples remove the learn.spidernet.pl list item, which is not an IP address.
The ansible.utils.ipwrap filter does not do this, but you could use the ansible.utils.ipaddr filter first to handle this scenario:
"{{ listips | ansible.utils.ipaddr | ansible.utils.ipwrap }}"You can use a number of the ansible.utils.ipaddr options to format networking data from an IPv4 or IPv6 address.
For example:
To return the address part, 192.0.2.1:
"{{ '192.0.2.1/24' | ansible.utils.ipaddr('address') }}"To return the variable-length subnet mask, 255.255.255.0:
"{{ '192.0.2.1/24' | ansible.utils.ipaddr('netmask') }}"To return the CIDR prefix, 24:
"{{ '192.0.2.1/24' | ansible.utils.ipaddr('prefix') }}"To return the network's broadcast address, 192.0.2.255:
"{{ '192.0.2.1/24' | ansible.utils.ipaddr('broadcast') }}"To return the network's network address, 192.0.2.0:
"{{ '192.0.2.1/24' | ansible.utils.ipaddr('network') }}"To return the IP address in DNS PTR record format, 1.2.0.192.in-addr.arpa.:
"{{ '192.0.2.1/24' | ansible.utils.ipaddr('revdns') }}"This correctly converts IPv6 addresses as well.
If you pass a list of items to ansible.utils.ipaddr, it attempts to convert the items that appear to be valid addresses and filter out items that are not.
The broadcast option should not be used with an IPv6 address/prefix because that protocol does not assign a broadcast address.
Other options should work with IPv6 addresses as expected.
You can display an IP address on a given network by passing an integer to the ansible.utils.ipaddr filter.
The following returns the fifth address (192.0.2.5/24) on the 192.0.2.0/24 network.
"{{ '192.0.2.0/24' | ansible.utils.ipaddr(5) }}"You can convert the network specification to a range of usable addresses for hosts with the range_usable option.
The following example returns the 192.0.2.1-192.0.2.254 address range:
"{{ '192.0.2.0/24' | ansible.utils.ipaddr('range_usable') }}"If you pass a network specification to the ansible.utils.network_in_usable filter, you can specify a particular address as an option to determine if that address is usable for hosts on that network (meaning, the address is not reserved for broadcasts or other uses).
The following example returns the Boolean value true:
"{{ '192.0.2.0/24' | ansible.utils.network_in_usable('192.0.2.5') }}"If you replace 192.0.2.5 with 192.0.2.255 (the reserved broadcast address) or 192.0.3.2 (not on the network), it returns the Boolean value false.
You can also find the next host on a network.
The following example returns the 192.0.2.6/24 address:
"{{ '192.0.2.5/24' | ansible.utils.ipaddr('next_usable') }}"When the end of the network is reached, it returns an empty value.
Network administrators can use the ansible.utils.cidr_merge filter to aggregate a list of subnets and individual hosts into the minimal representation.
For example, consider the following list:
mynetworks:
- 10.0.1.0/24
- 10.0.2.0/24
- 10.0.3.0/24
- 10.0.100.0/24
- 2001:db8::/64
- 2001:db8:0:1::/64You can use the "{{ mynetworks | ansible.utils.cidr_merge }}" expression to return the following list:
"msg": [
"10.0.1.0/24",
"10.0.2.0/23",
"10.0.100.0/24",
"2001:db8::/63"
]More filters, as well as more options for the preceding filters, are available in the ansible.utils collection.
Find more information about using these filters in the References note at the end of this section.