Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

 
 

Authenticate Users Executing Ansible Modules on Junos Devices

Understand how to authenticate users 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:

This topic discusses how to authenticate users when you use the juniper.device module set only. For information about using the junipernetworks.junos modules to connect to and authenticate with Junos devices, see Use the juniper.device.junos_* Ansible Modules to Manage Junos Devices.

Authentication Overview

The juniper.device 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.device 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 authentication agent or if the SSH private key has an empty passphrase. However, we do not recommend using SSH private keys with empty passphrases.

Ansible provides many methods to supply a password for password-based authentication or password-protected SSH keys. Some options include using a playbook prompt, providing command-line options, or creating a vault-encrypted data file that securely stores the password. See the official Ansible documentation for more information.

You can specify connection and authentication parameters for the juniper.device modules in the following ways. If you do not explicitly define the values, default values are used in some cases. Default values are 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, host or group variables, or command-line arguments.

  • SSH client configuration file—For SSH connections, the modules automatically query the default SSH configuration file at ~/.ssh/config, if one exists. You can include 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 modules support specifying connection and authentication-related options for local connections (connection: local) as top-level module arguments.

  • Playbook vars: section—The juniper.device modules support specifying connection and authentication-related options for local and persistent connections in a play’s vars: section, which is described in How to Define Authentication Parameters in the vars: Section for Local and Persistent Connections.

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 the juniper.device module set. For information about the arguments accepted for the individual modules, see the API reference documentation for that module.

Table 1: Default Values and Variable Precedence for Connection Parameters

Parameter Name

Parameter Aliases

Description

Default Value and Variable Precedence

host

hostname

ip

Hostname or IP address of the remote device with which the connection should be established.

{{ inventory_hostname }}

passwd

password

The user’s password or SSH key passphrase required to authenticate with the managed device.

  1. ANSIBLE_NET_PASSWORD environment variable

  2. Value specified for -k or --ask-pass command-line option

ssh_config

Path to an SSH client configuration file.

If you omit this parameter, the modules use the SSH configuration file in the default location, if one exists.

~/.ssh/config

ssh_private_key_file

ssh_keyfile

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.

  1. ANSIBLE_NET_SSH_KEYFILE environment variable

  2. Value specified for --private-key or --key-file command-line option

  3. none

user

username

Username that is used to authenticate with the managed node.

  1. ANSIBLE_NET_USERNAME environment variable

  2. remote_user as defined by Ansible

  3. USER environment variable

When executing the 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 the modules using any user account that has access to the managed Junos device. Junos OS user account access privileges are enforced, and the class configured for the Junos OS user 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 set 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. This option is in addition to defining the parameters through other means, 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 apply to both types of connections. For local connections, you can define the connection and authentication parameters either in the vars: section or as module arguments. If you define the parameters in both places, the module arguments take precedence. However, when you define parameters within a play for persistent connections, you must define the parameters in the vars: section. With persistent connections there is only a single connection for all tasks, and thus you must define the parameters globally so they apply to all tasks in that play.

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 play’s vars: section defines the authentication parameters for the persistent connection. The user and passwd values reference variables defined in the vault-vars.yaml vault file.

How to Authenticate the User Using SSH Keys

The juniper.device 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:

  1. On the Ansible control node, generate the user's public and private SSH keypair, and provide any required options, for example:
  2. (Optional) Load the key into the native SSH key agent. For example:
  3. Configure the public key on each device to which the modules will connect, which could include Junos devices or a console server connected to a Junos device.

    The easiest method to configure the public key on a Junos device is to load a file that contains the public key under the appropriate user account.

  4. Verify that the key works by logging in to the device using the key.

Use SSH Keys in Ansible Playbooks

After generating the SSH keypair 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. You can also 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, for plays that use the juniper.device modules with a persistent connection, you would define the settings in the vars: section. The following factors determine which arguments to include in the playbook:

  • The location of the key

  • Whether the key is actively loaded into an SSH key agent

  • Whether the key is password-protected

  • Whether the user’s SSH configuration file already defines settings for that host

The following examples outline how to address the different scenarios:

  • 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.

  • 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:

    Alternatively, you can specify the path of the SSH private key by: defining it in the SSH configuration file; 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 a number of ways. For example, you can use the passwd argument, define Ansible variables, or supply command-line options.

    The following example executes the playbook with the --ask-pass command-line option to prompt the user for the passphrase:

    Note: 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 the passphrase when you execute the playbook or store the variable using an encrypted vault rather than storing the credentials in an unencrypted format.

    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 private SSH key passphrase. 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:

  1. Include code under vars_prompt: that prompts for the user’s password or SSH key passphrase (and optionally the username) and stores the value in a variable.
  2. Set the user and passwd parameters so each references its respective variable.
  3. Include the tasks to execute.
  4. Execute the playbook, which prompts for the username and password. The terminal does not echo the password as you enter it because the variable is set to private: yes.

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:

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.

How to Authenticate the User Using an Ansible Vault-Encrypted File

You can use Ansible vault to securely store passwords and other sensitive connection and authentication values in a 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.

This example uses Ansible vault to create and encrypt a new vault file. You can also encrypt individual variables or use multiple encrypted files with different passwords. See the official Ansible documentation for detailed information about using Ansible vault for encrypting content and files.

To create and use an Ansible vault file containing required variables, including passwords:

  1. Create a vault-encrypted data file, and specify the password required to encrypt, decrypt, edit, and use the data file.
  2. Define the required variables in the file and save it.
  3. Verify that the file is encrypted.
  4. In the playbook, include the vault-encrypted variable file, and reference the required variables in the location appropriate for your modules and Ansible connection type.
    Note:

    If you instead define the actual user and passwd variables in the vault, the modules pick them up automatically, and you do not need to explicitly define them in the playbook.

  5. Execute the playbook with the --ask-vault-pass option, which prompts for the vault password.

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 use 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 and passwd—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

  • port—Port, if different from the default

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.