Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

 
 

Use Ansible to Configure Junos Devices

SUMMARY Use the Juniper Networks Ansible modules to manage the configuration on Junos devices.

Juniper Networks provides an Ansible module that enables you to configure Junos devices. Table 1 outlines the available module. The user account that is used to make configuration changes must have permissions to change the relevant portions of the configuration on each device.

Table 1: Module to Manage the Configuration

Content Set

Module Name

juniper.device collection

config

The following sections discuss how to use the module to modify and commit the configuration on Junos devices.

Module Overview

The juniper.device.config module enables you to perform the following operations on Junos devices:

  • Load configuration data

  • Commit the configuration

  • Roll back the configuration

  • Load the rescue configuration

To modify the configuration, the module’s argument list must include either the load parameter to load new configuration data or the rollback parameter to revert to the rescue configuration or a previously committed configuration. The basic process for making configuration changes is to lock the configuration, load the configuration changes, commit the configuration to make it active, and then unlock the configuration.

By default, the config module makes changes to the candidate configuration database using configure exclusive mode, which automatically locks and unlocks the candidate global configuration. You can also specify a different configuration mode. For example, you can make changes to a private copy of the candidate configuration or to the ephemeral configuration database. For more information about specifying the configuration mode, see How to Specify the Configuration Mode.

When loading new configuration data, in addition to specifying the configuration mode, you can also specify the load operation and the source and format of the changes.

The config module also enables you to load and commit the rescue configuration or roll the configuration back to a previously committed configuration. To load the rescue configuration or a previously committed configuration, you must include the rollback module argument. For more information, see the following sections:

After modifying the configuration, you must commit the configuration to make it the active configuration on the device. By default, the config module commits the changes to the configuration. To alter this behavior or supply additional commit options, see How to Commit the Configuration.

By default, when the config module includes the load or rollback arguments to change the configuration, the module automatically returns the configuration changes in diff or patch format in the module’s response. The differences are returned in the diff and diff_lines variables. To prevent the module from calculating and returning the differences, set the diff module argument to false.

How to Specify the Configuration Mode

You can specify the configuration mode to use when modifying the device configuration. To specify the configuration mode in your task, include the config module’s config_mode parameter. Supported configuration modes include:

  • batch

  • dynamic

  • ephemeral

  • exclusive

  • private

By default, the juniper.device.config module makes changes to the candidate configuration database using configure exclusive mode. Configure exclusive mode locks the candidate global configuration (also known as the shared configuration database) for as long as the module requires to make the requested changes to the configuration. Locking the database prevents other users from modifying or committing changes to the database until the lock is released.

The following examples show how to configure a private copy of the candidate configuration and how to configure the ephemeral database.

Example: config_mode: "private"

The following playbook uses private configuration mode to modify a private copy of the candidate configuration:

Configure the Ephemeral Database

You can use the juniper.device.config module to update the ephemeral configuration database on devices that support this database. The ephemeral database is an alternate configuration database that provides a fast programmatic interface for performing configuration updates on Junos devices.

To open and configure the default instance of the ephemeral configuration database, include the config_mode: "ephemeral" argument. For example:

To open and configure an existing user-defined instance of the ephemeral configuration database, include the config_mode: "ephemeral" argument, and set the ephemeral_instance argument to the name of the instance.

How to Specify the Load Action

The juniper.device.config module supports loading configuration changes using many of the same load operations supported in the Junos OS CLI. You specify the load operation by including the load parameter in the module’s argument list and setting it to the value of the corresponding load operation. Table 2 summarizes the parameter settings required for each type of load operation.

Table 2: Parameters for Specifying the Load Operation

Load Operation

load Argument

Description

load merge

load: "merge"

Merge the loaded configuration with the existing configuration.

load override

load: "override"

Replace the entire configuration with the loaded configuration.

load patch

load: "patch"

Load configuration data from a patch file.

load replace

load "replace"

Merge the loaded configuration with the existing configuration, but replace statements in the existing configuration with those that specify the replace: tag in the loaded configuration. If there is no statement in the existing configuration, the statement in the loaded configuration is added.

