Ansible Best Practice Playbook uses filters to process network addresses

written in front


  • Use filters to inspect, validate and manipulate variables containing network information
  • If you don’t understand enough, please help me to correct

In the evening, you sit under the eaves, watching the sky slowly getting dark, feeling lonely and desolate in your heart, feeling that your life has been deprived of you. I was a young man at the time, but I was afraid to live like this, to grow old. In my opinion, this is something more terrible than death. --------Wang Xiaobo


Collect and process network information

The standard setupmodule playautomatically gathers facts at the beginning of multiple , collecting a large amount of network-related information from each managed host.

Common internet facts:

  • ansible_facts[‘dns’][‘nameservers’]
  • ansible_facts[‘domain’]
  • ansible_facts[‘all_ipv4_addresses’]
  • ansible_facts[‘all_ipv6_addresses’]
  • ansible_facts[‘fqdn’]
  • ansible_facts[‘hostname’]

View the fully qualified names of all inventory hosts

---
- name: net_work
  hosts: all
  tasks:
    - name: print
      debug:
        msg:  "{
    
    { ansible_facts['fqdn'] }}"
$

Execute the test

$ ansible-playbook network.yaml
.........
TASK [print] ***************************************************************************************************************
ok: [servera] => {
    
    
    "msg": "servera.lab.example.com"
}
ok: [serverb] => {
    
    
    "msg": "serverb.lab.example.com"
}
ok: [serverc] => {
    
    
    "msg": "serverc.lab.example.com"
}
ok: [serverd] => {
    
    
    "msg": "serverd.lab.example.com"
}
ok: [servere] => {
    
    
    "msg": "servere.lab.example.com"
}
ok: [serverf] => {
    
    
    "msg": "serverf.lab.example.com"
}

web information filter

ipaddrFilters can be used to process and validate network-related facts:

  • Check the syntax of the IP address
  • Convert VLSN subnet mask to CIDR subnet
  • Perform Subnet Math
  • Find the next available address within the network range

Requirements: To use the ipaddr filter in the RHEL8 system, you need to install python3-netaddrthe package, which provides the Python module netaddr.

[student@workstation laomalS sudo yum install -y python3-netaddr

The ipaddr filter provides functionality for manipulating and validating network-related facts.

Can be used to check the syntax of an IP address, convert from VLSN subnet mask to CIDR subnet prefix notation, perform subnet calculations, find the next available address within a network range, and more.

In its simplest form, the ipaddr filter with no parameters accepts a single value. If the value is an IP address, the filter returns the IP address, if it is not an IP address, the filter returns False.

  • If the value is a valid P address, the filter will return the address.
  • If the value is not a valid IP address, the filter returns False.
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.50" | ipaddr}}'
servera | SUCCESS => {
    
    
    "msg": "175.25.250.50"
}
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.50/24" | ipaddr}}'
servera | SUCCESS => {
    
    
    "msg": "175.25.250.50/24"
}
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.500/24" | ipaddr}}'
servera | SUCCESS => {
    
    
    "msg": false
}

The ipaddr filter accepts parameter values:

  • If the value contains a valid IP address, a valid IP address is returned.
  • Returns an empty list if all items are invalid.
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.50/24" | ipaddr("netmask")}}'
servera | SUCCESS => {
    
    
    "msg": "255.255.255.0"
}
$
  • The ipaddr filter accepts the following options:
  • address: Validate that the input value is a valid IP address, if the input contains a network prefix, it will be stripped.
  • net: Validates that the input value is a network range and returns it in CIDR format.
  • host: Ensures that the IP address conforms to the equivalent CIDR prefix format.
  • prefix: Verifies that the input host satisfies the host/prefix or CIDR format and returns the prefix.
  • host/prefix: Validate that input is in network/prefix format.
  • public or private: Verify that the entered IP address or network range is within a range reserved by IANA as public or private, respectively.
  • size: Converts the input network range to the number of IP addresses in that range.
  • n: any integer. Converts a network range to the Nth element in that range. Negative numbers return the nth element from the last number.
  • network, netmask, broadcast: Verifies that the input host satisfies the host/prefix or CIDR format and converts it to a network address, subnet mask or broadcast address respectively.
  • subnet: Validates that an input host satisfies the host/prefix or CIDR format and returns the subnet containing the host.
  • ipv4 ipv6: Validates input for valid network ranges and converts them to ipv4 and ipv6 formats respectively.
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.50/24" | ipaddr("ipv6")}}'
servera | SUCCESS => {
    
    
    "msg": "::ffff:175.25.250.50/120"
}
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.50/24" | ipaddr("subnet")}}'
servera | SUCCESS => {
    
    
    "msg": "175.25.250.0/24"
}
$ ansible servera -m debug -a 'msg={
    
    { "175.25.250.50/24" | ipaddr("size")}}'
