Bookmark this page

Guided Exercise: Using Filters to Work with Network Addresses

  • Use filters and plug-ins to manipulate and validate data stored in variables that contain networking-related information.

Outcomes

  • Use the ansible.utils.ipaddr filter to derive networking information from IP address data retrieved from gathered facts.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

This command prepares an Ansible project in the /home/student/data-netfilters/ directory on the workstation machine.

[student@workstation ~]$ lab start data-netfilters

Procedure 7.4. Instructions

  1. The lab command provides the /home/student/data-netfilters/default_ipv4.yml playbook. Change to the ~/data-netfilters directory and review the default_ipv4.yml playbook.

    [student@workstation ~]$ cd ~/data-netfilters/
    [student@workstation data-netfilters]$ cat default_ipv4.yml
    - name: Display the default ipv4 address facts
      hosts: servera.lab.example.com
      become: false
    
      tasks:
        - name: Print the default ipv4 address facts
          ansible.builtin.debug:
            msg: "{{ ansible_default_ipv4 }}"
    1. Run the ~/data-netfilters/default_ipv4.yml playbook to list the ansible_default_ipv4 facts.

      [student@workstation data-netfilters]$ ansible-navigator run \
      > -m stdout default_ipv4.yml
      
      PLAY [Display the default ipv4 address facts] **********************************
      
      TASK [Gathering Facts] *********************************************************
      ok: [servera.lab.example.com]
      
      TASK [Print the default ipv4 address facts] ************************************
      ok: [servera.lab.example.com] => {
          "msg": {
              "address": "172.25.250.10",
              "alias": "eth0",
              "broadcast": "172.25.250.255",
              "gateway": "172.25.250.254",
              "interface": "eth0",
              "macaddress": "52:54:00:00:fa:0a",
              "mtu": 1500,
              "netmask": "255.255.255.0",
              "network": "172.25.250.0",
              "prefix": "24",
              "type": "ether"
          }
      }
      
      PLAY RECAP *********************************************************************
      servera.lab.example.com    : ok=2    changed=0    unreachable=0    failed=0  ...
  2. The ~/data-netfilters/filtering_data.yml file contains incomplete tasks that use the ansible.utils.ipaddr filter with various options. Edit the ~/data-netfilters/filtering_data.yml file, replacing any occurrence of #FIXME# in a fact definition with the expected value, as shown in the following substeps.

    The listips variable that is 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.pl
    1. Review the first example, which uses ansible.utils.ipaddr without any options to output the items in the list that are valid IP addresses or networks. You do not need to change anything in that task.

      - name: 1) Display all addresses
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipaddr }}"
    2. Use the host option with the ansible.utils.ipaddr filter to output only valid individual IP addresses, in the correct CIDR prefix format for host addresses.

      - name: 2) Use host
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipaddr('host') }}"
    3. Use the net option to output only values that are valid network specifications, converting the netmask to CIDR prefix format if necessary.

      - name: 3) Use net
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipaddr('net') }}"
    4. Use the private option to output only IP addresses or network ranges that are reserved by IANA to be private.

      - name: 4) Use private
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipaddr('private') }}"
    5. Use the public option to output only IP addresses and networks in globally routable public address spaces, according to IANA.

      - name: 5) Use public
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipaddr('public') }}"
    6. Use the ansible.utils.ipwrap filter to put brackets around the address part of IPv6 addresses.

      - name: 6) Use ipwrap
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipwrap }}"
    7. Most of the filters in the preceding examples removed the learn.spidernet.pl list item, which is not an IP address, except for the ansible.utils.ipwrap filter. The following example uses the ansible.utils.ipaddr filter, followed by the ansible.utils.ipwrap filter, to exclude the learn.spidernet.pl list item.

      - name: 7) Use ipaddr and ipwrap
        ansible.builtin.debug:
          msg: "{{ listips | ansible.utils.ipaddr | ansible.utils.ipwrap }}"
    8. Verify that the completed filtering_data.yml playbook should consist of the following content:

      # Complete each task by setting the fact as the expected value.
      # Replace FIXME by the appropriate filter usage.
      
      - name: First play for netfilter exercise
        hosts: servera.lab.example.com
        become: false
        vars:
          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.pl
      
        tasks:
          - name: 1) Display all addresses
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipaddr }}"
      
          - name: 2) Use host
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipaddr('host') }}"
      
          - name: 3) Use net
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipaddr('net') }}"
      
          - name: 4) Use private
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipaddr('private') }}"
      
          - name: 5) Use public
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipaddr('public') }}"
      
          - name: 6) Use ipwrap
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipwrap }}"
      
          - name: 7) Use ipaddr and ipwrap
            ansible.builtin.debug:
              msg: "{{ listips | ansible.utils.ipaddr | ansible.utils.ipwrap }}"
    9. Run the filtering_data.yml playbook and verify the output of each task.

      [student@workstation data-netfilters]$ ansible-navigator run \
      > -m stdout filtering_data.yml
      
      PLAY [First play for netfilter exercise] ***************************************
      
      TASK [Gathering Facts] *********************************************************
      ok: [servera.lab.example.com]
      
      TASK [1) Display all addresses] ************************************************
      ok: [servera.lab.example.com] => {
          "msg": [
              "192.168.2.1",
              "10.0.0.128/25",
              "172.24.10.0/24",
              "172.24.10.0/32",
              "ff02::1",
              "::1",
              "2001::1/64",
              "2001::/64"
          ]
      }
      
      TASK [2) Use host] *************************************************************
      ok: [servera.lab.example.com] => {
          "msg": [
              "192.168.2.1/32",
              "172.24.10.0/32",
              "ff02::1/128",
              "::1/128",
              "2001::1/64"
          ]
      }
      
      TASK [3) Use net] **************************************************************
      ok: [servera.lab.example.com] => {
          "msg": [
              "10.0.0.128/25",
              "172.24.10.0/24",
              "2001::/64"
          ]
      }
      
      TASK [4) Use private] **********************************************************
      ok: [servera.lab.example.com] => {
          "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"
          ]
      }
      
      TASK [5) Use public] ***********************************************************
      ok: [servera.lab.example.com] => {
          "msg": [
              "2001::1/64",
              "2001::/64"
          ]
      }
      
      TASK [6) Use ipwrap] ***********************************************************
      ok: [servera.lab.example.com] => {
          "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"
          ]
      }
      
      TASK [7) Use ipaddr and ipwrap] ************************************************
      ok: [servera.lab.example.com] => {
          "msg": [
              "192.168.2.1",
              "10.0.0.128/25",
              "172.24.10.0/24",
              "172.24.10.0/32",
              "[ff02::1]",
              "[::1]",
              "[2001::1]/64",
              "[2001::]/64"
          ]
      }
      
      PLAY RECAP *********************************************************************
      servera.lab.example.com    : ok=8    changed=0    unreachable=0    failed=0  ...
  3. Alternatively, you can run the filtering_data.yml playbook with ansible-navigator in interactive mode to view the result of these tasks individually.

    [student@workstation data-netfilters]$ ansible-navigator run filtering_data.yml
    1. Press 0 to display details about the First play for netfilter exercise play.

      Play Name                    Ok Changed Unreachable ...Task count   Progress
      0│First play for netfilter   8	    0           0 ...         8   Complete
      
      
      ^f/PgUp page up     ^b/PgDn page down     ↑↓ scroll ...       help  Successful
    2. Press 2 to display details of the Use host task.

      Result  Host                        Number  Changed  Task
      0│Ok      servera.lab.example.com          0    False  Gathering Facts
      1│Ok      servera.lab.example.com          1    False  1) Display all addresses
      2│Ok      servera.lab.example.com          2    False  2) Use host
      3│Ok      servera.lab.example.com          3    False  3) Use net
      
      ...output omitted...
      
      ^f/PgUp page up     ^b/PgDn page down     ↑↓ scroll ...       help  Successful
    3. Review the details to see the filtered IP addresses.

      OK: [servera.lab.example.com] ['192.168.2.1/32', ...             '2001::1/64']
      ...output omitted...
      14│  - 192.168.2.1/32
      15│  - 172.24.10.0/32
      16│  - ff02::1/128
      17│  - ::1/128
      18│  - 2001::1/64
      19│start: '2022-11-15T17:26:19.910457'
      
      ...output omitted...

      Press ESC three times to exit from the ansible-navigator command.

  4. Open the ~/data-netfilters/site.yml playbook. The tasks section of the play in that playbook has two parts. The first set of tasks consists of set_fact tasks for you to complete with the ansible.utils.ipaddr filter. Replace any occurrence of #FIXME# in a fact definition with the value specified by the following substeps. The second set of tasks consists of debug tasks that print the information contained in the facts that you set.

    1. Use ansible.utils.ipaddr filter to verify that the ipv4_addr variable contains a properly formatted IP address.

          - name: Set facts derived from ipv4_addr and ipv4_subnet
            ansible.builtin.set_fact:
              server_address: "{{ ipv4_addr | ansible.utils.ipaddr }}"
    2. Use the revdns option with ansible.utils.ipaddr filter to retrieve the IP address in DNS PTR record format.

          - name: Set facts derived from ipv4_addr and ipv4_subnet
            ansible.builtin.set_fact:
              server_address: "{{ ipv4_addr | ansible.utils.ipaddr }}"
              ptr_record: "{{ ipv4_addr | ansible.utils.ipaddr('revdns') }}"
    3. Use the network/prefix option to retrieve the network address and CIDR prefix.

          - name: Set facts derived from net_mask
            ansible.builtin.set_fact:
              cidr: "{{ net_mask | ansible.utils.ipaddr('network/prefix') }}"
    4. Use the broadcast option to retrieve the broadcast address.

          - name: Set facts derived from net_mask
            ansible.builtin.set_fact:
              cidr: "{{ net_mask | ansible.utils.ipaddr('network/prefix') }}"
              broadcast: "{{ net_mask | ansible.utils.ipaddr('broadcast') }}"
    5. Use the cidr variable, which you set in an earlier task, to provide the network and its CIDR prefix as an option to the ansible.utils.ipaddr filter so that the list it returns only includes IP addresses that are on that network.

      - name: Print addresses on {{ cidr }} from this task's list
        ansible.builtin.debug:
          msg: "{{ item | ansible.utils.ipaddr(cidr) }}"
        loop:

      Important

      In the above example, cidr must not be in quotes because it is a variable defined earlier in the play that must be expanded, not a literal option for the filter.

    6. Verify that the completed site.yml playbook consists of the following content:

      # Complete each task by setting the fact as the expected value.
      # Replace FIXME by the appropriate filter usage.
      # Tasks make use of the gathered fact 'default_ipv4', and its keys 'address', and 'netmask'.
      
      - name: Second play for netfilter exercise
        hosts: servera.lab.example.com
        become: false
      
        tasks:
          - name: Set address and network facts
            ansible.builtin.set_fact:
              ipv4_addr: "{{ ansible_facts['default_ipv4']['address'] }}"
              ipv4_subnet: "{{ ansible_facts['default_ipv4']['netmask'] }}"
      
          - name: Set facts derived from ipv4_addr and ipv4_subnet
            ansible.builtin.set_fact:
              server_address: "{{ ipv4_addr | ansible.utils.ipaddr }}"
              ptr_record: "{{ ipv4_addr | ansible.utils.ipaddr('revdns') }}"
              net_mask: "{{ ipv4_addr }}/{{ ipv4_subnet }}"
      
          - name: Set facts derived from net_mask
            ansible.builtin.set_fact:
              cidr: "{{ net_mask | ansible.utils.ipaddr('network/prefix') }}"
              broadcast: "{{ net_mask | ansible.utils.ipaddr('broadcast') }}"
      
      
          - name: Display server_address
            ansible.builtin.debug:
              msg: server_address is {{ server_address }}
      
          - name: Display PTR record form for server_address
            ansible.builtin.debug:
              msg: ptr_record is {{ ptr_record }}
      
          - name: Display address and netmask in VLSM notation
            ansible.builtin.debug:
              msg: net_mask is {{ net_mask }}
      
          - name: Display address and prefix in CIDR notation
            ansible.builtin.debug:
              msg: cidr is {{ cidr }}
      
          - name: Display broadcast address for {{ cidr }}
            ansible.builtin.debug:
              msg: broadcast is {{ broadcast }}
      
          - name: Print addresses on {{ cidr }} from this task's list
            ansible.builtin.debug:
              msg: "{{ item | ansible.utils.ipaddr(cidr) }}"
            loop:
              - 172.16.0.1
              - 172.25.250.4
              - 192.168.122.20
              - 192.0.2.55
    7. Run the site.yml playbook and verify the output of each task.

      [student@workstation data-netfilters]$ ansible-navigator run \
      > -m stdout site.yml
      
      PLAY [Second play for netfilter exercise] **************************************
      
      TASK [Gathering Facts] *********************************************************
      ok: [servera.lab.example.com]
      
      TASK [Set address and network facts] *******************************************
      ok: [servera.lab.example.com]
      
      TASK [Set facts derived from ipv4_addr and ipv4_subnet] ************************
      ok: [servera.lab.example.com]
      
      TASK [Set facts derived from net_mask] *****************************************
      ok: [servera.lab.example.com]
      
      TASK [Display server_address] **************************************************
      ok: [servera.lab.example.com] => {
          "msg": "server_address is 172.25.250.10"
      }
      
      TASK [Display PTR record form for server_address] ******************************
      ok: [servera.lab.example.com] => {
          "msg": "ptr_record is 10.250.25.172.in-addr.arpa."
      }
      
      TASK [Display address and netmask in VLSM notation] ****************************
      ok: [servera.lab.example.com] => {
          "msg": "net_mask is 172.25.250.10/255.255.255.0"
      }
      
      TASK [Display address and prefix in CIDR notation] *****************************
      ok: [servera.lab.example.com] => {
          "msg": "cidr is 172.25.250.0/24"
      }
      
      TASK [Display broadcast address for 172.25.250.0/24] ***************************
      ok: [servera.lab.example.com] => {
          "msg": "broadcast is 172.25.250.255"
      }
      
      TASK [Print addresses on 172.25.250.0/24 from this task's list] ****************
      ok: [servera.lab.example.com] => (item=172.16.0.1) => {
          "msg": ""
      }
      ok: [servera.lab.example.com] => (item=172.25.250.4) => {
          "msg": "172.25.250.4"
      }
      ok: [servera.lab.example.com] => (item=192.168.122.20) => {
          "msg": ""
      }
      ok: [servera.lab.example.com] => (item=192.0.2.55) => {
          "msg": ""
      }
      
      PLAY RECAP *********************************************************************
      servera.lab.example.com    : ok=10   changed=0    unreachable=0    failed=0  ...
    8. Run the site.yml playbook with the ansible-navigator command in interactive mode to view the result of these tasks one at a time.

      [student@workstation data-netfilters]$ ansible-navigator run site.yml

      You can investigate each result in the same way that you did in step 3.

Finish

On the workstation machine, change to the student user home directory and use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish data-netfilters

This concludes the section.

Revision: do374-2.2-82dc0d7