load set

load: "set"

Load configuration data that is in set format. The configuration data is loaded line by line and can contain configuration mode commands such as set, delete, and deactivate.

load update

load: "update"

Compare the complete loaded configuration against the existing configuration. Each configuration element that is different in the loaded configuration replaces its corresponding element in the existing configuration. During the commit operation, only system processes that are affected by changed configuration elements parse the new configuration.

How to Specify the Format of the Configuration Data to Load

The juniper.device.config module enables you to configure Junos devices using one of the standard, supported formats. You can provide configuration data as strings or files. Files can contain either configuration data or Jinja2 templates. When providing configuration data within a string, file, or Jinja2 template, supported formats for the data include text, Junos XML elements, Junos OS set commands, and JSON.

The config module attempts to auto-detect the format of configuration data that you supply as strings within the lines argument. However, you can explicitly specify the format for strings by including the format argument. When you provide configuration data in a file or Jinja2 template, you must specify the format of the data either by adding the appropriate extension to the file or by including the format argument.

Table 3 summarizes the supported formats for the configuration data and the corresponding value for the file extension and format parameter. If you include the format argument, it overrides both the auto-detect format for strings and the format indicated by a file extension.

Table 3: Specifying the Format for Configuration Data

Configuration Data Format

File Extension

format Parameter

CLI configuration statements (text)

.conf

"text"

JavaScript Object Notation (JSON)

.json

"json"

Junos OS set commands

.set

"set"

Junos XML elements

.xml

"xml"

Note:

When you set the module’s load argument to 'override' or 'update', you cannot use the Junos OS set command format.

How to Load Configuration Data as Strings

The juniper.device.config module enables you to load configuration data from a list of strings. To load configuration data as strings, include the appropriate load argument and the lines argument. The lines argument takes a list of strings containing the configuration data to load.

The module attempts to auto-detect the format of the lines configuration data. However, you can explicitly specify the format by including the format argument. For information about specifying the format, see How to Specify the Format of the Configuration Data to Load. If you include the format argument, it overrides the auto-detected format.

The following playbook configures and commits two op scripts. In this case, the load argument has the value 'set', because the configuration data in lines uses Junos OS set statement format.

The following playbook configures the same statements using lines with configuration data in text format. In this case, load: "merge" is used.

How to Load Configuration Data from a Local or Remote File

The juniper.device.config module enables you to load configuration data from a file. The file can reside in one of the following locations:

  • Ansible control node

  • Client device

  • URL that is reachable from the client device

When you load configuration data from a file, you must indicate the location of the file and the format of the configuration data in the file. Supported configuration data formats include text, Junos XML elements, Junos OS set commands, and JSON. For information about loading files containing Jinja2 templates, see How to Load Configuration Data Using a Jinja2 Template.

You can specify the format of the configuration data either by explicitly including the format parameter in the module’s argument list or by adding the appropriate extension to the configuration data file. If you specify the format parameter, it overrides the format indicated by the file extension. For information about specifying the format, see How to Specify the Format of the Configuration Data to Load. When the configuration data uses Junos XML format, you must enclose the data in the top-level <configuration> tag.

Note:

You do not need to enclose configuration data that is formatted as ASCII text, Junos OS set commands, or JSON in <configuration-text>, <configuration-set>, or <configuration-json> tags as required when configuring the device directly within a NETCONF session.

Table 4 outlines the module parameters that you can include to specify the location of the file.

Table 4: Specifying the Location of the Configuration File

Module Parameter

Description

src

Absolute or relative path to a file on the Ansible control node. The default directory is the playbook directory.

url

Absolute or relative path to a file on the client device, or an FTP location or an HTTP URL.

The default directory on the client device is the current working directory, which defaults to the user’s home directory.

To load configuration data from a local file on the Ansible control node, set the src argument to the absolute or relative path of the file containing the configuration data. For example:

To load configuration data from a file on the Junos device or from an FTP or HTTP URL, use the url parameter and specify the path of the file that contains the configuration data to load. For example:

