Today I learned:
When using Ansible for network automation, the setup module, or gather_facts does not work against network devices. This only works against Linux machines. In order to gather information about network devices you have to use their respective network modules.
If you attempt to run gather_facts against most networking devices you will get some pretty nondescript errors about “line has invalid autcommand”. Even running your commands with -vvvv or ANSIBLE_DEBUG=1
as suggested won’t return much more helpful info. Here’s an example of the
completely unhelpful output you’ll see.
This is a one-liner using the setup module that will gather information about a Linux box, such as IP address, hostname, and kernel version. This same command won’t work against a piece of network equipment.ansible -i -m setup
To gather data about a Cisco switch for example, you’d need to use the ios_facts module.ansible -i -m ios_facts
This will return information such as interfaces states, ip addresses, and other configuration settings. This information can be very useful when writing your playbooks, but requires you to use the device-specific module to gather them.
ansible@blueansible:~$ ansible testciscocore.test.com -m setup -u ansible -kSSH password:[WARNING]: Unhandled error in Python interpreter discovery for host testciscocore.test.com: unexpected output from Python interpreter discovery[WARNING]: sftp transfer mechanism failed on [testciscocore.test.com]. Use ANSIBLE_DEBUG=1 to see detailed information[WARNING]: scp transfer mechanism failed on [testciscocore.test.com]. Use ANSIBLE_DEBUG=1 to see detailed information[WARNING]: Platform unknown on host testciscocore.test.com is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this.See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.testciscocore.test.com | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to testciscocore.test.com closed.\r\n", "module_stdout": "\r\nLine has invalid autocommand \"/bin/sh -c '/usr/bin/python '\"'\"'\"echo /tmp/ansible-tmp-1593570629.3542137- 1034822-97488801995215\" ) && \"/AnsiballZ_setup.py'\"'\"' && sleep 0'\"", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 0}
An example of using ios_facts in a playbook:
name: Gather IOS Information ios_facts: gather_network_resources: l2_interfaces register: ios_result
This task above, when included in your list of tasks, will return information about Layer 2 interfaces on the IOS device, and store the results in the variable ios_result. The information can later be retrieved for making decisions later on. Look here for more detailed information on other parameters that can be used with ios_facts to limit or expand the information gathered from the device. There are other fact modules for other manufactures of devices like Fortinet, and others.
Note: Some _facts modules are being renamed to _info in Ansible 2.9. This is due to the nature of facts in Ansible. These specific modules do not return “Ansible facts”, they return information about a device, and thus are being named more appropriately.