Navigation
Guide That Contains This Content
[+] Expand All
[-] Collapse All

    Example: Using Ansible to Install Software

    Juniper Networks provides support for using Ansible to manage devices running Junos OS. The juniper_junos_software module in the Juniper.junos role enables you to install a Junos OS software image or other software package on a device running Junos OS. This example outlines how to use the juniper_junos_software Ansible module to install a software image on a device running Junos OS.

    Note: Starting in Ansible for Junos OS Release 2.0.0, the juniper_junos_software module replaces the functionality of the junos_install_os module.

    Requirements

    This example uses the following hardware and software components:

    • Configuration management server running Ansible 2.1 or later with version 2.0.0 or later of the Juniper.junos role installed
    • Device running Junos OS with NETCONF enabled and a user account configured with appropriate permissions
    • SSH public/private key pair configured for the appropriate user on the Ansible server and device running Junos OS
    • Existing Ansible inventory file with required hosts defined

    Overview

    The juniper_junos_software module enables you to install a software image on a device running Junos OS. This example presents an Ansible playbook that uses the juniper_junos_software module to upgrade Junos OS on the hosts in the specified inventory group. In this example, the software image resides on the Ansible control machine, and the module copies the image to the target device before installing it. The module does not explicitly define a host argument, so the module operates on the default host, which is {{ inventory_hostname }}.

    This playbook includes the Checking NETCONF connectivity task, which utilizes the wait_for module to try to establish a NETCONF session with the device running Junos OS using the default NETCONF port 830. If the control machine fails to establish a NETCONF session with a device during playbook execution, then it skips over the other tasks in the play for that device.

    The task to install the Junos OS software image on the device executes the juniper_junos_software module provided that the NETCONF check was successful. The version argument defines the desired Junos OS version as it would be reported by the show version command on the device running Junos OS. During playbook execution, the module first checks that the requested version is not already installed on the device. If the requested version is different from the currently installed version, the module installs the requested version.

    The local_package argument defines the path to the new Junos OS image on the Ansible control machine. During the installation, the module performs a storage cleanup operation on the target device, copies the software image to the /var/tmp directory on the device, verifies the file’s checksum, validates the new software against the active configuration, and then installs the software on each Routing Engine on the target host. By default, the juniper_junos_software module reboots the device after the installation is complete; however, this task explicitly sets reboot: true for clarity.

    The task stores the module result in the sw variable and notifies one handler. If the user does not execute the playbook using check mode, the wait_reboot handler then tries to establish a session with the device to verify that the device is back online. The wait_time variable defines the length of time that the control machine attempts to reconnect with the device.

    This example includes the logfile parameter to log the progress of the installation. This is important for debugging purposes should the installation fail as well as for logging the dates and times of installations on the devices. The user executing the playbook must have permissions to write to the specified log file. By default, only messages of severity level WARNING or higher are logged. In this example, the playbook is executed with the -v option to log messages of severity level INFO or higher to monitor the installation.

    Configuration

    Creating the Ansible Playbook

    Step-by-Step Procedure

    To create a playbook that uses the juniper_junos_software module to install a software image on a device running Junos OS:

    1. Include the boilerplate for the playbook and this play, which must contain connection: local and the Juniper.junos role.

      ---
      - name: Install Junos OS
        hosts: mx1
        roles:
          - Juniper.junos 
        connection: local
        gather_facts: no
      
    2. Define or import any necessary variables, which for this example, includes the desired Junos OS version and the path to the new image, among others.

        vars:
          OS_version: 17.3R1.10
          OS_package: jinstall-ppc-17.3R1.10-signed.tgz
          pkg_dir: software
          log_dir: /var/log/ansible
          netconf_port: 830
          wait_time: 3600
      
    3. (Optional) Create a task to verify NETCONF connectivity.

        tasks:
          - name: Checking NETCONF connectivity
            wait_for: 
              host: "{{ inventory_hostname }}" 
              port: "{{ netconf_port }}"
              timeout: 5
      
    4. Create the task to install the Junos OS package on the device and notify the handler.

          - name: Install Junos OS package
            juniper_junos_software:
              version: "{{ OS_version }}"
              local_package: "{{ pkg_dir }}/{{ OS_package }}"
              reboot: true
              validate: true
              logfile: "{{ log_dir }}/software.log"
            register: sw
            notify:
            - wait_reboot
      
    5. (Optional) Create a task to print the module response.

          - name: Print response
            debug:
              var: sw
      
    6. Create the handler that verifies that the device comes back online after rebooting.

      The handler name should be the same as that referenced in the installation task.

        handlers:
          - name: wait_reboot
            wait_for: 
              host: "{{ inventory_hostname }}"
              port: "{{ netconf_port }}"
              timeout: "{{ wait_time }}"
            when: not sw.check_mode
      

    Results

    On the Ansible control machine, review the completed playbook. If the playbook does not display the intended code, repeat the instructions in this example to correct the playbook.

    ---
    - name: Install Junos OS
      hosts: mx1
      roles:
        - Juniper.junos 
      connection: local
      gather_facts: no
      
      vars:
        OS_version: 17.3R1.10
        OS_package: jinstall-ppc-17.3R1.10-signed.tgz
        pkg_dir: software
        log_dir: /var/log/ansible
        netconf_port: 830
        wait_time: 3600
    
      tasks:
        - name: Checking NETCONF connectivity
          wait_for: 
            host: "{{ inventory_hostname }}" 
            port: "{{ netconf_port }}"
            timeout: 5
    
        - name: Install Junos OS package
          juniper_junos_software:
            version: "{{ OS_version }}"
            local_package: "{{ pkg_dir }}/{{ OS_package }}"
            reboot: true
            validate: true
            logfile: "{{ log_dir }}/software.log"
          register: sw
          notify:
          - wait_reboot
    
        - name: Print response
          debug:
            var: response
    
      handlers:
        - name: wait_reboot
          wait_for: 
            host: "{{ inventory_hostname }}"
            port: "{{ netconf_port }}"
            timeout: "{{ wait_time }}"
          when: not sw.check_mode
    

    Executing the Playbook

    Step-by-Step Procedure

    To execute the playbook:

    • Issue the ansible-playbook command on the control machine, and provide the playbook path and any desired options.

      user@ansible-cm:~/ansible$ ansible-playbook -v ansible-pb-junos-install-os.yaml
      Using /etc/ansible/ansible.cfg as config file
      
      PLAY [Install Junos OS] ****************************************************
      
      TASK: [Checking NETCONF connectivity] **************************************
      ok: [mx1a.example.com] => {"changed": false, "elapsed": 0, "failed": false, "path": null, "port": 830, "search_regex": null, "state": "started"}
      
      TASK: [Install Junos OS package] *******************************************
      changed: [mx1a.example.com] => {"changed": true, "check_mode": false, "failed": false, "msg": "Package /home/user/ansible/software/jinstall-ppc-17.3R1.10-signed.tgz successfully installed. Reboot successfully initiated."}
      
      
      TASK [Print response] ******************************************************
      ok: [mx1a.example.com] => {
          "sw": {
              "changed": true, 
              "check_mode": false, 
              "failed": false, 
              "msg": "Package /home/user/ansible/software/jinstall-ppc-17.3R1.10-signed.tgz successfully installed. Reboot successfully initiated."
          }
      }
      
      RUNNING HANDLER [wait_reboot] **********************************************
      ok: [mx1a.example.com] => {"changed": false, "elapsed": 914, "failed": false, "path": null, "port": 830, "search_regex": null, "state": "started"}
       
      PLAY RECAP *****************************************************************
      mx1a.example.com            : ok=4    changed=1    unreachable=0    failed=0

    Verification

    Verifying the Installation

    Purpose

    Verify that the software installation was successful.

    Action

    The playbook output should indicate any failed tasks. However, you can also review the contents of the log file defined in the playbook for details about the installation. Sample log file output is shown here. Some output has been omitted for brevity.

    user@ansible-cm:~/ansible$ cat /var/log/ansible/software.log
    2017-12-08 12:02:43,840 - ncclient.transport.ssh - INFO - Connected (version 2.0, client OpenSSH_7.2)
    2017-12-08 12:02:44,139 - ncclient.transport.ssh - INFO - Authentication (publickey) successful!
    ...
    2017-12-08 12:02:47,004 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] computing checksum on local package: /home/user/ansible/software/jinstall-ppc-17.3R1.10-signed.tgz
    2017-12-08 12:02:49,030 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] cleaning filesystem ...
    2017-12-08 12:02:49,030 - ncclient.operations.rpc - INFO - Requesting 'ExecuteRpc'
    2017-12-08 12:03:01,066 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] before copy, computing checksum on remote package: /var/tmp/jinstall-ppc-17.3R1.10-signed.tgz
    2017-12-08 12:03:01,071 - ncclient.operations.rpc - INFO - Requesting 'ExecuteRpc'
    2017-12-08 12:03:01,424 - paramiko.transport - INFO - Connected (version 2.0, client OpenSSH_7.2)
    2017-12-08 12:03:01,773 - paramiko.transport - INFO - Authentication (publickey) successful!
    2017-12-08 12:03:55,892 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 36159488 / 361592739 (10%)
    2017-12-08 12:04:52,136 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 72318976 / 361592739 (20%)
    2017-12-08 12:05:50,010 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 108478464 / 361592739 (30%)
    2017-12-08 12:06:48,170 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 144637952 / 361592739 (40%)
    2017-12-08 12:07:46,661 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 180797440 / 361592739 (50%)
    2017-12-08 12:08:42,598 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 216956928 / 361592739 (60%)
    2017-12-08 12:09:40,349 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 253116416 / 361592739 (70%)
    2017-12-08 12:10:36,962 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 289275904 / 361592739 (80%)
    2017-12-08 12:11:32,264 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 325435392 / 361592739 (90%)
    2017-12-08 12:12:26,129 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] jinstall-ppc-17.3R1.10-signed.tgz: 361592739 / 361592739 (100%)
    2017-12-08 12:12:26,900 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] after copy, computing checksum on remote package: /var/tmp/jinstall-ppc-17.3R1.10-signed.tgz
    2017-12-08 12:12:26,903 - ncclient.operations.rpc - INFO - Requesting 'ExecuteRpc'
    2017-12-08 12:12:32,903 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] checksum check passed.
    2017-12-08 12:12:32,904 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] validating software against current config, please be patient ...
    2017-12-08 12:12:32,905 - ncclient.operations.rpc - INFO - Requesting 'ExecuteRpc'
    2017-12-08 12:25:53,347 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] software validate package-result: 0
    Output: 
    Checking compatibility with configuration
    ...
    Initializing...
    Using jbase-ppc-17.2R1.13
    Verified manifest signed by PackageProductionEc_2017 method ECDSA256+SHA256
    Using /var/tmp/jinstall-ppc-17.3R1.10-signed.tgz
    Verified jinstall-ppc-17.3R1.10.tgz signed by PackageProductionEc_2017 method ECDSA256+SHA256
    ...
    Validating against /config/juniper.conf.gz
    mgd: commit complete
    Validation succeeded
    Validating against /config/rescue.conf.gz
    mgd: commit complete
    Validation succeeded
    
    2017-12-08 12:25:53,348 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] installing software ... please be patient ...
    2017-12-08 12:25:53,348 - ncclient.operations.rpc - INFO - Requesting 'ExecuteRpc'
    2017-12-08 12:31:11,822 - jnpr.ansible_module.juniper_junos_software - INFO - [mx1a.example.com] software pkgadd package-result: 0
    Output: 
    Installing package '/var/tmp/jinstall-ppc-17.3R1.10-signed.tgz' ... 
    Verified jinstall-ppc-17.3R1.10.tgz signed by PackageProductionEc_2017 method ECDSA256+SHA256
    ...
    
    Saving state for rollback ... 
    
    2017-12-08 12:31:11,823 - ncclient.operations.rpc - INFO - Requesting 'ExecuteRpc'
    2017-12-08 12:31:22,212 - ncclient.operations.rpc - INFO - Requesting 'CloseSession'
    

    Meaning

    The log file contents indicate that the image was successfully copied to and installed on the target device.

    Modified: 2018-01-31