servera | SUCCESS => {
    
    
    "msg": "256"
}

Use plugins to collect network information

Find DNS information

The dig command queries the DNS service and returns the resulting records. dig requires the python3-dns package to be installed on the control node.

$ ansible servera -m debug -a 'msg={
    
    {  lookup("dig","servera.lab.example.com")}}'
servera | SUCCESS => {
    
    
    "msg": "172.25.250.10"
}
$ ansible servera -m debug -a 'msg={
    
    {  lookup("dig","example.com")}}'
servera | SUCCESS => {
    
    
    "msg": "172.25.254.254"
}
$ ansible servera -m debug -a 'msg={
    
    {  lookup("dig","com")}}'
servera | SUCCESS => {
    
    
    "msg": "NXDOMAIN"
}

dig looks for the presence of an A record for the provided FQDN in the DNS server:

$ ansible servera -m debug -a 'msg={
    
    {  lookup("dig","example.com", "qtype=A")}}'
servera | SUCCESS => {
    
    
    "msg": "10 classroom.example.com."
}
$ ansible servera -m debug -a 'msg={
    
    {  lookup("dig","example.com", "@")}}'
servera | SUCCESS => {
    
    
    "msg": "172.25.254.254"
}

a demo

[student@workstation netfilters]$ cat ./tasks/main.yml
# Complete each task by setting the fact as the expected value.
# Replace ellipsis by the appropriate filter usage.
# All task but the last one should be using the 'ipaddr' filter.
# Use the lookup filter with the `dig` command for the last task

# Tasks make use of th gathered fact 'default_ipv4', and its keys 'address', 'network' and 'netmask'

- name: Task 1- Verify the 'ansible_default_ipv4.addresss' provided address is correctly formatted.
  set_fact:
    server_address: "{
    
    { ansible_facts.default_ipv4.address | ipaddr }}"
- name: Task 2- Check 'server_address' value
  assert:
    that: "server_address == ansible_facts.default_ipv4.address"
    fail_msg: "'server_address' must be {
    
    { ansible_facts.default_ipv4.address }}, but is {
    
    { server_address }}"


- name: Task 3- Obtain the DNS name associated to the server IP address (reverse DNS)
  set_fact:
    address_dns: "{
    
    { server_address | ipaddr('revdns') }}"
- name: Task 4- Check 'address_dns' value
  assert:
    that: "address_dns == '10.250.25.172.in-addr.arpa.'"
    fail_msg: "'address_dns' must be '10.250.25.172.in-addr.arpa.', but is {
    
    { address_dns }}"


- name: Task 5- Obtain server's network/netmask
  set_fact:
    net_mask: "{
    
    { ansible_facts.default_ipv4.network }}/{
    
    { ansible_facts.default_ipv4.netmask }}"
- name: Task 6- Check 'net_mask' value
  assert:
    that: "net_mask == '172.25.250.0/255.255.255.0'"
    fail_msg: "'net_mask' must be '172.25.250.0/255.255.255.0', but is {
    
    { net_mask }}"


- name: Task 7- Transform the network/netmask to the CIDR format
  set_fact:
    cidr: "{
    
    { net_mask | ipaddr('net') }}"