The value for url can be an absolute or relative local file path, an FTP location, or an HTTP URL.

  • The file path for a local file on the target device has one of the following forms:

    • /path/filename—File on a mounted file system, either on the local flash disk or on hard disk.

    • a:filename or a:path/filename—File on the local drive. The default path is / (the root-level directory). The removable media can be in MS-DOS or UNIX (UFS) format.

  • The file path for a file on an FTP server has the following form:

  • The file path for a file on an HTTP server has the following form:

In each case, the default value for the path variable is the home directory for the user. To specify an absolute path, the application starts the path with the characters %2F; for example, ftp://username:password@hostname/%2Fpath/filename.

How to Load Configuration Data Using a Jinja2 Template

The juniper.device.config module enables you to render configuration data from a Jinja2 template file on the Ansible control node and load and commit the configuration on a Junos device. Jinja is a template engine for Python that enables you to generate documents from predefined templates. The templates, which are text files in the desired language, provide flexibility through the use of expressions and variables. You can create Junos OS configuration data using Jinja2 templates in one of the supported configuration formats, which includes ASCII text, Junos XML elements, Junos OS set commands, and JSON. The Ansible module uses the Jinja2 template and a supplied dictionary of variables to render the configuration data.

To load and commit configuration data using a Jinja2 template, include the template and vars parameters in the module’s argument list.

  • template—Path of the Jinja2 template file

  • vars—Dictionary of keys and values that are required to render the Jinja2 template

You must also include the format parameter when the template’s file extension does not indicate the format of the data. For information about specifying the format, see How to Specify the Format of the Configuration Data to Load.

For example, the interfaces-mpls.j2 file contains the following Jinja2 template:

To use the juniper.device.config module to load the Jinja2 template, set the template argument to the path of the template file and define the variables required by the template in the vars dictionary. The following playbook uses the Jinja2 template and the variables defined in vars to render the configuration data and load and commit it on the target host. The format parameter indicates the format of the configuration data in the template file.

The module generates the following configuration data, which is loaded into the candidate configuration on the device and committed:

How to Load the Rescue Configuration

A rescue configuration enables you to define a known working configuration or a configuration with a known state that you can restore at any time. You use the rescue configuration when you need to revert to a known configuration or as a last resort if the device configuration and the backup configuration files become damaged beyond repair. When you create a rescue configuration, the device saves the most recently committed configuration as the rescue configuration.

The juniper.device.config module enables you to revert to an existing rescue configuration on Junos devices. To load and commit the rescue configuration on a device, include the module’s rollback: "rescue" argument. For example:

How to Roll Back the Configuration

Junos devices store a copy of the most recently committed configuration and up to 49 previous configurations, depending on the platform. You can roll back to any of the stored configurations. This is useful when configuration changes cause undesirable results, and you want to revert back to a known working configuration. Rolling back the configuration is similar to the process for making configuration changes on the device, but instead of loading configuration data, you perform a rollback, which replaces the entire candidate configuration with a previously committed configuration.

The juniper.device.config module enables you to roll back to a previously committed configuration on Junos devices. To roll back the configuration and commit it, include the module’s rollback argument, and specify the ID of the rollback configuration. Valid ID values are 0 (zero, for the most recently committed configuration) through one less than the number of stored previous configurations (maximum is 49).

The following playbook prompts for the rollback ID of the configuration to restore, rolls back the configuration and commits it, and then prints the configuration changes to standard output:

How to Commit the Configuration

By default, when you use the juniper.device.config module to modify the configuration using either the load or the rollback argument, the module automatically performs a commit check and commits the changes. To prevent the module from performing a commit check or from committing the changes, set the check or commit argument to false, respectively.

You can also customize the commit operation with many of the same options that are available in the Junos OS CLI. Table 5 outlines the module arguments that you can use to specify different commit options.

Table 5: Commit Options

Module Argument

Description

Default value for load and rollback operations

check: boolean

Perform a commit check or confirm a previous confirmed commit operation.

true

check_commit_wait: seconds

Wait the specified number of seconds between the commit check and the commit operation.

comment: "string"

