ON THIS PAGE
Understanding the Default Values for Juniper Networks Modules
How to Define Authentication Parameters in the vars: Section for Local and Persistent Connections
How to Define the provider Parameter in Juniper.junos Modules
How to Authenticate the User Using a Playbook or Command-Line Password Prompt
How to Authenticate the User Using an Ansible Vault-Encrypted File
Authenticate Users Executing Ansible Modules on Junos Devices
Authentication Overview
Juniper Networks provides Ansible modules that you can use to manage Junos devices.
The Juniper Networks modules are distributed through the
juniper.device
collection and the
Juniper.junos
role, which are hosted on Ansible Galaxy.
The Juniper Networks modules enable you to directly connect to and manage Junos
devices using SSH, telnet, or a serial console connection. The modules also support
connecting to the device through an SSH or telnet connection to a console server
that is connected to the device’s CONSOLE
port. The remote device
must be able to authenticate the user using a password or other standard SSH
authentication mechanisms, depending on the connection protocol.
When you use Ansible to manage Junos devices, the most convenient way to access the device is to configure SSH keys. SSH keys enable the remote device to identify trusted users. Alternatively, you can provide a username and password when you execute modules and playbooks.
For SSH connections, the Juniper Networks modules first attempt SSH public key-based authentication and then try password-based authentication. When SSH keys are in use, the supplied password is used as the passphrase for unlocking the private SSH key. When password-based authentication is used, the supplied password is used as the device password. If SSH public key-based authentication is being used and the SSH private key has an empty passphrase, then a password is not required. However, SSH private keys with empty passphrases are not recommended. To retrieve a password for password-based authentication or password-protected SSH keys, you can prompt for the password from the playbook or command-line, or you can create a vault-encrypted data file that securely stores the password.
You can specify connection and authentication parameters for the Juniper Networks modules in the following ways. If you do not explicitly define the values, default values are used in some cases, as described in Understanding the Default Values for Juniper Networks Modules. If you define a parameter’s value in multiple places, Ansible selects the value based on variable precedence, as outlined in Understanding variable precedence in the official Ansible docs.
-
Ansible variables—You can specify the connection and authentication parameter values by using normal Ansible variables, for example, variables defined in inventory or vault files, in host or group variables, or using command-line options.
-
SSH client configuration file—For SSH connections, the Juniper Networks modules automatically query the default SSH configuration file at ~/.ssh/config, if one exists, unless you define the
ssh_config
option to specify a different configuration file. The modules use any relevant settings in the SSH configuration file for the given connection, unless you explicitly define variables that override the setting. -
Module arguments—The
juniper.device
andJuniper.junos
modules support specifying connection and authentication-related options for local connections (connection: local
) as top-level module arguments. Additionally,Juniper.junos
modules support using a provider dictionary in the module arguments as described in How to Define the provider Parameter in Juniper.junos Modules. -
vars:
section—Thejuniper.device
modules support specifying connection and authentication-related options for local and persistent connections in a play’svars:
section, which is described in How to Define Authentication Parameters in the vars: Section for Local and Persistent Connections.
This document discusses the different aspects of authentication when using the Juniper Networks modules to manage Junos devices.
Understanding the Default Values for Juniper Networks Modules
You can explicitly define the connection and authentication parameters for
modules that manage Junos devices. If you do not define a parameter, the module
uses a default value in some cases. Table 1 outlines the default values and variable precedence for common connection
parameters for modules in the juniper.device
collection and
Juniper.junos
role. For information about the arguments
accepted for the individual modules, see the API reference documentation for
that module.
Parameter Name |
Parameter Aliases |
Description |
Default Value and Variable Precedence |
---|---|---|---|
|
|
Hostname or IP address of the remote device with which the connection should be established. |
|
|
|
The user’s password or SSH key passphrase used to authenticate with the managed device. |
|
|
– |
Path to an SSH client configuration file. If you omit this parameter, the modules uses the SSH configuration file in the default location, if one exists. |
~/.ssh/config |
|
|
Path to the SSH private key file used to authenticate with the remote device. If you do not explicitly specify the path and no default value is found, then the module uses the SSH private key file specified in the user’s SSH configuration or the operating-system-specific default. |
|
|
|
Username that is used to authenticate with the managed node. |
|
When executing Juniper Networks modules, the host
argument is
always required for a connection. However, you do not have to explicitly specify
the host, because it defaults to {{ inventory_hostname }}
.
You can execute Juniper Networks modules using any user account that has access
to the managed Junos device. When you execute the modules, Junos OS user account
access privileges are enforced, and the class configured for the Junos OS user
account determines the permissions. If you do not specify a user, the user is
set according to the algorithm described for user
in Table 1. See the Ansible documentation for the precedence used to define
remote_user
, which can be defined in a number of ways,
including:
-
-u
or--user
command line option -
ANSIBLE_REMOTE_USER
environment variable -
remote_user
configuration setting
How to Define Authentication Parameters in the vars: Section for Local and Persistent Connections
You can define connection and authentication parameters for the
juniper.device
modules in the play’s vars:
section, in addition to defining them as you normally would through other
variables, for example, in the SSH configuration file, in the Ansible inventory
file, as command-line arguments, or as module arguments. The
vars:
section enables you to define common connection
parameters in a single location that all modules in the play can use to connect
to a host. Additionally, certain Ansible connections require using the
vars:
section when you define the parameters within the
play, as described here.
The juniper.device
modules support the following Ansible
connections types:
-
local connections, which are defined by using
connection: local
-
persistent connections, which are defined by using
connection: juniper.device.pyez
For both local and persistent connections, Ansible executes modules locally on
the control node. When you use connection: local
, Ansible
establishes a separate connection to the host for each task in the play that
requires a connection. By contrast, when you use
connection: juniper.device.pyez
, Ansible establishes a
single, persistent connection to a host, which persists over the execution of
all tasks in the play.
You use the same connection and authentication parameters for persistent
connections as you do for local connections, and the default parameter values
discussed in Understanding the Default Values for Juniper Networks Modules apply
to both types of connections. However, when you define connection and
authentication parameters within a play for persistent connections, you must
define the parameters in the vars:
section as opposed to
defining the parameters as top-level module arguments in each task because there
is only a single connection, and thus the parameters must apply to all tasks in
that play. For local connections, you can define the parameters either in the
vars:
section or as module arguments. If you define the
parameters in both places, the module arguments take precedence.
The following playbook executes two juniper.device
modules on
each host in the inventory group. The play defines the Ansible connection as
juniper.device.pyez
, which establishes a connection to each
host that persists over the execution of all tasks in the play. The
authentication parameters for the persistent connection are defined within the
play’s vars:
section. The user
and
passwd
values reference variables defined in the
vault-vars.yaml
vault file.
--- - name: Get Device Facts hosts: dc1 connection: juniper.device.pyez gather_facts: no vars: 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 }}"
How to Define the provider Parameter in Juniper.junos Modules
Starting in Juniper.junos
Release 2.0.0, the
Juniper.junos
modules support the provider
parameter in addition to supporting individual top-level module arguments for
each of the connection and authentication-related parameters. The
provider
parameter enables you to define the connection and
authentication parameters for multiple modules in one place and easily pass
those values to the modules that use them. Additionally, if you need to update
the parameters later, you only need to make the update in a single location.
The juniper.device
collection modules do not support using
the provider
parameter.
The provider
argument accepts a dictionary that contains the
connection details required to connect to and authenticate with a device. The
host
argument is always required for a connection, but you
do not have to explicitly specify a value if the module uses the default value
for host
. The dictionary can optionally define additional
parameters required for the connection, including user
,
passwd
, and ssh_private_key_file
, among
others. For information about the arguments accepted for the individual modules,
see the API reference documentation for that module.
In the following example, the credentials
variable is a
dictionary that defines the host
, user
, and
passwd
parameters:
vars: credentials: host: "{{ inventory_hostname }}" user: "{{ ansible_user }}" passwd: "{{ ansible_password }}"
The following sample playbook uses the single provider
argument
to pass the connection details to the juniper_junos_facts
module instead of defining individual module arguments. As you add additional
tasks that use the Juniper.junos
modules, you can then
reference the same dictionary for each module.
--- - name: Get Device Facts hosts: dc1 connection: local gather_facts: no roles: - Juniper.junos vars: credentials: host: "{{ inventory_hostname }}" user: "{{ ansible_user }}" passwd: "{{ ansible_password }}" tasks: - name: Retrieve facts from Junos devices juniper_junos_facts: provider: "{{ credentials }}" savedir: "{{ playbook_dir }}" - name: Print version debug: var: junos.version
How to Authenticate the User Using SSH Keys
The Juniper Networks juniper.device
and
Juniper.junos
modules enable you to use SSH keys to connect to
a Junos device or to a console server that is connected to the device. To
authenticate a user using SSH keys, first generate the keys on the Ansible control
node and then configure the keys on the device to which the module will connect,
either the managed Junos device or the console server connected to the Junos
device.
Generate and Configure the SSH Keys
To generate SSH keys on the Ansible control node and configure the public key on the remote device:
Use SSH Keys in Ansible Playbooks
After generating the SSH key pair and configuring the public key on the
remote device, you can use the key to connect to the device. The Juniper
Networks modules automatically query the default SSH configuration file at
~/.ssh/config, if one exists, unless you define the
ssh_config
option to specify a different configuration
file. The modules use any relevant settings in the SSH configuration file
for the given connection, unless you explicitly define variables that
override the setting. In addition, the modules automatically look for keys
in the default location and keys that are actively loaded in an SSH key
agent.
To define specific settings for SSH keys, you can include the appropriate
arguments in your Ansible playbook. Define the arguments in the location
appropriate for your set of modules and Ansible connection, for example, in
the vars:
section for plays that use the
juniper.device
modules with a persistent connection.
The arguments to include are determined by the location of the key, whether
the key is actively loaded into an SSH key agent, whether the key is
password-protected, and whether the user’s SSH configuration file already
defines settings for that host.
-
To connect to a Junos device using SSH keys that are actively loaded into the native SSH key agent or that are in the default location and do not have password protection, you do not need to define any connection or authentication-related arguments, unless they differ from the default.
juniper.device.facts: savedir: "{{ playbook_dir }}"
-
To connect to a Junos device using SSH keys that are not in the default location and do not have password protection, set the
ssh_private_key_file
argument to the path of the SSH private key file. For example:juniper.device.facts: ssh_private_key_file: "/home/user/.ssh/id_rsa_alternate" savedir: "{{ playbook_dir }}"
Alternatively, you can specify the path of the SSH private key by defining it in the SSH configuration file; by setting the
ANSIBLE_NET_SSH_KEYFILE
environment variable; or by defining the--private-key
or--key-file
command-line option when you execute the playbook. -
To connect to a Junos device using a password-protected SSH key file, which is the recommended method, you can reference the SSH key file passphrase in the
passwd
argument or provide the password by using normal Ansible variables or command-line options.It is the user's responsibility to obtain the SSH key file passphrase in a secure manner appropriate for their environment. It is best practice to either prompt for it during each invocation of the playbook or store the variables using an encrypted vault rather than storing the credentials in an unencrypted format. For example, you can execute the playbook with the
--ask-pass
command-line option and provide the SSH key file passphrase when prompted, as shown here:juniper.device.facts: ssh_private_key_file: "/home/user/.ssh/id_rsa_dc" savedir: "{{ playbook_dir }}"
[user@localhost]$ ansible-playbook playbook.yaml --ask-pass SSH password:
For more information about using a prompt or encrypted vault file for the SSH key passphrase, see How to Authenticate the User Using a Playbook or Command-Line Password Prompt and How to Authenticate the User Using an Ansible Vault-Encrypted File.
For instructions on using SSH keys to connect to a console server, see How to Authenticate Through a Console Server.
How to Authenticate the User Using a Playbook or Command-Line Password Prompt
To authenticate a user executing Ansible modules, you can prompt for the user’s
credentials when you execute the playbook. For example, you can define an
interactive prompt in the playbook, or you can execute the playbook with the
-k
or --ask-pass
command-line option to
prompt for the password. When SSH keys are in use, the supplied password is used
as the passphrase for unlocking the private SSH key. When password-based
authentication is used, the supplied password is used as the device
password.
To define an interactive prompt in the playbook to obtain the user’s password or SSH key passphrase:
Alternatively, you can execute a playbook with the -k
or
--ask-pass
command-line option to prompt for the password
or passphrase. Consider the following playbook, which uses the default
username:
--- - name: Get Device Facts hosts: all connection: local gather_facts: no tasks: - name: Retrieve facts from Junos devices juniper.device.facts: savedir: "{{ playbook_dir }}" - name: Print facts debug: var: junos.version
Execute the playbook, and include the -k
or
--ask-pass
command-line option, which prompts for the
password and does not echo the password on the command line.
[user@localhost]$ ansible-playbook playbook.yaml --ask-pass SSH password: PLAY [Get Device Facts] *********************************************** ...
How to Authenticate the User Using an Ansible Vault-Encrypted File
You can create an Ansible vault that securely stores saved passwords and other
sensitive connection and authentication values in an vault-encrypted data file.
Your playbook can then reference those variables in the location appropriate for
your set of modules and Ansible connection type, for example, in the play’s
vars:
section or as module arguments.
To create and use an Ansible vault file containing required variables, including passwords:
How to Authenticate Through a Console Server
The Juniper Networks Ansible modules can connect to Junos devices through a console server. For SSH connections through a console server, you need to provide the authentication credentials for both the console server and the Junos device. You can provide either a device password or a password-protected SSH key file for the console server authentication.
To connect to a Junos device through a console server, you must provide the following parameters in your playbook, if there is no default value or the default value is not appropriate:
-
host
—Console server hostname or IP address -
user
andpasswd
—Junos OS login credentials -
cs_user
—Console server username -
cs_passwd
—Device password or SSH key file passphrase required to authenticate with the console server
In the following example, the credentials for the Junos OS user and the console
server user are defined in an Ansible vault file. The vault variables are then
referenced in the playbook. In this case, the cs_passwd
argument is the passphrase for the SSH key specified in the
ssh_private_key_file
argument.
--- - name: Get Device Facts hosts: dc1_con connection: local gather_facts: no vars_files: - vault-vars.yaml vars: host: "{{ inventory_hostname }}" user: "{{ junos_username }}" passwd: "{{ junos_password }}" cs_user: "{{ cs_username }}" cs_passwd: "{{ cs_key_password }}" ssh_private_key_file: "/home/user/.ssh/id_rsa_dc" tasks: - name: Retrieve facts from Junos devices juniper.device.facts: savedir: "{{ playbook_dir }}"