Connect to Junos Devices Using Ansible
SUMMARY The Juniper Networks Ansible modules enable you to connect to Junos devices using SSH, telnet, or serial console connections.
Juniper Networks provides Ansible modules that you can use to manage Junos devices. The
Juniper Networks modules are distributed through the juniper.device
collection. The
modules can connect to Junos devices using different protocols and Ansible connections,
which are described in this document.
Connection Methods Overview
The juniper.device
collection modules enable you to connect to a
Junos device using SSH, telnet, or a serial console connection. You must use a
serial console connection when your terminal or laptop is physically connected to
the CONSOLE port on a Junos device. You can use SSH or telnet
to connect to the device’s management interface or to a console server that is
directly connected to the device’s CONSOLE port.
New or zeroized devices that have factory-default configurations require access through a console connection. Thus, you can use Ansible to initially configure a device that is not yet configured for remote access by using either a serial console connection when you are directly connected to the device or by using telnet or SSH through a console server that is directly connected to the device.
By default, the juniper.device
modules use SSH to connect to a
device. To use telnet or a serial console connection, set the mode
parameter to the appropriate value. To telnet to a device, set the
mode
argument equal to "telnet"
. To use a
serial console connection, set the mode
argument equal to
"serial"
. Table 1 summarizes
the connection modes, their default values for certain parameters, and any required
Junos OS configuration. The juniper.device
modules support all
connection modes as of their initial release.
Connection Mode |
Value of |
Default Port |
Required Junos OS Configuration |
---|---|---|---|
NETCONF over SSH (default) |
– |
830 |
[edit system services] netconf { ssh; } |
Serial console connection |
|
/dev/ttyUSB0 |
– |
SSH through a console server |
– |
22 |
– |
Telnet to Junos device |
|
23 |
[edit system services] telnet; |
Telnet through a console server |
|
23 |
– |
Before you can access the management interface using telnet or NETCONF over SSH,
you must first enable the appropriate service at the [edit system
services]
hierarchy level. Because telnet uses clear-text passwords
(therefore creating a potential security vulnerability), we recommend that you
use SSH.
When you execute the juniper.device
modules to manage a Junos
device, the remote device must be able to authenticate the Ansible user using
credentials appropriate for the given protocol. For more information, see Authenticate Users Executing Ansible Modules on Junos Devices.
The juniper.device
modules support different Ansible connections
when connecting to Junos devices, including local (per-task) connections and
persistent (per-play) connections. The Ansible connection determines whether Ansible
establishes a separate connection to the host for each task in the play or whether
it establishes a single connection to a host that persists over all tasks in the
play. For information about specifying the Ansible connection, see Understanding Local and Persistent Ansible Connections.
Understanding Local and Persistent Ansible Connections
The Juniper Networks Ansible modules do not require Python on Junos devices
because they use Junos PyEZ and the Junos XML API over NETCONF to interface with
the device. Therefore, to perform operations on Junos devices, you must run
modules locally on the Ansible control node, where Python is installed. You can
run the modules locally by including connection: local
in the
playbook play. When you use connection: local
, Ansible
establishes a separate connection to the host for each task in the play that
performs operations on the host.
The juniper.device
collection modules also support
connection: juniper.device.pyez
for establishing a
persistent connection to a host. When you use a persistent connection, Ansible
still executes the modules locally on the control node, but it only establishes
and maintains a single connection to each host, which persists over the
execution of all tasks in the play. Establishing a persistent connection to a
host can be more efficient for executing multiple tasks than establishing a
separate connection to the host for every task in the play.
Table 2 summarizes the Ansible connections and the content sets that support them.
Ansible connection |
Description |
Content Set Support |
---|---|---|
|
Execute the modules locally on the Ansible control node but establish a separate connection to a host for each task in the play that performs operations on the host. |
|
|
Execute the modules locally on the Ansible control node but establish a persistent connection to a host that persists over the execution of all tasks in the play. |
|
When you use connection: local
, Ansible establishes a separate
connection to a host for each module, which means you can define module-specific
connection and authentication parameters in the module’s argument list. By
contrast, when you use connection: juniper.device.pyez
, the
connection persists across all tasks in the play, and thus you must define the
connection and authentication parameters globally for all modules. You can
define the parameters in the vars:
section of a play, in
addition to providing them through other means, for example, in an SSH
configuration file or in the Ansible inventory file. For additional details, see
Authenticate Users Executing Ansible Modules on Junos Devices.
The following playbook establishes a persistent connection to each host that is
used for all tasks in the play. The user’s credentials, which are stored in an
Ansible vault file, are defined in the play’s vars:
section.
--- - name: Get Device Information hosts: dc1 connection: juniper.device.pyez gather_facts: no vars: host: "{{ inventory_hostname }}" user: "{{ admin_username }}" passwd: "{{ admin_password }}" vars_files: - vault-vars.yaml tasks: - name: Retrieve facts from Junos devices juniper.device.facts: savedir: "{{ playbook_dir }}" - name: Get hardware inventory juniper.device.command: commands: "show chassis hardware" dest_dir: "{{ playbook_dir }}"
Connect to a Device Using SSH
The Juniper Networks Ansible modules support using SSH to connect to a Junos device. You can establish a NETCONF session over SSH on the device’s management interface or you can establish an SSH connection with a console server that is directly connected to the device’s CONSOLE port. The SSH server must be able to authenticate the user using standard SSH authentication mechanisms, as described in Authenticate Users Executing Ansible Modules on Junos Devices. To establish a NETCONF session over SSH, you must also satisfy the requirements outlined in Set up Ansible for Junos OS Managed Nodes.
The Juniper Networks modules automatically query the default SSH configuration
file at ~/.ssh/config, if one exists. You can also include the
ssh_config
parameter to specify a different configuration
file.
When using SSH to connect to a Junos device or to a console server connected to the device, the modules first attempt SSH public key-based authentication and then try password-based authentication. When password-based authentication is used, the supplied password is used as the device password. When SSH keys are in use, the supplied password is used as the passphrase for unlocking the private key. If the SSH private key has an empty passphrase, then a password is not required. However, we do not recommend using SSH private keys with empty passphrases.
The following playbook establishes a NETCONF session over SSH with a Junos device and retrieves the device facts. The playbook uses SSH keys in the default location.
--- - name: Get Device Facts hosts: dc1 connection: local gather_facts: no tasks: - name: Retrieve facts from Junos devices juniper.device.facts: savedir: "{{ playbook_dir }}" - name: Print version ansible.builtin.debug: var: junos.version
The Juniper Networks Ansible modules also enable you to connect to a Junos device
through an SSH connection to a console server. In this case, you must specify
the login credentials for both the Junos device and the console server. You use
the user
and passwd
parameters to specify the
Junos OS login credentials, and you use the cs_user
and
cs_passwd
parameters to specify the console server
credentials. When SSH keys are in use, cs_passwd
is the
passphrase for the private key.
The following playbook prompts for the user’s credentials for the console server and the Junos device. The module authenticates with the console server and then the Junos device. If authentication is successful, the playbook then retrieves the device facts from the managed node and prints the Junos OS version.
--- - name: Get Device Facts hosts: dc1_con connection: local gather_facts: no vars_prompt: - name: "CS_USER" prompt: "Console server username" private: no - name: "CS_PASSWORD" prompt: "Console server password" private: yes - name: "JUNOS_USER" prompt: "Junos OS username" private: no - name: "JUNOS_PASSWORD" prompt: "Junos OS password" private: yes vars: cs_user: "{{ CS_USER }}" cs_passwd: "{{ CS_PASSWORD }}" user: "{{ JUNOS_USER }}" passwd: "{{ JUNOS_PASSWORD }}" tasks: - name: "Retrieve facts from Junos devices" juniper.device.facts: savedir: "{{ playbook_dir }}" - name: Print version ansible.builtin.debug: var: junos.version
The Juniper Networks modules automatically query the default SSH client
configuration file at ~/.ssh/config, if it exists. You can
use a different SSH configuration file by including the
ssh_config
parameter and specifying the location of the
configuration file. For example:
--- - name: Get Device Facts hosts: dc1 connection: local gather_facts: no vars: ssh_config: "/home/admin/.ssh/config_dc" tasks: - name: "Retrieve facts from Junos devices" juniper.device.facts: savedir: "{{ playbook_dir }}" - name: Print version ansible.builtin.debug: var: junos.version
Connect to a Device Using Telnet
The Juniper Networks modules enable you to connect to a Junos device using
telnet, which provides unencrypted access to the network device. You can telnet
to the device’s management interface or to a console server that is directly
connected to the device’s CONSOLE port. Accessing the
device through a console server enables you to initially configure a new or
zeroized device that is not yet configured for remote access. To telnet to the
management interface, you must configure the Telnet service at the [edit
system services]
hierarchy level on all devices that require access
to the interface.
To telnet to the remote device, set the mode
parameter to
"telnet"
and optionally include the port
parameter to specify a port. When you set mode
to
"telnet"
but omit the port
parameter, the
value for port
defaults to 23. For persistent connections,
define mode
and port
under the
vars:
section. For local connections, you can define the
parameters either under the vars:
section or as module
arguments.
The following playbook telnets to a Junos device using port 7016, retrieves the device facts, and saves them to a file. The playbook prompts for the username and password.
--- - name: Get Device Facts hosts: dc1 connection: local gather_facts: no vars_prompt: - name: "DEVICE_USERNAME" prompt: "Device username" private: no - name: "DEVICE_PASSWORD" prompt: "Device password" private: yes vars: user: "{{ DEVICE_USERNAME }}" passwd: "{{ DEVICE_PASSWORD }}" mode: "telnet" port: "7016" tasks: - name: Retrieve facts from Junos devices juniper.device.facts: savedir: "{{ playbook_dir }}" - name: Print version ansible.builtin.debug: var: junos.version
Connect to a Device Using a Serial Console Connection
The Juniper Networks modules enable you to connect to a Junos device using a serial console connection, which is useful when you must initially configure a new or zeroized device that is not yet configured for remote access. To use this connection method, your terminal or laptop must be physically connected to the Junos device through the CONSOLE port. For detailed instructions about connecting to the CONSOLE port on a Junos device, see the hardware documentation for your specific device.
To connect to a Junos device through a serial console connection, set the
module’s mode
parameter to "serial"
, and
optionally include the port
parameter to specify a port. When
you set mode
to "serial"
but omit the
port
parameter, the value for port
defaults to /dev/ttyUSB0
. For persistent connections, define
mode
and port
under the
vars:
section. For local connections, you can define the
parameters either under the vars:
section or as module
arguments.
The following playbook connects to a Junos device through the CONSOLE port and then loads and commits an initial configuration. The playbook prompts for the username and password.
--- - name: Load Initial Configuration hosts: dc1 connection: local gather_facts: no vars_prompt: - name: "DEVICE_USERNAME" prompt: "Device username" private: no - name: "DEVICE_PASSWORD" prompt: "Device password" private: yes tasks: - name: Load initial configuration and commit juniper.device.config: user: "{{ DEVICE_USERNAME }}" passwd: "{{ DEVICE_PASSWORD }}" mode: "serial" load: "merge" src: "configs/junos.conf" register: response - name: Print the response ansible.builtin.debug: var: response