Log a comment for that commit operation in the system log file and in the device’s commit history.

commit: boolean

Commit the configuration changes or confirm a previous confirmed commit operation.

true

commit_empty_changes: boolean

Commit the configuration changes even if there are no differences between the candidate configuration and the committed configuration.

false

commit_force_sync: boolean

Synchronize and commit the configuration on all Routing Engines, even if there are open configuration sessions or uncommitted configuration changes on the other Routing Engine.

false

commit_sync: boolean

Synchronize and commit the configuration on all Routing Engines.

false

confirmed: minutes

Require that a commit operation be confirmed within a specified amount of time after the initial commit. If the commit is not confirmed in the specified time, roll back to the previously committed configuration.

Either the commit: true option or the check: true option must be used to confirm the commit.

timeout: seconds

Wait for completion of the operation using the specified value as the timeout.

30 seconds

Commit Comment

When you commit the configuration, you can include a brief comment to describe the purpose of the committed changes. To log a comment describing the changes, include the comment: "comment string" argument with the message string.

Commit Check

By default, the config module executes both a commit check and a commit operation. The check_commit_wait argument defines the number of seconds to wait between the commit check and commit operations. Include this argument when you need to provide sufficient time for the device to complete the commit check operation and release the configuration lock before initiating the commit operation. If you omit the check_commit_wait argument, there might be certain circumstances in which a device initiates the commit operation before the commit check operation releases its lock on the configuration, resulting in a CommitError and failed commit operation.

Commit Empty Changes

By default, if there are no differences between the candidate configuration and the committed configuration, the module does not commit the changes. To force a commit operation even when there are no differences, include the commit_empty_changes: true argument.

Commit Synchronize

If the device has dual Routing Engines, you can synchronize and commit the configuration on both Routing Engines by including the commit_sync: true argument. To force the commit synchronize operation to succeed even if there are open configuration sessions or uncommitted configuration changes on the other Routing Engine, use the commit_force_sync: true argument. When you include the commit_force_sync: true option, the device terminates any configuration sessions on the other Routing Engine before synchronizing and committing the configuration.

Commit Confirm

To require that a commit operation be confirmed within a specified amount of time after the initial commit, include the confirmed: minutes argument. If the commit is not confirmed within the given time limit, the configuration automatically rolls back to the previously committed configuration. The allowed range is 1 through 65,535 minutes. The confirmed commit operation is useful for verifying that a configuration change works correctly and does not prevent management access to the device. If the change prevents access or causes other errors, the automatic rollback to the previous configuration enables access to the device after the rollback deadline passes. To confirm the commit operation, invoke the config module with the check: true or commit: true argument.

In the following playbook, the first task modifies the configuration, waits 10 seconds between the commit check and the commit operation, and requires that the commit operation be confirmed within 5 minutes. It also logs a comment for the commit. The second task issues a commit check operation to confirm the commit. In a real-world scenario, you might perform validation tasks after the initial commit and only execute the commit confirmation if the tasks pass certain validation criteria.

How to Ignore Warnings When Configuring Devices

The juniper.device.config module enables you to modify and commit the configuration on Junos devices. In some cases, the RPC reply might contain <rpc-error> elements with a severity level of warning or higher that cause the module to raise an RpcError exception. An RpcError exception can cause the load or commit operation to fail.

In certain cases, it might be necessary or desirable to suppress the RpcError exceptions that are raised in response to warnings for load and commit operations. You can instruct the config module to suppress RpcError exceptions that are raised for warnings by including the ignore_warning parameter in the module’s argument list. The ignore_warning argument takes a Boolean, a string, or a list of strings.

To instruct the module to ignore all warnings for load and commit operations performed by the module, include the ignore_warning: true argument. The following example ignores all warnings for load and commit operations.

If you include ignore_warning: true and all of the <rpc-error> elements have a severity level of warning, the application ignores all warnings and does not raise an RpcError exception. However, any <rpc-error> elements with higher severity levels will still raise exceptions.

To instruct the module to ignore specific warnings, set the ignore_warning argument to a string or a list of strings containing the warnings to ignore. The following example ignores two specific warnings:

