IOS_FACTS module – collects information from devices running iOS.
Information is taken from the following commands:
dir
show version
show memory statistics
show interfaces
show ipv6 interface
show lldp
show lldp neighbors detail
show running-config
In the module, you can specify which parameters to collect – you can collect all information, but only a subset is possible. By default, the module collects all information other than the configuration file.
What information to collect is specified in the gather_subset parameter. The following options are supported (the commands that will be executed are also indicated on device):

Collect all the facts:
- ios_facts:
gather_subset: all
Collect only a subset of interfaces:
- ios_facts:
gather_subset:
- interfaces
Collect everything except hardware:
- ios_facts:
gather_subset:
- "!hardware"
Ansible collects these facts:
- ansible_net_all_ipv4_addresses – list of IPv4 addresses on the device
- ansible_net_all_ipv6_addresses – list of IPv6 addresses on the device
- ansible_net_config – configuration (for Cisco sh run)
- ansible_net_filesystems – device file system
- ansible_net_gather_subset – what information is collected (hardware, default, interfaces, config)
- ansible_net_hostname – device name
- ansible_net_image – OS name and path
- ansible_net_interfaces – a dictionary with all device interfaces. Names
- interfaces – keys, and data – parameters of each interface
- ansible_net_memfree_mb – how much free memory is on the device
- ansible_net_memtotal_mb – how much memory is on the device
- ansible_net_model – device model
- ansible_net_serialnum – serial number
- ansible_net_version – IOS version
How to use ios_facts module.
Example playbook ios_facts.yml using the ios_facts module (collecting all data):
$ ansible-playbook ios_facts.yml
---
- name: Collect IOS facts
hosts: all
gather_facts: false
tasks:
- name: Facts
ios_facts:
gather_subset: all
and file group_vars/all.yml with connection variables:
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: cisco
ansible_password: cisco
ansible_become: yes
ansible_become_method: enable
ansible_become_pass: cisco1

In order to see exactly what facts are collected from the device, you can add -v flag:
$ ansible-playbook 1_ios_facts.yml -v

Saving facts with ios_facts ansible
In the form in which information is displayed in verbose mode, it is quite difficult understand what information is collected about devices. In order to better understand what information is collected about devices, in what format, copy received information to a file.
The copy module will be used for this.
Playbook ios_facts.yml collects all information about devices and writes to different files (create all_facts directory before running playbook or uncomment the Create all_facts dir task and Ansible will create the directory itself):
---
- name: Collect IOS facts
hosts: cisco-routers
gather_facts: false
connection: local
tasks:
- name: Facts
ios_facts:
gather_subset: all
register: ios_facts_result
#- name: Create all_facts dir
# file:
# path: ./all_facts/
# state: directory
# mode: 0755
- name: Copy facts to files
copy:
content: "{{ ios_facts_result | to_nice_json }}"
dest: "all_facts/{{inventory_hostname}}_facts.json"
The copy module allows you to copy files from the control host (on which installed Ansible) to a remote host. But, in this case, the parameter is specified connection: local , the files will be copied to the local host. Most often, the copy module is used like this:
- copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
But, in this case, there is no source file whose contents need to be copied. Instead, there is the content of the ios_facts_result variable that needs to be migrated to the all_facts/{{inventory_hostname}}_facts.json file.
In order to transfer the contents of a variable to a file, in the copy module, instead of src, the content parameter is used.
In line content: “{{ ios_facts_result | to_nice_json }}”
- the to_nice_json parameter is a Jinja2 filter that transforms the information variable into a format in which it is more convenient to read information
- a variable in Jinja2 format must be enclosed in double curly braces and also quoted in double quotes
Because the dest path uses device names, unique files will be generated for each device.
Storing information about devices will not only help you understand what information is being collected, but it can also be useful for future use of the information. For example, you can use device facts in a template.
If the information has changed, the status changed will be set for the corresponding device. Thus, by executing the playbook, it is always clear when some information has changed.
Define changes on devices and facts with the –diff option with ansible ios_facts
In Ansible, you can not only see that changes have taken place, but also see exactly what changes have been made. For example, in a situation where device facts are stored, this can be very useful.
An example of running a playbook with the –diff option and with the changes made on one of the devices:
$ ansible-playbook ios_facts.yml --diff --limit=192.168.0.22

This output shows not only that the changes were made, but what device and what changes.