Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

Using Ansible to Configure Devices Running Junos OS

 

Juniper Networks provides support for using Ansible to manage the configuration of devices running Junos OS. The juniper_junos_config module in the Juniper.junos role and the junos_config Ansible core module enable you to configure devices running Junos OS. The user account that is used to make configuration changes must have permissions to change the relevant portions of the configuration on each device.

Note

Starting in Ansible for Junos OS Release 2.0.0, the juniper_junos_config module combines and replaces the functionality of the junos_commit, junos_get_config, junos_install_config, and junos_rollback modules.

The following sections discuss how to use the juniper_junos_config module to modify and commit the configuration on devices running Junos OS. For information about the junos_config Ansible core module, see https://docs.ansible.com/ansible/latest/junos_config_module.html.

juniper_junos_config Module Overview

The juniper_junos_config module in the Juniper.junos role enables you to modify and commit the configuration on devices running Junos OS. You can load new configuration data, roll the configuration back to a previous version, or load a rescue configuration. To modify the configuration, the module argument list must include either the load parameter to load new configuration data or the rollback parameter to revert to either 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 juniper_junos_config module makes changes to the candidate configuration database using configure exclusive mode, which automatically locks and unlocks the configuration database. For more information about specifying the configuration mode, see Specifying the Configuration Mode.

When loading new configuration data, you can specify the configuration mode, the load operation, and the source and format of the changes. The value of the load argument defines the load operation used to load the configuration data into the candidate configuration. The juniper_junos_config module supports many of the same load actions that are available in the Junos OS command-line interface (Junos OS CLI), including merge, override, replace, set, and update. For more information, see Specifying the Load Action.

The juniper_junos_config module enables you to configure devices running Junos OS using one of the standard, supported formats. You can provide configuration data as strings or as files containing either configuration data snippets 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. For information about specifying the format of the configuration data, see Specifying the Format of the Configuration Data to Load.

When you include the load parameter, you must also specify the source of the configuration data to load. You can specify the source as a list of configuration strings, a file on the local Ansible server, a Jinja2 template, or a URL reachable from the client device by including the lines, src, template, or url parameter, respectively. For more information about specifying the source of the configuration data, see the following sections:

The juniper_junos_config module 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:

By default, the juniper_junos_config module automatically commits the changes to the configuration. To alter this behavior or supply additional commit options, see Committing the Configuration.

By default, when the juniper_junos_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.

Specifying the Configuration Mode

You can specify the configuration mode to use when modifying the candidate configuration database. By default, the juniper_junos_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.

To explicitly specify the mode, include the config_mode parameter in the juniper_junos_config module argument list. Supported modes include exclusive and private. Both modes discard any uncommitted changes upon exiting.

The following playbook uses configure private mode to modify the configuration:

user@ansible-cm:~/ansible$ ansible-playbook configure-script.yaml

Specifying the Load Action

The juniper_junos_config module supports loading configuration changes using a load merge, load replace, load override, load set, or load update operation. You specify the load operation by including the load parameter in the module argument list and setting it to the value of the corresponding load operation. Table 1 summarizes the parameter settings required for each type of load operation

Table 1: 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 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.

Specifying the Format of the Configuration Data to Load

The juniper_junos_config module enables you to configure devices running Junos OS using one of the standard, supported formats. You can provide configuration data as strings or files. Files can contain either configuration data snippets 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.

Note

Starting in Junos OS Release 16.1R1 and later releases, device running Junos OS support loading configuration data in JSON format.

The juniper_junos_config module attempts to auto-detect the format of configuration data supplied as strings using 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 2 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 2: 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 juniper_junos_config load argument to 'override' or 'update', you cannot use the Junos OS set command format.

Loading Configuration Data as Strings

The juniper_junos_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 juniper_junos_config 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 Specifying the Format of the Configuration Data to Load. If you include the format parameter in the module argument list, it overrides the auto-detect 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 CLI text format. In this case, load: "merge" is used.

Loading Configuration Data from a Local or Remote File

The juniper_junos_config module enables you to load configuration data from a file. The file can reside on the Ansible control machine, on the client device, or at a URL that is reachable from the client device. When you load configuration data from a file, you must indicate the format of the configuration data in the file and the location of 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 Loading 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 argument list or by adding the appropriate extension to the configuration data file. For information about specifying the format, see Specifying the Format of the Configuration Data to Load. If you include the format parameter in the module argument list, it overrides the format indicated by the file extension. 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 3 outlines the juniper_junos_config module arguments that you can include to specify the location of the file.

Table 3: Specifying the Location of the Configuration File