- name: Task 8- Check 'cidr' value
  assert:
    that: "cidr == '172.25.250.0/24'"
    fail_msg: "'cidr' must be '172.25.250.0/24', but is {
    
    { cidr }}"


- name: Task 9- Verify the server address actualy belong to the network/mask
  set_fact:
    address_in_range: "{
    
    { server_address | ipaddr(net_mask) }}"
- name: Task 10- Check 'address_in_range' value
  assert:
    that: "address_in_range == server_address"
    fail_msg: "'address_in_range' must be {
    
    { server_address }}, but is {
    
    { address_in_range }}"


- name: Task 11- Obtain the broadcast address associated to the CIDR
  set_fact:
    broadcast: "{
    
    { cidr | ipaddr('broadcast') }}"
- name: Task 12- Check 'broadcast' value
  assert:
    that: "broadcast == '172.25.250.255'"
    fail_msg: "'broadcast' must be '172.25.250.255', but is {
    
    { broadcast }}"


- name: Task 13- DIG for the MX record of the domain 'example.com'
  set_fact:
    dig_record: "{
    
    { lookup( 'dig', 'example.com.', 'qtype=MX') }}"
- name: Task 14- Check 'dig_record' value
  assert:
    that: "dig_record == '10 classroom.example.com.'"
    fail_msg: "'dig_record' must be '10 classroom.example.com.', but is '{
    
    { dig_record }}'"

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

PLAY [Tasks for netfilter guided exercise] *****************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [servera.lab.example.com]

TASK [netfilters : Task 1- Verify the 'ansible_default_ipv4.addresss' provided address is correctly formatted.] ********
ok: [servera.lab.example.com]

TASK [netfilters : Task 2- Check 'server_address' value] ***************************************************************
ok: [servera.lab.example.com] => {
    
    
    "changed": false,
    "msg": "All assertions passed"
}

TASK [netfilters : Task 3- Obtain the DNS name associated to the server IP address (reverse DNS)] **********************
ok: [servera.lab.example.com]

TASK [netfilters : Task 4- Check 'address_dns' value] ******************************************************************
ok: [servera.lab.example.com] => {
    
    
    "changed": false,
    "msg": "All assertions passed"
}

TASK [netfilters : Task 5- Obtain server's network/netmask] ************************************************************
ok: [servera.lab.example.com]

TASK [netfilters : Task 6- Check 'net_mask' value] *********************************************************************
ok: [servera.lab.example.com] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [netfilters : Task 7- Transform the network/netmask to the CIDR format] *******************************************
ok: [servera.lab.example.com]

TASK [netfilters : Task 8- Check 'cidr' value] *************************************************************************
ok: [servera.lab.example.com] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [netfilters : Task 9- Verify the server address actualy belong to the network/mask] *******************************
ok: [servera.lab.example.com]

TASK [netfilters : Task 10- Check 'address_in_range' value] ************************************************************
ok: [servera.lab.example.com] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [netfilters : Task 11- Obtain the broadcast address associated to the CIDR] ***************************************
ok: [servera.lab.example.com]

TASK [netfilters : Task 12- Check 'broadcast' value] *******************************************************************
ok: [servera.lab.example.com] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [netfilters : Task 13- DIG for the MX record of the domain 'example.com'] *****************************************
ok: [servera.lab.example.com]

TASK [netfilters : Task 14- Check 'dig_record' value] ******************************************************************
ok: [servera.lab.example.com] => {
    
    
    "changed": false,
    "msg": "All assertions passed"
}

PLAY RECAP *************************************************************************************************************
servera.lab.example.com    : ok=15   changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[student@workstation data-netfilters]$ cat site.yml
- name: Tasks for netfilter guided exercise
  hosts: servera.lab.example.com
  roles:
    - role: netfilters

[student@workstation data-netfilters]$

blog reference

《DO447》

Guess you like

Origin blog.csdn.net/sanhewuyang/article/details/131998033