Fedora - Automating Network Devices with Ansible - Printable Version +- Sick Gaming (https://www.sickgaming.net) +-- Forum: Computers (https://www.sickgaming.net/forum-86.html) +--- Forum: Linux, FreeBSD, and Unix types (https://www.sickgaming.net/forum-88.html) +--- Thread: Fedora - Automating Network Devices with Ansible (/thread-96176.html) |
Fedora - Automating Network Devices with Ansible - xSicKxBot - 07-14-2020 Automating Network Devices with Ansible <div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/07/automating-network-devices-with-ansible.png" width="1024" height="237" title="" alt="" /></div><div><p>Ansible is a great automation tool for system and network engineers, with Ansible we can automate small network to a large scale enterprise network. I have been using Ansible to automate both Aruba, and Cisco switches from my Fedora powered laptops for a couple of years. This article covers the requirements and executing a couple of playbooks.</p> <p> <span id="more-31280"></span> </p> <h2>Configuring Ansible</h2> <p>If Ansible is not installed, it can be installed using the command below</p> <pre class="wp-block-preformatted">$ sudo dnf -y install ansible</pre> <p>Once installed, create a folder in your home directory or a directory of your preference and copy the ansible configuration file. For this demonstration, I will be using the following.</p> <pre class="wp-block-preformatted">$ mkdir -pv /home/$USER/network_automation $ sudo cp -v /etc/ansible.cfg /home/$USER/network_automation $ cd /home/$USER/network_automation $ sudo chown $USER.$USER && chmod 0600 ansible.cfg</pre> <p>To prevent lengthy commands from failing, edit the ansible.cfg and append the following lines. We must add the persistent connection and set the desired time in seconds for the <em>command_timeout</em> as demonstrated below. A use case where this is useful is when you are performing backups of a network device that has a lengthy configuration.</p> <pre class="wp-block-preformatted">$ vim ansible.cfg [persistent_connection] command_timeout = 300 connection_timeout = 30</pre> <h3>Requirements</h3> <p>If SELinux is enabled, you will need to install SELinux binding, which is required when using the copy module.</p> <pre class="wp-block-preformatted"># Install SELinux bindings dnf -y install python3-libselinux python3-libsemanage</pre> <h3>Creating the inventory</h3> <p>The inventory holds the names of the network assets, and grouping of the assets are in square brackets <em>[]</em>, below is a sample inventory.</p> <pre class="wp-block-preformatted">[site_a] Core_A ansible_host=192.168.122.200 Distro_A ansible_host=192.168.122.201 Distro_B ansible_host=192.168.122.202</pre> <div class="wp-block-jetpack-markdown"> <p>Group vars can be used to address the common variables, for example, credentials, network operating system, and so on. Ansible document on <a href="https://docs.ansible.com/ansible/latest/network/getting_started/first_inventory.html">inventory</a> provides additional details.</p> </div> <h2>Playbook</h2> <div class="wp-block-jetpack-markdown"> <blockquote> <p>Playbooks are Ansible’s configuration, deployment, and orchestration language. They can describe a policy you want your remote systems to enforce, or a set of steps in a general IT process.<br /> <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks.html">Ansible Playbook</a></p> </blockquote> </div> <h3>Read Operations</h3> <div class="wp-block-jetpack-markdown"> <p>Let us create a simple playbook to run a show command to read the configuration on a few switches.</p> <pre> <div class="codecolorer-container text default language-yaml" style="overflow:auto;border:1px solid #9F9F9F;width:435px"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace"> 1 ---<br /> 2 - name: Basic Playbook<br /> 3 hosts: site_a<br /> 4 connection: local<br /> 5 <br /> 6 tasks:<br /> 7 - name: Get Interface Brief<br /> 8 ios_command:<br /> 9 commands:<br /> 10 - show ip interface brief | e una<br /> 11 register: interfaces<br /> 12 <br /> 13 - name: Print results<br /> 14 debug:<br /> 15 msg: "{{ interfaces.stdout[0] }}</div></div> </pre> <figure><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/07/automating-network-devices-with-ansible.png" alt="Without Debug" /></figure> </p> <figure><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/07/automating-network-devices-with-ansible-1.png" alt="With Debug" /></figure> </p> <p>The above images show the differences without and with the debug module respectively.</p> <p>Let’s break the playbook into three blocks, starting with lines 1 to 4.</p> <ul> <li>The three dashes/hyphens starts the YAML document</li> <li>The hosts defines the hosts or host groups, multiple groups are comma-separated</li> <li>Connection defines the methodology to connect to the network devices. Another option is network_cli (recommended method) and will be used later in this article. See <a href="https://docs.ansible.com/ansible/latest/network/user_guide/platform_ios.html">IOS Platform Options</a> for more details.</li> </ul> <p>Lines 6 to 11 starts the tasks, we will be using <a href="https://docs.ansible.com/ansible/latest/modules/ios_command_module.html">ios_command</a> and <a href="https://docs.ansible.com/ansible/latest/modules/ios_config_module.html">ios_config</a>. This play will execute the show command <em>show ip interface brief | e una</em> and save the output from the command into the interfaces variable, with the register key.</p> <p>Lines 13 to 15, by default, when you execute a show command you will not see the output, though this is not used during automation. It is very useful for debugging; therefore, the debug module was used.</p> <p>The below video shows the execution of the playbook. There are a couple of ways you can execute the playbook.</p> <ul> <li>Passing arguments to the command line, for example, include <em>-u <username></em> <em>-k</em> to prompt for the remote user credentials</li> </ul> <pre> <div class="codecolorer-container text default" style="overflow:auto;border:1px solid #9F9F9F;width:435px"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace">ansible-playbook -i inventory show_demo.yaml -u admin -k</div></div> </pre> <ul> <li>Include the credentials in the host or group vars</li> </ul> <pre> <div class="codecolorer-container text default" style="overflow:auto;border:1px solid #9F9F9F;width:435px"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace">ansible-playbook -i inventory show_demo.yaml</div></div> </pre> </div> <div class="wp-block-jetpack-markdown"> <blockquote> <p>Never store passwords in plain text. We recommend using SSH keys to authenticate SSH connections. Ansible supports ssh-agent to manage your SSH keys. If you must use passwords to authenticate SSH connections, we recommend encrypting them with<br /> <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_vault.html#playbooks-vault">Using Vault in Playbooks</a></p> </blockquote> </div> <figure class="wp-block-video"><video controls src="https://fedoramagazine.org/wp-content/uploads/2020/06/Screencast-from-25-06-20-100214.webm"></video><figcaption>Passing arguments to the command line</figcaption></figure> <figure class="wp-block-video"><video controls src="https://fedoramagazine.org/wp-content/uploads/2020/06/Screencast-from-25-06-20-100811.webm"></video><figcaption>Credentials in the inventory</figcaption></figure> <p>If we want to save the output to a file, we will use the copy module as shown in the playbook below. In addition to using the copy module, we will include the <em>backup_dir</em> variable to specify the directory path.</p> <div class="wp-block-jetpack-markdown"> <pre> <div class="codecolorer-container text default" style="overflow:auto;border:1px solid #9F9F9F;width:435px"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace">---<br /> - name: Get System Infomation<br /> hosts: site_a<br /> connection: network_cli<br /> gather_facts: no<br /> <br /> vars:<br /> backup_dir: /home/eramirez/dev/ansible/fedora_magazine<br /> <br /> tasks:<br /> - name: get system interfaces<br /> ios_command:<br /> commands:<br /> - show ip int br | e una<br /> register: interface<br /> <br /> - name: Save result to disk<br /> copy:<br /> content: "{{ interface.stdout[0] }}"<br /> dest: "{{ backup_dir }}/{{ inventory_hostname }}.txt"</div></div> </pre> <p>To demonstrate the use of variables in the inventory, we will use plain text. This method <strong>Must</strong> not be used in production.</p> <pre> <div class="codecolorer-container text default language-yaml" style="overflow:auto;border:1px solid #9F9F9F;width:435px"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace">[site_a]<br /> Core_A ansible_host=192.168.122.200<br /> Distro_A ansible_host=192.168.122.201<br /> Distro_B ansible_host=192.168.122.202<br /> [all:vars]<br /> ansible_connection=network_cli<br /> ansible_network_os=ios<br /> ansible_user=admin<br /> ansible_password=fedora<br /> ansible_become=yes<br /> ansible_become_password=yes<br /> ansible_become_method=enable</div></div> </pre> </div> <figure class="wp-block-video"><video controls src="https://fedoramagazine.org/wp-content/uploads/2020/06/Screencast-from-24-06-20-234555.webm"></video></figure> <h3>Write Operations</h3> <div class="wp-block-jetpack-markdown"> <p>In the previous section, we saw that we could get information from the network devices; in this section, we will write (add/modify) the configuration on these network devices. To make changes to the network device, we will be using the <a href="https://docs.ansible.com/ansible/latest/modules/ios_config_module.html">ios config</a> module.</p> </div> <div class="wp-block-jetpack-markdown"> <p>Let us create a playbook to configure a couple of interfaces in all of the network devices in site_a. We will first take a backup of the current configuration of all devices in site_a. Lastly, we will save the configuration.</p> <pre> <div class="codecolorer-container text default language-yaml" style="overflow:auto;border:1px solid #9F9F9F;width:435px;height:300px"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace">---<br /> - name: Get System Infomation<br /> hosts: site_a<br /> connection: network_cli<br /> gather_facts: no<br /> <br /> vars:<br /> backup_dir: /home/eramirez/dev/ansible/fedora_magazine<br /> <br /> tasks:<br /> - name: Backup configs<br /> ios_config:<br /> backup: yes<br /> backup_options:<br /> filename: "{{ inventory_hostname }}_running_cfg.txt"<br /> dir_path: "{{ backup_dir }}"<br /> <br /> - name: get system interfaces<br /> ios_config:<br /> lines:<br /> - description Raspberry Pi<br /> - switchport mode access<br /> - switchport access vlan 100<br /> - spanning-tree portfast<br /> - logging event link-status<br /> - no shutdown<br /> parents: "{{ item }}"<br /> with_items:<br /> - interface FastEthernet1/12<br /> - interface FastEthernet1/13<br /> <br /> - name: Save switch configuration<br /> ios_config:<br /> save_when: modified</div></div> </pre> </div> <p>Before we execute the playbook, we will first validate the interface configuration. We will then run the playbook and confirm the changes as illustrated below.</p> <figure class="wp-block-video"><video controls src="https://fedoramagazine.org/wp-content/uploads/2020/06/Screencast-from-25-06-20-113943.webm"></video></figure> <h2>Conclusion</h2> <p>This article is a basic introduction to whet your appetite that demonstrates how Ansible is used to manage network devices. Ansible is capable of automating a vast network, which includes MPLS routing and performing validation before executing the next task.</p> </div> https://www.sickgaming.net/blog/2020/07/13/automating-network-devices-with-ansible/ |