Use Ansible to Install Software on Junos Devices
Use the Juniper Networks Ansible modules to install software on Junos devices.
Use Ansible to Install Software
Juniper Networks provides an Ansible module that enables you to install or upgrade the software image on a Junos device. Table 1 outlines the module.
|
Content Set |
Module Name |
|---|---|
|
|
The following sections discuss how to specify the software image location and the general software installation process and options when using the Ansible module 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 juniper.device.software module to install
software on Junos devices, you can download the software package to the Ansible
control node, and the module, by default, copies the package to the target
device before performing the installation. For mixed Virtual Chassis
environments, the software 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 Ansible 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 argument that is appropriate for your installation:
-
local_package—Install software on a standalone Junos device or on members in a non-mixed Virtual Chassis. The argument value is a single string specifying the absolute or relative path to the software image. -
pkg_set—Install software on the members in a mixed Virtual Chassis. The argument value is a list of strings that specify the absolute or relative file paths of the software images, 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
from the Ansible control node 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 (individual
device or Virtual Chassis primary 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 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
ansible.builtin.debug:
var: response
When you execute the 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 when the
validateargument is set totrue.Note:By default, the
softwaremodule does 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 thevalidateargument totrue.Installs the package on each individual Routing Engine, unless
all_reis set tofalse.Reboots each upgraded Routing Engine, unless the
rebootargument is set tofalse.
The software module enables 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.device.software module performs 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 juniper.device.software module to install
software on a device, the module invokes the appropriate RPC for the included
installation arguments. For example, the module invokes 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 module supports explicit arguments for many of the installation options, for
example, the validate option. The module also supports 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 module, see the API reference documentation for the 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.
You should only include installation options that are supported on the target Junos device for the given RPC.
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
ansible.builtin.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
requires a VM Host installation package
(junos-vmhost-install-x.tgz) and
upgrades the host OS and compatible Junos OS. In the CLI, you perform the
upgrade using the request vmhost software add operational mode
command, which corresponds to the
<request-vmhost-package-add> RPC.
The juniper.device.software module supports 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 specified 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
ansible.builtin.debug:
var: response
How to Perform a Unified ISSU or NSSU
The juniper.device.software module supports 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 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
ansible.builtin.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 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
ansible.builtin.debug:
var: response
How to Install Software on an EX Series Virtual Chassis Member
Generally, when you upgrade a non-mixed EX Series Virtual Chassis, you follow the
installation process outlined in Installation Process Overview to upgrade the entire Virtual Chassis. However, there might
be times when you need to install software on specific member switches in the
Virtual Chassis. Starting with Release 1.0.3 of the
juniper.device collection, you can install a software
package on individual member switches in a non-mixed EX Series Virtual Chassis.
To install software on specific members, include the member_id
argument and define a list of strings that specify the member IDs. The system
installs the software package from the Virtual Chassis primary device onto the
specified members.
The following Ansible playbook upgrades the software on member 0 and member 1 in the EX Series Virtual Chassis:
---
- name: Upgrade specific EX VC members
hosts: ex_vc
connection: local
gather_facts: no
vars:
OS_version: "23.2R1.13"
OS_package: "junos-install-ex-x86-64-23.2R1.13.tgz"
pkg_dir: "software"
log_dir: /var/log/
tasks:
- name: Check NETCONF connectivity
ansible.builtin.wait_for:
host: "{{ inventory_hostname }}"
port: 830
timeout: 5
- name: Install package on EX VC members
juniper.device.software:
version: "{{ OS_version }}"
local_package: "{{ pkg_dir }}/{{ OS_package }}"
member_id: ["0","1"]
logfile: "{{ log_dir }}/software.log"
Example: Use Ansible to Install Software
This example uses the juniper.device.software module 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.17 or later with the
juniper.devicecollection 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
juniper.device.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 Check NETCONF connectivity task,
which utilizes the ansible.builtin.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 juniper.device.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: "23.4R1.9" OS_package: "junos-install-mx-x86-64-23.4R1.9.tgz" pkg_dir: "software" log_dir: "{{ playbook_dir }}" netconf_port: 830 wait_time: 3600 -
(Optional) Create a task to verify NETCONF connectivity.
tasks: - name: Check NETCONF connectivity ansible.builtin.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 ansible.builtin.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 ansible.builtin.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: "23.4R1.9"
OS_package: "junos-install-mx-x86-64-23.4R1.9.tgz"
pkg_dir: "software"
log_dir: "{{ playbook_dir }}"
netconf_port: 830
wait_time: 3600
tasks:
- name: Check NETCONF connectivity
ansible.builtin.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
ansible.builtin.debug:
var: response
handlers:
- name: wait_reboot
ansible.builtin.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-playbookcommand 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 [Check 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-23.4R1.9.tgz successfully installed. Response from device is: \nVerified junos-install-mx-x86-64-23.4R1.9 signed by PackageProductionECP256_2023 method ECDSA256+SHA256\n [...output truncated...] NOTICE: 'pending' set will be activated at next reboot... Reboot successfully initiated. Reboot message: Shutdown NOW! [pid 79385]"} 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-23.4R1.9.tgz successfully installed. Response from device is: \nVerified junos-install-mx-x86-64-23.4R1.9 signed by PackageProductionECP256_2023 method ECDSA256+SHA256\nVerified auto-snapshot signed by PackageProductionECP256_2023 method ECDSA256+SHA256\n [...output truncated...] NOTICE: 'pending' set will be activated at next reboot... Reboot successfully initiated. Reboot message: Shutdown NOW! [pid 79385]" } } RUNNING HANDLER [wait_reboot] ********************************************** ok: [mx1a.example.com] => {"changed": false, "elapsed": 250, "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.
2024-08-23 22:20:49,455 - ncclient.transport.ssh - INFO - Connected (version 2.0, client OpenSSH_7.9) 2024-08-23 22:20:52,950 - ncclient.transport.ssh - INFO - Authentication (publickey) successful! ... 2024-08-23 22:21:00,770 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] computing checksum on local package: /home/user/ansible/software/junos-install-mx-x86-64-23.4R1.9.tgz 2024-08-23 22:21:08,070 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] cleaning filesystem ... ... 2024-08-23 22:21:08,329 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] before copy, computing checksum on remote package: /var/tmp/junos-install-mx-x86-64-23.4R1.9.tgz ... 2024-08-23 22:21:08,491 - paramiko.transport - INFO - Connected (version 2.0, client OpenSSH_7.9) 2024-08-23 22:21:08,958 - paramiko.transport - INFO - Authentication (publickey) successful! 2024-08-23 22:21:16,846 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 363528192 / 3635202890 (10%) 2024-08-23 22:21:24,405 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 727056384 / 3635202890 (20%) 2024-08-23 22:21:31,966 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 1090568192 / 3635202890 (30%) 2024-08-23 22:21:39,652 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 1454096384 / 3635202890 (40%) 2024-08-23 22:21:47,631 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 1817608192 / 3635202890 (50%) 2024-08-23 22:21:55,343 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 2181136384 / 3635202890 (60%) 2024-08-23 22:22:02,878 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 2544648192 / 3635202890 (70%) 2024-08-23 22:22:11,395 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 2908176384 / 3635202890 (80%) 2024-08-23 22:22:19,949 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 3271688192 / 3635202890 (90%) 2024-08-23 22:22:27,522 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] b'junos-install-mx-x86-64-23.4R1.9.tgz': 3635202890 / 3635202890 (100%) 2024-08-23 22:22:27,533 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] after copy, computing checksum on remote package: /var/tmp/junos-install-mx-x86-64-23.4R1.9.tgz ... 2024-08-23 22:22:44,891 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] checksum check passed. 2024-08-23 22:22:44,892 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] validating software against current config, please be patient ... ... 2024-08-23 22:27:52,538 - ncclient.transport.ssh - INFO - [host mx1a.example.com session-id 27526] Received message from host 2024-08-23 22:27:52,542 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] software validate package-result: 0 Output: Verified junos-install-mx-x86-64-23.4R1.9 signed by PackageProductionECP256_2023 method ECDSA256+SHA256 Adding junos-mx-x86-64-23.4R1.9 ... ... Validating against /config/juniper.conf.gz mgd: commit complete Validation succeeded 2024-08-23 22:27:52,542 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] installing software on RE0 ... please be patient ... ... 2024-08-23 22:30:57,510 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] software pkgadd package-result: 0 Output: Verified junos-install-mx-x86-64-23.4R1.9 signed by PackageProductionECP256_2023 method ECDSA256+SHA256 ... NOTICE: 'pending' set will be activated at next reboot... 2024-08-23 22:30:57,510 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] installing software on RE1 ... please be patient ... ... 2024-08-23 22:34:30,228 - jnpr.ansible_module.juniper.device.software - INFO - [mx1a.example.com] software pkgadd package-result: 0 Output: Pushing /var/tmp/junos-install-mx-x86-64-23.4R1.9.tgz to re1:/var/tmp/junos-install-mx-x86-64-23.4R1.9.tgz Verified junos-install-mx-x86-64-23.4R1.9 signed by PackageProductionECP256_2023 method ECDSA256+SHA256 ... NOTICE: 'pending' set will be activated at next reboot... ... 2024-08-23 22:34:30,732 - ncclient.operations.rpc - INFO - [host mx1a.example.com session-id 27526] Requesting 'CloseSession'
Meaning
The log file contents indicate that the image was successfully copied and installed on both Routing Engines on the target device.