The module suppresses RpcError exceptions if all of the <rpc-error> elements have a severity level of warning and each warning in the response matches one or more of the specified strings.

Example: Use Ansible to Configure Junos Devices

The juniper.device.config module enables you to manage the configuration on Junos devices. This example uses the config module to make configuration changes on a Junos device through NETCONF over SSH.

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 controller and the Junos device

  • Existing Ansible inventory file with required hosts defined

Overview

This example presents an Ansible playbook that uses the juniper.device.config module to enable a new op script in the configuration of the target Junos devices. The configuration data file, junos-config.conf, contains the relevant configuration data formatted as text.

The playbook includes the Check NETCONF connectivity task, which utilizes the ansible.builtin.wait_for Ansible module to try to establish a NETCONF session with the target device using the NETCONF default port (830). If the control node fails to establish a NETCONF session with a target device during playbook execution, then it skips the remaining tasks in the play for that device.

The playbook uses the juniper.device.file_copy module to copy the new op script from the Ansible control node to the Junos device. The module arguments specify the directory and filename of the script on the local device and the destination directory on the remote device.

The task to configure the device executes the juniper.device.config module provided that the NETCONF check was successful. The load: "merge" argument loads the new configuration data into the candidate configuration using a load merge operation. By default, the config module commits configuration data on a device for load and rollback operations. The module arguments include the comment argument, which records a commit comment in the device’s system log file and commit history.

Configuration

Create the Configuration Data File

Step-by-Step Procedure

To create the configuration data file that is used by the module:

  1. Create a new file with the appropriate extension based on the format of the configuration data, which in this example is text.

  2. Include the desired configuration changes in the file.

Create the Ansible Playbook

Step-by-Step Procedure

To create a playbook that uses the config module to make configuration changes on a Junos device:

  1. Include the playbook boilerplate, which executes the modules locally.

  2. (Optional) Create a task to verify NETCONF connectivity.

  3. Create a task to copy the new op script to the device.

  4. Create the task to load the configuration onto the device and commit it.

  5. (Optional) Create a task to print the response, which includes the configuration changes in diff format.

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.

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.

Verification

Verify the Configuration

Purpose

Verify that the configuration was correctly updated on the Junos device.

Action

Review the Ansible playbook output to see whether the configuration task succeeded or failed. You can also log in to the Junos device and view the configuration, commit history, and log files to verify the configuration and commit, for example:

Troubleshoot Playbook Errors

Troubleshoot Timeout Errors

Problem

The playbook generates a TimeoutExpiredError error message and fails to update the device configuration.

The default time for a NETCONF RPC to time out is 30 seconds. Large configuration changes might exceed this value causing the operation to time out before the configuration can be uploaded and committed.

Solution

To accommodate configuration changes that might require a commit time that is longer than the default RPC timeout interval, set the module’s timeout argument to an appropriate value and re-run the playbook.

Troubleshoot Configuration Lock Errors

Problem

The playbook generates a LockError error message indicating that the configuration cannot be locked. For example:

or

A configuration lock error can occur for the following reasons:

  • Another user has an exclusive lock on the configuration.

  • Another user made changes to the configuration database but has not yet committed the changes.

  • The user executing the Ansible module does not have permissions to configure the device.

Solution

The LockError message string usually indicates the root cause of the issue. If another user has an exclusive lock on the configuration or has modified the configuration, wait until the lock is released or the changes are committed, and execute the playbook again. If the cause of the issue is that the user does not have permissions to configure the device, either execute the playbook with a user who has the necessary permissions, or if appropriate, configure the Junos device to give the current user the necessary permissions to make the changes.

Troubleshoot Configuration Change Errors

Problem

The playbook generates a ConfigLoadError error message indicating that the configuration cannot be modified, because permission is denied.

This error message is generated when the user executing the Ansible module has permission to alter the configuration but does not have permission to alter the requested section of the configuration.

Solution

Either execute the playbook with a user who has the necessary permissions, or if appropriate, configure the Junos device to give the current user the necessary permissions to make the changes.