Use Ansible to Install Software on Junos Devices
SUMMARY Use the Juniper Networks Ansible modules to install software on Junos devices.
Use Ansible to Install Software
Juniper Networks supports using Ansible to manage Junos devices and provides modules that enable you to install or upgrade the software image on a device. Table 1 outlines the modules.
Content Set |
Module Name |
---|---|
|
|
|
Starting in Juniper.junos
Release 2.0.0, the
juniper_junos_software
module replaces the functionality of
the junos_install_os
module.
The following sections discuss how to specify the software image location and the general software installation process and options when using the modules to install software packages on Junos devices. They also discuss how to perform more specialized upgrade scenarios such as a VM host upgrade, a unified in-service software upgrade (unified ISSU), or a nonstop software upgrade (NSSU) on devices that support these features.
How to Specify the Software Image Location
When you use the software
or
juniper_junos_software
module to install software on Junos
devices, you can download the software package to the Ansible control node, and
the modules, by default, copy the package to the target device before performing
the installation. For mixed Virtual Chassis environments, the packages must
reside on the Ansible control node. For standalone devices or non-mixed Virtual
Chassis environments, you can also instruct the module to install a software
image that already resides on the target Junos device or resides at a URL that
is reachable from the target device.
Table 2 outlines the module arguments that you must set depending on the software
package location. The module must always include either the
local_package
, pkg_set
, or
remote_package
argument. The no_copy
argument defaults to false
, which instructs the module to copy
the software package from the specified location on the control node to the
target device.
Software Package Location |
|
|
|
---|---|---|---|
Ansible control node |
Omit or set to |
For standalone devices or non-mixed Virtual Chassis environments: Set |
(Optional) File path on the target device to which the software package is copied. The default directory is /var/tmp. If |
For mixed Virtual Chassis environments: Set |
– |
||
Remote Location |
– |
– |
URL from the perspective of the target Junos device from which the software package is installed. |
Target device |
Set to |
– |
File path on the target device where the software package must already reside. The default directory is /var/tmp. |
If the software package resides on the Ansible control node, include the
local_package
argument to install software on a standalone
Junos device or on members in a non-mixed Virtual Chassis, or include the
pkg_set
argument to install software on the members in a
mixed Virtual Chassis. The module argument specifies the absolute or relative
file path to the software package or packages on the local control node.
The local_package
argument is a single string specifying the
software image path. The pkg_set
argument contains a list of
strings that specify the necessary software image paths, in no particular order,
for the various Virtual Chassis members. For example:
pkg_set: - 'software/jinstall-qfx-5-13.2X51-D35.3-domestic-signed.tgz' - 'software/jinstall-ex-4300-13.2X51-D35.3-domestic-signed.tgz'
By default, when you include the local_package
or
pkg_set
argument, the module copies any software packages
to the /var/tmp directory on the target Junos device
(individual device or Virtual Chassis primary device). If you want to copy the
local_package
image to a different directory, define the
remote_package
argument and specify the target directory.
If the remote_package
argument includes a filename, the
filenames of the local_package
and
remote_package
arguments must be identical, or the module
generates an error.
If the software package already resides on the target Junos device, the module
must include the no_copy: True
argument as well the
remote_package
argument, which specifies the file path to
an existing software package on the target device. If
remote_package
does not specify a directory, the default is
/var/tmp.
If the software package resides at a location other than the Ansible control node
or target device, the module must include the remote_package
argument and specify the location of the software package. The value of
remote_package
is a URL from the perspective of the target
Junos device. For information about acceptable URL formats, see Format for Specifying Filenames and URLs in Junos OS CLI
Commands.
Installation Process Overview
To use Ansible to install a software package on a Junos device, execute the
software
or juniper_junos_software
module, and provide any
necessary arguments. For example:
--- - name: Perform a Junos OS software upgrade hosts: dc1 connection: local gather_facts: no tasks: - name: Upgrade Junos OS juniper.device.software: local_package: "software/jinstall-ppc-17.3R1.10-signed.tgz" no_copy: false validate: True register: response - name: Print the response debug: var: response
When you execute the software
or
juniper_junos_software
module, it performs the following
operations:
Once the software package is on the target device, whether downloaded there initially or copied over by the module, the module then performs the following operations:
Validates the configuration against the new package if the
validate
parameter is set totrue
.Note:By default, the
software
andjuniper_junos_software
modules do not validate the software package or bundle against the existing configuration as a prerequisite to adding the software package. To ensure that the active configuration will work with the new software image, set thevalidate
argument totrue
.Installs the package on each individual Routing Engine, unless
all_re
is set tofalse
.Reboots each upgraded Routing Engine, unless the
reboot
argument is set tofalse
.
The software
and juniper_junos_software
modules
enable you to log the progress of the installation by including the
logfile
module argument. By default, only messages of
severity level WARNING or higher are logged. To log messages of severity level
INFO or higher, which is required to log messages for the general installation
process, execute the playbook with the -v
or
--verbose
command-line option.
How to Specify Timeout Values
The Juniper Networks software modules perform operations over a NETCONF session. The default time for a NETCONF RPC to time out is 30 seconds. During the installation process, certain operations increase the RPC timeout interval as follows:
-
Copying and installing the package on the device—1800 seconds (30 minutes)
-
Computing the checksum—300 seconds (5 minutes)
-
Performing a storage cleanup—300 seconds (5 minutes)
In some cases, the installation process, checksum calculation, or storage cleanup
might exceed these time intervals. You can change the timeout value for these
operations by setting the install_timeout
,
checksum_timeout
, and cleanfs_timeout
arguments to the required number of seconds in the module’s argument list. For
example:
- name: Upgrade Junos OS juniper.device.software: local_package: "software/jinstall-ppc-17.3R1.10-signed.tgz" validate: True install_timeout: 2000 checksum_timeout: 420 cleanfs_timeout: 600
How to Specify Installation Options That Do Not Have an Equivalent Module Argument
When you use the software
or
juniper_junos_software
module to install software on a
device, the module invokes the appropriate RPC for the given installation
arguments, for example, the <request-package-add>
RPC for
standard Junos OS installations, the
<request-vmhost-package-add>
RPC for VM host
upgrades, the <request-package-in-service-upgrade>
RPC
for unified ISSU scenarios, and so on. The modules support explicit arguments
for many of the installation options, for example, the validate
option. The modules also support the kwargs
argument, which
enables you to include any additional options that are supported by the RPC but
which do not have an equivalent module argument. The kwargs
argument takes a dictionary of key/value pairs of additional supported options.
For the current list of options supported by the modules, see the API reference documentation for that module. For a list of all available options for a specific RPC, see the documentation for the equivalent command or search for the RPC’s request tag in the Junos XML API Explorer.
The modules should only include installation options that are supported on the target Junos device.
In the following playbook, the software
module installs a new
software image on the target hosts. The module includes the
kwargs
argument with unlink: True
. This
argument, which removes the software package from the directory after a
successful upgrade, is equivalent to including the
<unlink/>
option in the
<request-package-add>
RPC.
--- - name: Perform a Junos OS software upgrade hosts: router1 connection: local gather_facts: no tasks: - name: Upgrade Junos OS juniper.device.software: local_package: "software/jinstall-ppc-17.3R1.10-signed.tgz" kwargs: unlink: True register: response - name: Print the response debug: var: response
How to Perform a VM Host Upgrade
On devices that have Routing Engines with VM host support, Junos OS runs as a
virtual machine (VM) over a Linux-based host (VM host). A VM host upgrade, which
upgrades the host OS and compatible Junos OS, requires a VM Host Installation
Package (junos-vmhost-install-x.tgz) and
is performed using the request vmhost software add
operational
mode command, which corresponds to the
<request-vmhost-package-add>
RPC.
The software
and juniper_junos_software
modules
support the vmhost: True
argument for performing a VM host
upgrade. When the argument is present, the module performs the installation
using the <request-vmhost-package-add>
RPC.
The following playbook upgrades and reboots the Junos OS and host OS on the devices:
--- - name: Upgrade VM Hosts hosts: vm_hosts connection: local gather_facts: no tasks: - name: Perform a VM host upgrade juniper.device.software: local_package: "junos-vmhost-install-qfx-x86-64-18.1R1.9.tgz" vmhost: True register: response - name: Print the response debug: var: response
How to Perform a Unified ISSU or NSSU
The software
and juniper_junos_software
modules
support performing a unified in-service software upgrade (unified ISSU) or a
nonstop software upgrade (NSSU) on devices that support the feature and meet the
necessary requirements. For more information about the unified ISSU and NSSU
features, see the software documentation for your product.
The unified ISSU feature enables you to upgrade between two different Junos OS
releases with no disruption on the control plane and with minimal disruption of
traffic. To perform a unified in-service software upgrade, the
software
or juniper_junos_software
module
must include the issu: True
argument. For example:
--- - name: Perform a Junos OS software upgrade hosts: mx1 connection: local gather_facts: no tasks: - name: Perform a unified ISSU juniper.device.software: local_package: "junos-install-mx-x86-64-17.2R1.13.tgz" issu: True register: response - name: Print the response debug: var: response
The NSSU feature enables you to upgrade the Junos OS software running on a switch
or Virtual Chassis with redundant Routing Engines with minimal disruption to
network traffic. To perform a nonstop software upgrade, the
software
or juniper_junos_software
module
must include the nssu: True
argument. For example:
--- - name: Perform a Junos OS software upgrade hosts: ex1 connection: local gather_facts: no tasks: - name: Perform an NSSU juniper.device.software: local_package: "jinstall-ex-4300–17.3R1.10-signed.tgz" nssu: True register: response - name: Print the response debug: var: response
Example: Use Ansible to Install Software
This example uses the software
module in the
juniper.device
collection to install a software image on a
Junos device.
Requirements
This example uses the following hardware and software components:
-
Configuration management server running Ansible 2.10 or later with the
juniper.device
collection installed -
Junos device with NETCONF enabled and a user account configured with appropriate permissions
-
SSH public/private key pair configured for the appropriate user on the Ansible control node and Junos device
-
Existing Ansible inventory file with required hosts defined
Overview
This example presents an Ansible playbook that uses the
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 node, 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 Junos device using the default NETCONF port 830. If the
control node fails to establish a NETCONF session with a device during playbook
execution, then it skips the remaining tasks in the play for that device.
The Install Junos OS package
task executes the
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 Junos device. 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 of the Junos OS
software package on the Ansible control node. 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 software
module reboots each
Routing Engine after the installation completes; however, this task explicitly
sets reboot: True
for clarity.
The task stores the module result in the response
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 node 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
To create a playbook that uses the software
module to
install a software image on a Junos device:
-
Include the boilerplate for the playbook and this play, which executes the modules locally.
--- - name: Install Junos OS hosts: mx1 connection: local gather_facts: no
-
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: "20.3R1.8" OS_package: "junos-install-mx-x86-64-20.3R1.8.tgz" pkg_dir: "software" log_dir: "{{ playbook_dir }}" netconf_port: 830 wait_time: 3600
-
(Optional) Create a task to verify NETCONF connectivity.
tasks: - name: Checking NETCONF connectivity wait_for: host: "{{ inventory_hostname }}" port: "{{ netconf_port }}" timeout: 5
-
Create the task to install the Junos OS package on the device and notify the handler.
- name: Install Junos OS package juniper.device.software: version: "{{ OS_version }}" local_package: "{{ pkg_dir }}/{{ OS_package }}" reboot: True validate: True logfile: "{{ log_dir }}/software.log" register: response notify: - wait_reboot
-
(Optional) Create a task to print the module response.
- name: Print response debug: var: response
-
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 response.check_mode
Results
On the Ansible control node, 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 connection: local gather_facts: no vars: OS_version: "20.3R1.8" OS_package: "junos-install-mx-x86-64-20.3R1.8.tgz" pkg_dir: "software" log_dir: "{{ playbook_dir }}" 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.device.software: version: "{{ OS_version }}" local_package: "{{ pkg_dir }}/{{ OS_package }}" reboot: True validate: True logfile: "{{ log_dir }}/software.log" register: response 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 response.check_mode
Execute the Playbook
To execute the playbook:
-
Issue the
ansible-playbook
command on the control node, and provide the playbook path and any desired options.user@ansible-cn:~/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, "match_groupdict": {}, "match_groups": [], "path": null, "port": 830, "search_regex": null, "state": "started"} TASK [Install Junos OS package] ******************************************** changed: [mx1a.example.com] => {"changed": true, "check_mode": false, "msg": "Package /home/user/ansible/software/junos-install-mx-x86-64-20.3R1.8.tgz successfully installed. Response from device is: \nVerified junos-install-mx-x86-64-20.3R1.8 signed by PackageProductionECP256_2020 method ECDSA256+SHA256\n [...output truncated...] NOTICE: 'pending' set will be activated at next reboot... Reboot successfully initiated. Reboot message: Shutdown NOW! [pid 83918]"} TASK [Print response] ****************************************************** ok: [mx1a.example.com] => { "response": { "changed": true, "check_mode": false, "failed": false, "msg": "Package /home/user/ansible/software/junos-install-mx-x86-64-20.3R1.8.tgz successfully installed. Response from device is: \nVerified junos-install-mx-x86-64-20.3R1.8 signed by PackageProductionECP256_2020 method ECDSA256+SHA256\nVerified manifest signed by PackageProductionECP256_2020 method ECDSA256+SHA256\n [...output truncated...] NOTICE: 'pending' set will be activated at next reboot... Reboot successfully initiated. Reboot message: Shutdown NOW! [pid 83918]" } } RUNNING HANDLER [wait_reboot] ********************************************** ok: [mx1a.example.com] => {"changed": false, "elapsed": 209, "match_groupdict": {}, "match_groups": [], "path": null, "port": 830, "search_regex": null, "state": "started"} PLAY RECAP ***************************************************************** mx1a.example.com : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Verification
Verify 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-cn:~/ansible$ cat software.log 2020-12-11 00:24:49,478 - paramiko.transport - INFO - Connected (version 2.0, client OpenSSH_7.5) 2020-12-11 00:24:49,632 - paramiko.transport - INFO - Authentication (publickey) successful! 2020-12-11 00:24:57,923 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 344145920 / 3441301038 (10%) 2020-12-11 00:25:05,976 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 688275456 / 3441301038 (20%) 2020-12-11 00:25:13,949 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 1032404992 / 3441301038 (30%) 2020-12-11 00:25:22,051 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 1376534528 / 3441301038 (40%) 2020-12-11 00:25:30,357 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 1720664064 / 3441301038 (50%) 2020-12-11 00:25:38,360 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 2064793600 / 3441301038 (60%) 2020-12-11 00:25:46,575 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 2408923136 / 3441301038 (70%) 2020-12-11 00:25:54,983 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 2753052672 / 3441301038 (80%) 2020-12-11 00:26:03,066 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 3097182208 / 3441301038 (90%) 2020-12-11 00:26:11,330 - jnpr.ansible_module.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-20.3R1.8.tgz': 3441301038 / 3441301038 (100%) 2020-12-11 00:26:11,331 - jnpr.ansible_module.software - INFO - [mx1a.example.com] after copy, computing checksum on remote package: /var/tmp/junos-install-mx-x86-64-20.3R1.8.tgz ... 2020-12-11 00:26:27,623 - jnpr.ansible_module.software - INFO - [mx1a.example.com] checksum check passed. 2020-12-11 00:26:27,623 - jnpr.ansible_module.software - INFO - [mx1a.example.com] validating software against current config, please be patient ... ... 2020-12-11 00:30:55,725 - jnpr.ansible_module.software - INFO - [mx1a.example.com] software validate package-result: 0 Output: Removing /packages/sets/previous Verified junos-install-mx-x86-64-20.3R1.8 signed by PackageProductionECP256_2020 method ECDSA256+SHA256 Verified manifest signed by PackageProductionECP256_2020 method ECDSA256+SHA256 Checking PIC combinations Adding junos-mx-x86-64-20.3R1.8 ... ... Validating against /config/juniper.conf.gz mgd: commit complete Validation succeeded 2020-12-11 00:30:55,725 - jnpr.ansible_module.software - INFO - [mx1a.example.com] installing software on RE0 ... please be patient ... ... 2020-12-11 00:33:56,203 - jnpr.ansible_module.software - INFO - [mx1a.example.com] software pkgadd package-result: 0 Output: Verified junos-install-mx-x86-64-20.3R1.8 signed by PackageProductionECP256_2020 method ECDSA256+SHA256 ... 2020-12-11 00:33:56,250 - jnpr.ansible_module.software - INFO - [mx1a.example.com] installing software on RE1 ... please be patient ... ... 2020-12-11 00:37:18,562 - jnpr.ansible_module.software - INFO - [mx1a.example.com] software pkgadd package-result: 0 Output: Pushing /var/tmp/junos-install-mx-x86-64-20.3R1.8.tgz to re1:/var/tmp/junos-install-mx-x86-64-20.3R1.8.tgz Verified junos-install-mx-x86-64-20.3R1.8 signed by PackageProductionECP256_2020 method ECDSA256+SHA256 ... <?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:f6f6a59c-fedd-49fc-9cb3-9848f419a5b7"> <request-reboot><both-routing-engines/><in>0</in></request-reboot></nc:rpc>]]>]]> 2020-12-11 00:37:19,880 - ncclient.operations.rpc - INFO - [host mx1a.example.com session-id 46151] Requesting 'CloseSession'
Meaning
The log file contents indicate that the image was successfully copied and installed on both Routing Engines on the target device.
Juniper.junos
Release 2.0.0, the
juniper_junos_software
module replaces the functionality of
the junos_install_os
module.