Module Argument

Description

src

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

url

Absolute or relative path to a file on the client device, or an FTP location, or a Hypertext Transfer Protocol (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 machine, 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 managed device running Junos OS, 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 a Hypertext Transfer Protocol (HTTP) URL.

  • A local filename can have 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.

  • A filename on an FTP server has the following form:

  • A filename 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.

Loading Configuration Data Using a Jinja2 Template

The juniper_junos_config module enables you to render configuration data from a Jinja2 template file on the Ansible control machine and load and commit the configuration on a device running Junos OS. 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 juniper_junos_config 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 juniper_junos_config module argument list. Set the template argument to the path of the Jinja2 template file. The value of the vars argument is a dictionary of keys and values that are required to render the Jinja2 template. You must also include the format parameter when the file extension does not indicate the format of the data. For information about specifying the format, see Specifying the Format of the Configuration Data to Load.

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

To use the juniper_junos_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 parameter. 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:

Loading the Rescue Configuration

A rescue configuration allows 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_junos_config module enables you to revert to an existing rescue configuration on devices running Junos OS. To load and commit the rescue configuration on devices running Junos OS, include the rollback: "rescue" module argument. For example:

Rolling Back the Configuration

Devices running Junos OS 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_junos_config module enables you to roll back to a previously committed configuration on devices running Junos OS. To roll back the configuration and commit it, include the rollback module 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.

user@ansible-cm:~/ansible$ ansible-playbook configuration-rollback.yaml

Committing the Configuration

By default, when you use the juniper_junos_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.

Table 4 outlines the juniper_junos_config module arguments that you can use to customize the commit operation.

Table 4: juniper_junos_config Commit Options

Module Argument

Description

Default value for load or 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

confirmed: minutes

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

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

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.

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

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 juniper_junos_config module with the check: true or commit: true argument.

By default, the juniper_junos_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 this 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.

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. The second task issues a commit check operation to confirm the commit.

Ignoring Warnings When Configuring Devices

The juniper_junos_config module enables you to modify and commit the configuration on devices running Junos OS. In some cases, the RPC reply might contain <rpc-error> elements with a severity of warning or higher that cause the module to raise an RpcError exception, thus causing 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 juniper_junos_config module to suppress RpcError exceptions that are raised for warnings by including the ignore_warning parameter in the module argument list. The ignore_warning argument takes a Boolean, a string, or a list of strings.

To instruct the juniper_junos_config module to ignore all warnings for load and commit operations performed by the module, include the ignore_warning: true argument in the module argument list. 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 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 of warning and each warning in the response matches one or more of the specified strings.

Example: Using Ansible to Configure Devices

Ansible and Juniper Networks provide collections of Ansible modules that you can use to manage the configuration of devices running Junos OS. This example outlines how to use Ansible to make configuration changes on devices running Junos OS through NETCONF over SSH.

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 the device running Junos OS

  • Existing Ansible inventory file with required hosts defined

Overview

The juniper_junos_config module in the Juniper.junos role enables you to manage the configuration on devices running Junos OS. The user account executing the module must have permissions to change the relevant portions of the configuration on each target device. When configuring a device with the juniper_junos_config module, supported formats for the configuration data include CLI configuration statements, Junos XML elements, Junos OS set commands, and JSON.

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

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

The task to configure the device executes the juniper_junos_config module provided that the NETCONF check was successful. The juniper_junos_config module requires a host argument, but because it uses the {{ inventory_hostname }} variable by default, this argument is not explicitly included.

The load: "merge" module argument loads the new configuration data into the candidate configuration using a load merge operation. By default, the juniper_junos_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

Creating the Configuration Data File

Step-by-Step Procedure

To create the configuration data file that is used by the juniper_junos_config 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, for example:

Creating the Ansible Playbook

Step-by-Step Procedure

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

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

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

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

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

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.

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 ansible-pb-junos-config.yaml

Verification

Verifying the Configuration

Purpose

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

Action

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

user@dc1a> show configuration system scripts
user@dc1a> show system commit
user@dc1a> show log messages

Troubleshooting Playbook Errors

Troubleshooting 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 juniper_junos_config timeout argument to an appropriate value and re-run the playbook.

Troubleshooting 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 device running Junos OS to give the current user the necessary permissions to make the changes.

Troubleshooting 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 device running Junos OS to give the current user the necessary permissions to make the changes.

Release History Table
Release
Description
Starting in Ansible for Junos OS Release 2.0.0, the juniper_junos_config module combines and replaces the functionality of the junos_commit, junos_get_config, junos_install_config, and junos_rollback modules.