Connect to Junos Devices Using Ansible
Understand how to connect to Junos devices when using the
juniper.device module set in the juniper.device
Ansible collection.
Juniper Networks provides Ansible modules that you can use to manage devices running
Junos OS and devices running Junos OS Evolved. The Juniper Networks modules are
distributed through the juniper.device collection. The
juniper.device collection includes two sets of modules:
-
juniper.devicemodules (command,config,facts,file_copy,jsnapy,ping,pmtud,rpc,software,srx_cluster,system,table) -
junipernetworks.junosmodules (juniper.device.junos_*)
This document discusses how to use the juniper.device module set only to
connect to Junos devices using different protocols and Ansible connections. For
information about using the junipernetworks.junos modules to connect to
Junos devices, see Use the juniper.device.junos_* Ansible Modules to Manage Junos Devices.
Connection Methods Overview
The juniper.device 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. You can use either a serial console connection when you are directly connected to the device or you can use 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 to telnet. To use a serial
console connection, set the mode argument 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.
|
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 cleartext passwords
(thereby creating a potential security vulnerability), we recommend that you use
SSH.
When you use 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.device modules do not require Python on
Junos devices because the modules 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 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. However, the persistent
connection establishes and maintains a single connection to each host, which
persists over the execution of all tasks in the play. A persistent connection
can be more efficient for executing multiple tasks than using a separate
connection to the host for each task in the play.
Table 2 summarizes the Ansible connections for the modules in the
juniper.device module set.
|
Ansible connection |
Description |
|---|---|
|
|
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. |
You can define connection and authentication parameters for local and persistent
connections in the playbook. Local connections establish a separate connection
to a host for each task. Thus, you can define the connection and authentication
parameters for local connections in the play's vars: section
and in a module's argument list. The module arguments take precedence. By
contrast, persistent connections have a single connection for all tasks in the
play. Thus, you must define the connection and authentication parameters for
persistent connections globally in the play's vars:
section.
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 globally in the play’s vars:
section.
---
- name: Get Device Information
hosts: dc1
connection: juniper.device.pyez
gather_facts: no
vars:
host: "{{ inventory_hostname }}"
user: "{{ vault_admin_username }}"
passwd: "{{ vault_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.device modules support using SSH to
connect to a Junos device. You can establish a NETCONF session over SSH on the
device’s management interface. You can also 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 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.
For SSH connections 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 the passphrase for unlocking the private key. You do not need to supply a password if you load the key into an SSH key agent or if the SSH private key has an empty passphrase. 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 that are loaded in an SSH key agent.
---
- 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 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. Use the
user and passwd parameters to specify the
Junos OS login credentials. 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. Additionally, set the port
argument to the TCP port that maps to the TTY device, if applicable.
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 }}"
port: 3007
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.device 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
default value for port is 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.versionConnect to a Device Using a Serial Console Connection
The juniper.device modules enable you to connect to
a Junos device using a serial console connection, which is useful when you must
initially configure a new 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 default value for port
is /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