Ansible Playbook for Network OS Upgrade with pre and post checks
You have 100s of network switches or routers that you need to upgrade. How much time would it take for you to do the upgrades? There are a lot number of sub-tasks involved while upgrading IOS image of a Cisco router or a switch.
This time of upgradation can be reduced through automation from various Enterprise Configuration Management tools that also have ability to upgrade network OS. Though these tools give an easy to use graphical interface, but this requires you to have appropriate license and also restricts you to customize your upgrade process.
Ansible is one of the tool that can be used and the upgrade process can also be customized to include any tasks that you want, e.g. taking pre-checks, post-checks and then comparing them and highlighting the differences, etc.
Following is the Ansible-playbook for IOS upgradation, that includes following sub-tasks. More tasks can be included as per need.
IOS upgrade tasks included in the playbook
- Verify the current version of OS version
- Decide whether to upgrade the IOS of device or not.
- Backup the running configuration of device
- Take pre and post checks of defined commands.
- Upload IOS image file from ftp to the device
- Change boot variable on device and save the config.
- Reload the device to boot with new IOS image
- Compare pre and post-checks and display the difference
vi ios_upgrade_vars.yml---# variables used for IOS upgrade playbookupgrade_ios_version: 16.09.05upgrade_ios_image: image.binftp_user:ftp_password:ftp_server:precheck_path:postcheck_path:
---# Ansible Playbook to upgrade Cisco IOS. Created by Prashant Sahu (Network Galaxy) http://www.networkgalaxy.org- name: Upgrade Cisco IOShosts: ios-xe-01connection: network_clivars_files:- ~/ios_upgrade_vars.ymltasks:- name: Checking current IOS versionios_facts:- name: Comparing Installed and Expected IOS versiondebug:msg:- "Current version is {{ ansible_net_version}}"- "Upgrade image is {{ upgrade_ios_version }}"- name: Deciding whether the IOS will be upgraded or notdebug:msg: "{% if ansible_net_version == upgrade_ios_version %} Current IOS version is up to date. Upgrade would be skipped for this host {% else %} Current Image version is different than the upgrade image and will be upgraded {% endif %}"- name: End the play for the host if device os version is up to datemeta: end_hostwhen: ansible_net_version == upgrade_ios_version- name: Backing up the running configuration to local fileios_config:backup: yes- name: Writing Memory on deviceios_config:save_when: always- name: Reading 'show ip route' ouputcli_command:command: show ip routeregister: ip_route_pre- name: Copying 'show ip route' ouput to local filecopy:content: "{{ ip_route_pre.stdout }}"dest: "{{ precheck_path }}{{ inventory_hostname }}_route-precheck"- name: Reading 'show ip interface brief' ouputcli_command:command: show ip interface briefregister: interface_ip_pre- name: Copying 'show ip interface brief' ouput to local filecopy:content: "{{ interface_ip_pre.stdout }}"dest: "{{ precheck_path }}{{ inventory_hostname }}_interface-ip-precheck"- name: Copying IOS image to bootflash of device. This may take time.....ios_command:commands:- command: "copy ftp://{{ftp_user}}:{{ftp_password}}@{{ftp_server}}/{{ upgrade_ios_image }} flash:{{ upgrade_ios_image }}"prompt: 'Destination filename [{{ upgrade_ios_image}}]?'answer: "\r"vars:ansible_command_timeout: 600- name: Changing Boot Variable to new imageios_config:parents: boot-start-markercommands:- boot system flash {{ upgrade_ios_image }}- boot system flash {{ ansible_net_image }}match: exactbefore:- no boot systemsave_when: always- name: Reloading the Devicecli_command:command: "reload"check_all: Trueprompt:- "Save?"- "reload?"- "confirm"answer:- 'yes'- 'yes'- 'y'- name: reset the connectionmeta: reset_connection- name: wait for network device to come back upwait_for_connection:delay: 100connect_timeout: 1200- name: Comparing Installed and Expected IOS versiondebug:msg:- Expected image after the upgrade is {{ upgrade_ios_version }}- Current version is {{ ansible_net_version }}- name: Upgrade Resultdebug:msg: "{% if ansible_net_version == upgrade_ios_version %} IOS Upgrade is complete! {% else %} IOS upgrade is not successul. Please check logs on {{ inventory_hostname }} {% endif %}"- name: Reading 'show ip route' ouputcli_command:command: show ip routeregister: ip_route_post- name: Copying 'show ip route' ouput to local filecopy:content: "{{ ip_route_post.stdout }}"dest: "{{ postcheck_path }}/{{ inventory_hostname }}_route-postcheck"- name: Reading 'show ip interface brief' ouputcli_command:command: show ip interface briefregister: interface_ip_post- name: Copying 'show ip interface brief' ouput to local filecopy:content: "{{ interface_ip_post.stdout }}"dest: "{{ postcheck_path }}{{ inventory_hostname }}_interface-ip-postcheck"- name: Comparing Pre and Post outputshosts: localhostgather_facts: novars_files:- ~/ios_upgrade_vars.ymltasks:- name: Comparing pre and post routescopy:src: "{{ postcheck_path }}{{ inventory_hostname }}_route-postcheck"dest: "{{ precheck_path }}{{ inventory_hostname }}_route-precheck"check_mode: yesdiff: yes- name: Comparing pre and post interface IPcopy:src: "{{ postcheck_path }}{{ inventory_hostname }}_interface-ip-postcheck"dest: "{{ precheck_path }}{( inventory_hostname }}_interface-ip-precheck"check_mode: yesdiff: yes
In the task Comparing Pre and Post outputs the inventory_hostname resolves to localhost rather than the network device
ReplyDelete