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
Authenticating Users Executing Ansible Modules on Devices Running Junos OS
Authentication Overview
Juniper Networks provides Ansible modules that you can use to
manage devices running Junos OS. 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 devices running Junos OS 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 devices running Junos OS, 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 devices running Junos OS.
Understanding the Default Values for Juniper Networks Modules
You can explicitly define the connection and authentication
parameters for modules that manage devices running Junos OS. 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 device running Junos OS. 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 optionANSIBLE_REMOTE_USER
environment variableremote_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.
Ansible has deprecated connection: local
. Therefore, when you use the juniper.device
collection modules, we recommend that you use connection: juniper.device.pyez
in your playbook to avoid issues in the event that Ansible removes
support for local connections in a later release.
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 devices running Junos OS 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 devices running Junos OS 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 device running Junos OS 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 device running Junos OS or the console server connected
to the device running Junos OS.
Generating and Configuring the SSH Keys
To generate SSH keys on the Ansible control node and configure the public key on the remote device:
Using 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 device running Junos OS 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 device running Junos OS 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 device running Junos OS 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 devices running Junos OS 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 devices running Junos OS 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 device running Junos OS. You can provide either a device password or a password-protected SSH key file for the console server authentication.
To connect to a device running Junos OS 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 addressuser
andpasswd
—Junos OS login credentialscs_user
—Console server usernamecs_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 devices running Junos OS juniper.device.facts: savedir: "{{ playbook_dir }}"