Network Device Authentication with Ansible 2.3

March 30, 2017 by Peter Sprygada

Ansible 2.3 Networking Update

In a recent post, Coming Soon: Networking Features in Ansible 2.3, one of the key features to be introduced is a new connection framework. This new connection framework supports persistent SSH connections for modules that communicate with network devices via two methods:

1) the tried and true CLI method
2) the newly included NETCONF method

With the new connection framework, the network modules are currently undergoing a transformation with regards to how credentials are supplied. In Ansible versions 2.0 to 2.2, network modules support providing connection credentials as top-level arguments in the module.

If you want to build a task using the ios_command Ansible module the credentials used to authenticate to the device could be provided as top level arguments. The following example demonstrates the simplest form of passing credentials to modules in order to authenticate to the remote device:


ios_command:
  commands: show version
  host: “{{ inventory_hostname }}”
  username: cisco
  password: cisco
  

In some cases, such as with configuration modules, additional authentication details are required. In order to enter configuration mode, the Playbook tasks must first enter “enable” mode and, in some cases, supply an enable-mode password. Notice the additional two arguments (authorize and auth_pass) added to the task below. In the following example, these arguments instruct the module to first enter enable mode and supply the enable mode password before attempting to configure the device:


ios_config: lines: hostname foo 
  host: “{{ inventory_hostname }}”
  username: cisco 
  password: cisco 
  authorize: yes 
  auth_pass: cisco 
  

As an aside, some vendor network modules support more than one type of transport for sending CLI commands to the remote device. Specifically, the Arista EOS and Cisco NX-OS platforms provide an alternative method which involves sending CLI commands over HTTP(S). To add support for using the updated transport layer, additional top level arguments were introduced that allows for specifying the transport for use with any configuration parameters.

The following example demonstrates the use of changing the underlying transport from the default transport (CLI) to eapi in order to send CLI commands over HTTP(S):


eos_command:
  commands: show version
  host: “{{ inventory_hostname }}”
  username: admin
  password: admin
  transport: eapi
  use_ssl: no

Each of the examples thus far demonstrates how to use top level arguments to pass credential information for network modules. The implementation provides a straightforward and simple to read approach. However, when writing a Playbook that can consist of many network modules, repeating these parameters can be cumbersome, redundant, and error prone. In an effort to help streamline the passing of credentials, network modules support an additional top level argument called “provider.”

The provider argument allows Playbook designers to apply the necessary credentials as a single entry. Take the simple example above using the ios_command module. To implement the same module using the provider argument, one might put the top level credential arguments into a single argument called provider in the following example:


vars:
  cli:
    host: “{{ inventory_hostname }}”
    username: cisco
    password: cisco

tasks:
  - name: run show version
    ios_command: 
      commands: show version
      provider: “{{ cli }}”

This can also be used when changing the transport and supplying additional parameters and therefore reused throughout the Playbook.

As seen in the following example, using the provider argument simplifies the passing of credentials into network modules and promotes the reuse to help avoid miskeying argument values on a per task basis:


vars:
  nxapi:
    host: “{{ inventory_hostname }}”
    username: admin
    password: admin
    transport: nxapi
    use_ssl: no

tasks:
  - name: run show version
    nxos_command: 
      commands: show version
      provider: “{{ nxapi }}”

  - name: run show ip route
    nxos_command: 
      commands: show ip route
      provider: “{{ nxapi }}”

So what does this have to do with Ansible 2.3?

As mentioned, the forthcoming release of Ansible 2.3 introduces a new connection framework. This new connection framework is integrated into Ansible and makes use of many of the available plugins available.

With this new connection framework, we have decided to deprecate the use of top level arguments for passing credentials into network modules. This applies to all top level credentials arguments except provider.

When executing a Playbook with the following task:


ios_command:
  commands: show version
  host: “{{ inventory_hostname }}”
  username: cisco
  password: cisco

Ansible will now run the Playbook as it has but will return a deprecation warning for each of the top level arguments as such:


[WARNING]: argument username has been deprecated and will be removed in a future version
[WARNING]: argument host has been deprecated and will be removed in a future version
[WARNING]: argument password has been deprecated and will be removed in a future version

As the warning messages indicate, the top level arguments are now considered deprecated and will be removed in the future. Instead of using legacy top level arguments, Playbooks should be updated to use the provider argument for all network module credentials.

Why was this change introduced to Ansible 2.3?

The new connection framework is designed for future features and benefits moving forward. A notable benefit is that the new connection framework is integrated as an Ansible plugin. Because of this, there is now the ability to pass credential information from the command line in Ansible just as is done for non-network modules.

The original Ansible 2.2 example Playbook can be re-written the following way for Ansible 2.3:


---
- hosts: ios_routers
  connection: local
  
  tasks:
    - name: run show version
      ios_command:
        commands: show version

Notice, the new task entry does not include any credential information anywhere. In order to execute the new Playbook, the credentials are now taken from the Ansible command line as shown here:


$ ansible-playbook demo.yaml -u cisco -k
SSH password:

PLAY [ios01] ***************************************************************

TASK [ios_command] *********************************************************
ok: [ios01]

PLAY RECAP *****************************************************************
ios01                      : ok=1    changed=0    unreachable=0    failed=0

The Playbook above uses the user credentials supplied from the Ansible command line to authenticate to the remote device. This removes the requirement to encode any credentials into the Playbook, helping to further simplify the Playbook.

Final Thoughts

Ansible 2.3 will introduce a new connection framework for networking modules, bringing enhancements to how modules are authenticated to the network device.

In order to help streamline and enhance Playbooks, Ansible 2.3 deprecates the use of top level arguments in favor of use of the provider argument. Current Playbooks that implement top level arguments will still function in Ansible 2.3 but are expected to be removed in a future release per the standard Ansible project deprecation schedule. Playbooks should be updated sooner rather than later to help avoid future problems.

Finally, network modules in Ansible will be able to consume credentials provided via the Ansible command line. This can provide a more consistent and more secure environment that can simplify Playbook development.

 

Share:

Topics:
Network Automation


 

Peter Sprygada

Peter is a Senior Principal Engineer for Ansible at Red Hat, where he brings over 20 years experience building and operating global network infrastructures. He holds two patents in network configuration automation and currently leads the Ansible network engineering team that focuses on building solutions and integrating network automation use cases into Ansible. You can follow him on twitter at @privateip.


rss-icon  RSS Feed