ON THIS PAGE
How to Specify the Source Database for the Configuration Data
How to Specify the Scope of the Configuration Data to Return
How to Specify the Format of the Configuration Data to Return
How to Retrieve Configuration Data for Third-Party YANG Data Models
How to Specify Options That Do Not Have an Equivalent Module Argument
How to Compare the Active Configuration to a Previous Configuration
Use the
juniper.device.config
Ansible
Module
to Retrieve or Compare Junos OS Configurations
You can use the
juniper.device.config
Ansible
module to
retrieve or compare configurations on devices running Junos OS and devices running Junos OS
Evolved.
Juniper Networks provides an Ansible module that enables you to manage the configuration of devices running Junos OS and devices running Junos OS Evolved. Table 1 outlines the available module, which you can use to retrieve or compare Junos device configurations.
|
Collection |
Module Set |
Module Name |
|---|---|---|
|
|
You can use the juniper.device.config module to request the complete
configuration. You can also request selected portions of the configuration for both the
native Junos OS configuration as well as for configuration data corresponding to
third-party YANG data models that have been added to the device.
To retrieve the configuration, execute the
juniper.device.config
module with the retrieve parameter. The module’s response includes the
configuration in text format in the config and
config_lines keys, unless the return_output option
is set to false. You can also compare the active configuration with a
previously committed configuration.
The following sections discuss how to use the module to retrieve or compare configurations.
How to Specify the Source Database for the Configuration Data
When you use the juniper.device.config module to retrieve the
configuration, you must include the retrieve parameter in the
module’s argument list. The retrieve parameter specifies the
configuration database from which to retrieve the data. You can set
retrieve to the following values to return configuration
data from the respective database:
-
candidate—Retrieve data from the candidate configuration. -
committed—Retrieve data from the committed configuration.
Committed Configuration Database
The following playbook retrieves the complete committed configuration in text format for each device in the inventory group:
---
- name: Get Junos OS configuration
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get committed configuration
juniper.device.config:
retrieve: committed
register: response
- name: Print result
ansible.builtin.debug:
var: response
Candidate Configuration Database
The following playbook retrieves the complete candidate configuration in text format for each device in the inventory group. The module returns an error if the database is locked or modified.
---
- name: Get Junos OS configuration
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get candidate configuration
juniper.device.config:
retrieve: candidate
register: response
- name: Print result
ansible.builtin.debug:
var: response
How to Specify the Scope of the Configuration Data to Return
In addition to retrieving the complete Junos OS configuration, you can retrieve
specific portions of the configuration by using the
filter
parameter. The filter parameter’s value is a string containing
the subtree filter that selects the configuration statements to return. The
subtree filter returns the configuration data that matches the selection
criteria. If you request multiple hierarchies, the value of
filter must represent all levels of the configuration
hierarchy starting at the root (represented by the
<configuration> element) down to each element to
display.
The following playbook retrieves and prints the configuration at the
[edit interfaces] and [edit protocols]
hierarchy levels in the committed configuration database for each device:
---
- name: Get Junos OS configuration hierarchies
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get selected configuration hierarchies
juniper.device.config:
retrieve: committed
filter: "<configuration><interfaces/><protocols/></configuration>"
register: response
- name: Print result
ansible.builtin.debug:
var: responseThe following playbook retrieves and prints the configuration for the ge-1/0/1 interface:
---
- name: Get Junos OS configuration hierarchies
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get selected configuration hierarchies
juniper.device.config:
retrieve: committed
filter: "<interfaces><interface>
<name>ge-1/0/1</name></interface></interfaces>"
register: response
- name: Print result
ansible.builtin.debug:
var: responseThe following playbook retrieves and prints the configuration committed at the
[edit system services] hierarchy level:
---
- name: Get Junos OS configuration hierarchies.
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get selected configuration hierarchies
juniper.device.config:
retrieve: committed
filter: "system/services"
register: response
- name: Print result
ansible.builtin.debug:
var: responseHow to Specify the Format of the Configuration Data to Return
When you use the juniper.device.config module to retrieve the
configuration, the module invokes the Junos XML protocol
<get-configuration> operation, which can return
configuration data in different formats. By default, the module returns
configuration data as formatted text. The text format uses newlines, tabs and
other white space, braces, and square brackets to indicate the hierarchical
relationships between the statements.
To specify the format in which to return the configuration data, set
the
module's format parameter equal to the required format.
Acceptable values include:
-
json—JavaScript Object Notation (JSON) -
set—Junos OSsetcommands -
text—Formatted text (default) -
xml—Junos XML elements
In the playbook output, the config and
config_lines keys contain the configuration in the
requested format. If you request Junos XML or JSON format, the
config_parsed key contains the equivalent configuration in
JSON format.
The following playbook retrieves the complete committed configuration for each device in the inventory group in XML format:
---
- name: Get Junos OS configuration.
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get configuration in XML format
juniper.device.config:
retrieve: committed
format: xml
register: response
- name: Print result
ansible.builtin.debug:
var: responseHow to Handle Large Configurations
Junos devices return RPC responses in XML format. Even when you request data in JSON, set, or text format, the NETCONF server's response wraps the data in XML tags. Thus, the Ansible modules must use an XML parser to handle the RPC reply. XML parsers often impose safety limits on the document depth and the size of single text nodes. These limits are a built-in security measure to prevent malicious attacks, memory exhaustion, and general performance issues.
Network devices can have large, complex configurations and extensive command and RPC output. By default, the XML parser imposes a size limit for text nodes, which is generally around 10 MB. When a single text node exceeds the size limit, the parser generates an error. For example:
TASK [Retrieve the committed configuration] **************************************** [ERROR]: Task failed: Module failed: Resource limit exceeded: Text node too long, try XML_PARSE_HUGE, line 83442, column 21 (<string>, line 83442)
Generally, if you request configuration, command, or RPC data in XML format, the
document contains many small XML nodes, and the parser doesn't encounter this
limit except in rare cases. However, if you request the same data in JSON, set,
or text format, the device returns the data wrapped in one or more XML tags. For
example, in addition to the <rpc-reply> tag, the device
wraps set and text configuration data in a
<configuration-set> tag or a
<configuration-text> tag as appropriate. Similarly,
the device encloses command output in text format in an
<output> element. For extensive data, the response
can result in a single XML text node that exceeds the parser's default
limits.
When you request large configurations or extensive command or RPC output in any format, the XML parser handles the RPC reply. Thus, you can encounter the node-size limit error for all formats, although it is rarer for XML data. In these cases, we recommend returning the response as XML.
If you require one of the other formats, you can override the parser limits by
including the huge_tree: true module argument. When you use
huge_tree: true, it enables the
XML_PARSE_HUGE option, which ignores limits on the maximum
text node size, the maximum attribute size, and the maximum depth. As a result,
the parser can process large XML documents, deep XML trees, and large text
nodes.
The following playbook retrieves the committed configuration in
set format for the devices in the inventory group. The
juniper.device.config module arguments include
huge_tree: true. With this option, the task succeeds even
if a specific response exceeds the parser's default node-size limit.
---
- name: Handle large configurations
hosts: junos
connection: local
gather_facts: false
tasks:
- name: Retrieve the committed configuration
juniper.device.config:
retrieve: committed
diff: false
check: false
commit: false
format: set
huge_tree: true
register: response
- name: Print response
ansible.builtin.debug:
var: responseHow to Retrieve Configuration Data for Third-Party YANG Data Models
You can load standardized or custom YANG modules on Junos devices to add data models that are not natively supported by Junos OS but can be supported by translation. You configure nonnative data models in the candidate configuration using the syntax defined for those models. When you commit the configuration, the data model’s translation scripts translate that data and commit the corresponding Junos OS configuration as a transient change in the checkout configuration.
The candidate and active configurations contain the configuration data for
nonnative YANG data models in the syntax defined by those models. You can use
the juniper.device.config module to retrieve configuration data
for standard (IETF, OpenConfig) and custom YANG data models in addition to
retrieving the native Junos OS configuration. By default, the module's reply
does not include configuration data for third-party YANG data models.
To retrieve configuration data that is defined by a nonnative YANG data model in
addition to retrieving the Junos OS configuration, execute the module with the
model parameter, and include the namespace
parameter when appropriate. The model argument takes one of the
following values:
-
custom—Retrieve configuration data that is defined by custom YANG data models. You must include thenamespaceargument when retrieving data for custom YANG data models. -
ietf—Retrieve configuration data that is defined by IETF YANG data models. -
openconfig—Retrieve configuration data that is defined by OpenConfig YANG data models. -
True—Retrieve all configuration data, including the complete Junos OS configuration and data from any YANG data models.
If the model argument specifies ietf or
openconfig, the module automatically uses the appropriate
namespace. If you specify model: custom to retrieve data for a
custom YANG data model, you must also include the namespace
argument with the corresponding namespace.
If you include the model argument with the value
custom, ietf, or
openconfig and also include the filter
argument to return a specific XML subtree, Junos OS only returns the matching
hierarchy from the nonnative data model. If the Junos OS configuration contains
a hierarchy of the same name, for example "interfaces", it is not included in
the reply. The filter option is not supported when using
model: True.
When you use the
juniper.device.config
module to retrieve nonnative configuration data, you can only specify the format
of the returned data if you also include the filter parameter.
If you omit the filter parameter, you must specify
format: xml.
The following playbook retrieves the OpenConfig interfaces
configuration hierarchy from the committed configuration. If you omit the
filter argument, the RPC returns the complete Junos OS and
OpenConfig configurations.
---
- name: Retrieve OpenConfig configuration
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Retrieve the OpenConfig interfaces configuration
juniper.device.config:
retrieve: committed
model: openconfig
filter: interfaces
format: xml
register: response
- name: Print result
ansible.builtin.debug:
var: responseThe following task retrieves the l2vpn configuration hierarchy
from the committed configuration for a custom YANG data model with the given
namespace:
tasks:
- name: Retrieve custom configuration
juniper.device.config:
retrieve: committed
model: custom
filter: l2vpn
remove_ns: False
namespace: http://yang.juniper.net/customyang/l2vpn
format: xml
register: responseThe following task retrieves the complete Junos OS committed configuration as well as the configuration data for other YANG data models that have been added to the device:
tasks:
- name: Retrieve Junos OS and all third-party configuration data
juniper.device.config:
retrieve: committed
model: True
format: xml
register: responseHow to Specify Options That Do Not Have an Equivalent Module Argument
When you use the juniper.device.config module to retrieve the
configuration, the module invokes the Junos XML protocol
<get-configuration> operation. The module supports
explicit arguments for many of the <get-configuration>
attributes, for example, the format attribute. The module also
supports the options argument, which enables you to include any
additional <get-configuration> attributes that do not
have an equivalent module argument. The options argument takes
a dictionary of key/value pairs of any attributes supported by the
<get-configuration> operation.
For the complete list of attributes supported by the Junos XML protocol
<get-configuration> operation, see <get-configuration>.
For example, the
juniper.device.config
module retrieves data from the pre-inheritance configuration, in which the
<groups>, <apply-groups>,
<apply-groups-except>, and
<interface-range> tags are separate elements in the
configuration output. To retrieve data from the post-inheritance configuration,
you can include the options argument with
inherit: inherit. The post-inheritance configuration
displays statements that are inherited from user-defined groups and ranges as
children of the inheriting statements,
The following playbook retrieves the configuration data at the [edit
system services] hierarchy level from the post-inheritance
committed configuration. In the post-inheritance configuration, statements
configured under group hierarchy levels such as [edit groups global
system services] are inherited under [edit system
services] and returned in the retrieved configuration data.
---
- name: Get Junos OS configuration hierarchies
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get selected hierarchy from the post-inheritance configuration
juniper.device.config:
retrieve: committed
filter: system/services
options:
inherit: inherit
register: response
- name: Print result
ansible.builtin.debug:
var: responseHow to Save Configuration Data to a File
When you use the juniper.device.config module to retrieve the
configuration, you can save the returned configuration data in a file on the
local Ansible control node. To save the data to a file, include the module’s
dest_dir or dest parameter. The
dest_dir option specifies a directory path. The
dest option can specify both a path and a filename. If an
output file already exists with the target name, the module overwrites the
file.
To specify the directory in which to save the retrieved configurations, set the
dest_dir argument to the path of the target directory. The
configuration for each device is stored in a separate file named
hostname.config.
The following playbook retrieves the committed configuration from all devices in the inventory group. The playbook saves each device configuration to a separate file in the configs directory under the playbook directory on the Ansible control node.
---
- name: Get Junos OS configuration
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Save configuration to a file
juniper.device.config:
retrieve: committed
dest_dir: "{{ playbook_dir }}/configs"To specify the path and filename for the output files, set the
dest argument to the absolute or relative path of the file.
If you include the dest argument, but omit the directory, the
files are saved in the playbook directory. If you retrieve the configuration for
multiple devices, the dest argument must include a variable
such as {{ inventory_hostname }} to differentiate the filename
for each device. If you do not differentiate the filenames, the configuration
file for each device will overwrite the configuration file of the other
devices.
The following playbook retrieves the [edit system services]
hierarchy from the committed configuration database on all devices in the
inventory group. The playbook saves each device configuration to a separate file
in the playbook directory on the Ansible control node. Each file is uniquely
identified by its hostname.
---
- name: Get Junos OS configuration
hosts: junos
connection: local
gather_facts: no
tasks:
- name: Get selected configuration hierarchies and save to file
juniper.device.config:
retrieve: committed
filter: "system/services"
dest: "{{ inventory_hostname }}-system-services-config"If you are saving the configuration data to files and do not want to duplicate
the configuration data in the module’s response, you can you can optionally
include return_output: false in the module’s argument list.
Setting return_output to false causes the
module to omit the config, config_lines, and
config_parsed keys in its response. Doing this might be
necessary if the device returns a significant amount of configuration data.
How to Compare the Active Configuration to a Previous Configuration
The juniper.device.config module enables you to compare the
active configuration to a previously committed configuration, or rollback
configuration. To compare the active configuration to a previous configuration,
include the following module arguments:
juniper.device.config: diff: true rollback: id check: false commit: false
By default, when you include the rollback: id
argument, the module rolls back the configuration, performs a commit check, and
commits the changes. You must include the commit: false
argument to only compare the configurations and prevent the module from loading
and committing the rollback configuration. Including the
check: false argument prevents the unnecessary commit check
operation.
The module returns the diff and diff_lines
keys. The keys contain the configuration differences between the active and
previous configuration in diff or patch format.
-
diff—Dictionary that contains a single key namedpreparedand its value, which is a single multi-line string containing the differences. -
diff_lines—List of single line strings containing the differences.
To save the differences to a file on the local Ansible control node, include the
diffs_file argument, and define the absolute or relative
path of the output file. If you include the diffs_file argument
but omit the directory, the files are saved in the playbook directory. If you
compare the configurations on multiple devices, the diffs_file
argument must include a variable such as
{{ inventory_hostname }} to differentiate the filename for
each device. If you do not differentiate the filenames, the output file for each
device will overwrite the output file of the other devices.
The following playbook prompts for the rollback ID of a previously committed configuration. The playbook then compares the committed configuration to the specified rollback configuration, saves the comparison to a uniquely-named file, and prints the response to standard output.
---
- name: Compare configurations
hosts: dc1
connection: local
gather_facts: no
vars_prompt:
- name: ROLLBACK
prompt: "Rollback ID to compare with active configuration"
private: no
tasks:
- name: Compare active to previous configuration
juniper.device.config:
diff: true
rollback: "{{ ROLLBACK }}"
check: false
commit: false
diffs_file: "{{ inventory_hostname }}-diff-rollback-{{ ROLLBACK }}"
register: response
- name: Print diff
ansible.builtin.debug:
var: responseuser@ansible-cn:~$ ansible-playbook configuration-compare-to-rollback.yaml
Rollback ID to compare with active configuration: 2
PLAY [Compare configurations] *************************************************
TASK [Compare active to previous configuration] ******************************
changed: [dc1a.example.net]
TASK [Print diff] ************************************************************
ok: [dc1a.example.net] => {
"response": {
"changed": true,
"diff": {
"prepared": "\n[edit system services]\n- netconf {\n- ssh;\n- }\n"
},
"diff_lines": [
"",
"[edit system services]",
"- netconf {",
"- ssh;",
"- }"
],
"failed": false,
"msg": "Configuration has been: opened, rolled back, diffed, closed."
}
}
PLAY RECAP ********************************************************************
dc1a.example.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
user@ansible-cn:~$ cat dc1a.example.net-diff-rollback-2
[edit system services]
- netconf {
- ssh;
- }