Skip to content

swietlas/Ansible_software_update

Repository files navigation

Ansible_software_update

Ansible script to update software on Cisco devices.

How it works:

  • Script ensures backup directory exists and save config before applying any change
 - name: Get ansible date/time facts
      ansible.builtin.setup:
        filter: "ansible_date_time"
        gather_subset: "!all"

    - name: Store DTG as fact
      ansible.builtin.set_fact:
        DTG: "{{ ansible_date_time.date }}"

    - name: Create Directory
      ansible.builtin.file:
        path: ./backups/{{ hostvars.localhost.DTG }}
        state: directory
        mode: u+rw,g-wx,o-rwx
  run_once: true
  
  # Later in script:
  
      - name: Backup Running Config
      ios_command:
        commands: show run
      register: config
      tags: backup

    - name: Save output of sh run to ./backups/
      ansible.builtin.copy:
        content: "{{ config.stdout[0] }}"
        dest: "./backups/{{ hostvars.localhost.DTG }}/{{ inventory_hostname }}-{{ hostvars.localhost.DTG }}-config.txt"
        mode: u+rw,g-wx,o-rwx
      tags: backup

  
  • Script checks whether current software version matches targer IOS release

    • if maches then skip for current host
    • if not then runs tasks
     - name: Collect ios facts
        ios_facts:
          gather_subset:
            - hardware
        tags: hwinfo
    
      - name: display hardware info
        ansible.builtin.debug:
          msg:
            - "*** HARDWARE INFO ***"
            - "Free Space is: {{ ansible_net_filesystems_info[ flashname ]['spacefree_kb'] }} kb of {{ ansible_net_filesystems_info[ flashname ]['spacetotal_kb'] }} kb"
            - "Current IOS image is: {{ ansible_net_image }}"
            - "Target IOS image is: {{ upgrade_ios_image }}"
            - "Current IOS version is: {{ ansible_net_version }}"
            - "Target IOS version is: {{ upgrade_ios_version }}"
        tags: hwinfo
    
      - name: Check if current IOS release eq target release Cl
        ansible.builtin.meta: end_host
        when: ansible_net_version == upgrade_ios_version
        tags: checkver
  • It uses variables defined in group_vars and host_vars:

    • upgrade_ios_image (target release)
    • ios_md5sum (for target release)
    • ios_size (for target release)
    • upgrade_ios_version
---
ansible_connection: network_cli
ansible_become: yes
ansible_become_method: enable
ansible_network_os: ios
ansible_user: ansi
ansible_password: C1sc0123!
flashname: "flash:"
#upgrade_ios_version: 15.1(4)M12a
#upgrade_ios_image: c1861-adventerprisek9-mz.151-4.M12a.bin
#ios_md5sum: 43b0f86a6627b3bb320ed4b3c96ddcb7
#ios_size: 49644
upgrade_ios_version: 15.2(4)M11
upgrade_ios_image: c1861-adventerprisek9-mz.152-4.M11.bin
ios_md5sum: 21abb3fccde22f65dd134d53f3970a0d
ios_size: 56056
...
  • Before transfering new IOS file script verifies whether or not there is enought space available for new IOS image:
    • if not then remove old image
    - name: Not enough free space info check
     ansible.builtin.debug:
       msg:
         - "[Error] there not enought free space for new IOS version"
     when: ansible_net_filesystems_info[ flashname ]['spacefree_kb'] < ios_size
     tags: space

   - name: Delete old IOS release if not enought free space
     ios_command:
       commands: delete /force {{ ansible_net_image }}
     when: ansible_net_filesystems_info[ flashname ]['spacefree_kb'] < ios_size
     tags: del_old
  • Copy new image to flash:
 - name: Copy IOS to device
      ios_command:
        commands:
          - command: "copy tftp://{{ tftp_server }}/{{ upgrade_ios_image }} flash:"
            prompt: 'Destination filename \[{{ upgrade_ios_image }}\]?'
            answer: "\r"
          - command: show flash
      when: ansible_net_filesystems_info[ flashname ]['spacefree_kb'] > ios_size
      until: result[1] contains upgrade_ios_image
      retries: 3
      vars:
        ansible_command_timeout: 600
      tags: cp_ios

    - name: Check md5sum of IOS on device
      ios_command:
        commands:
          - 'verify /md5 flash:{{ upgrade_ios_image }} {{ ios_md5sum }}'
        # - command: 'verify /md5 flash:{{ upgrade_ios_image }} {{ ios_md5sum }}'
      register: md5_output
      vars:
        ansible_command_timeout: 600
      tags: md5sum
  • Final step is to verify if new image has been transferred successfully and reload.
- name: Change config and reload if md5 checksum matches
     block:
       - name: Set new boot variable
         ios_config:
           lines:
             - no boot system {{ ansible_net_image }}
             - boot system flash:{{ upgrade_ios_image }}
           save_when: always

       - name: Reload device
         ios_command:
           commands:
             - command: reload
               prompt: '\[confirm\]'
               answer: "\r"

       - name: Wait for device to reboot
         ansible.builtin.wait_for:
           host: "{{ inventory_hostname }}"
           port: 22
           delay: 120
           timeout: 600
         delegate_to: localhost

       - name: Gather facts of the switch again
         ios_facts:

       - name: Assert that the running IOS version is correct
         ansible.builtin.assert:
           that:
             - upgrade_ios_version == ansible_net_version
           success_msg: "Upgrade successful."
           fail_msg: "IOS version does not match compliant version. Upgrade unsuccessful."

     when: '"Verified" in md5_output.stdout[0]'
     ```

About

Ansible script to update software on Cisco devices

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published