Core Docs Refactor and Redesign (#36067)

* Docs refactor as outlined in https://github.com/ansible/proposals/issues/79. Moves content into 'guides'; refactors TOC; fixes CSS; design tweaks to layout and CSS; fixes generated plugin, CLI and module docs to fix links accodingly; more.

* Adding extra blank line for shippable
This commit is contained in:
scottb 2018-02-13 07:23:55 -08:00 committed by GitHub
commit 373b1dcf59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
157 changed files with 13167 additions and 178 deletions

View file

@ -0,0 +1,21 @@
************************
Ansible Networking Guide
************************
Introduction
============
Ansible Network extends the benefits of simple, powerful, agentless automation to network administrators and teams. Ansible Network modules can configure your network stack, test and validate existing network state, and discover and correct network configuration drift.
If you're new to Ansible, or new to using Ansible for network management, start with the Getting Started Guide (under development).
For documentation on using a particular network module, consult the :doc:`list of all network modules<module_docs/list_of_network_modules>`. Some network modules are maintained by the Ansible community - here's a list of :doc:`network modules maintained by the Ansible Network Team<module_docs/network_maintained>`.
.. toctree::
:maxdepth: 3
network_best_practices_2.5
network_debug_troubleshooting
network_working_with_command_output

View file

@ -0,0 +1,370 @@
.. network-best-practices:
**************************************
Network Best Practices for Ansible 2.5
**************************************
Overview
========
This document explains the best practices for using Ansible 2.5 to manage your network infrastructure.
Audience
--------
* This example is intended for network or system administrators who want to understand how to use Ansible to manage network devices.
Prerequisites
-------------
This example requires the following:
* **Ansible 2.5** (or higher) installed. See :doc:`intro_installation` for more information.
* One or more network devices that are compatible with Ansible.
* Basic understanding of YAML :doc:`YAMLSyntax`.
* Basic understanding of Jinja2 Templates. See :doc:`playbooks_templating` for more information.
* Basic Linux command line use.
* Basic knowledge of network switch & router configurations.
Concepts
========
This section explains some fundamental concepts that you should understand when working with Ansible Networking.
Structure
----------
The examples on this page use the following structure:
.. code-block:: console
.
├── facts-demo.yml
├── group_vars
│   ├── eos.yml
│   └── ios.yml
└── inventory
Inventory
---------
An ``inventory`` file is an INI-like configuration file that defines the mapping of hosts into groups.
In our example, the inventory file defines the groups ``eos``, ``ios``, ``vyos`` and a "group of groups" called ``switches``. Further details about subgroups and inventory files can be found in the :ref:`Ansible inventory Group documentation <subgroups>`.
Connection & Credentials (group_vars)
-------------------------------------
Because Ansible is a flexible tool, there are a number of ways to specify connection information and credentials. We recommend using ``group_vars``.
**group_vars/eos.yml**
.. code-block:: yaml
ansible_connection: network_cli
ansible_network_os: eos
ansible_user: myuser
ansible_ssh_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
37373735393636643261383066383235363664386633386432343236663533343730353361653735
6131363539383931353931653533356337353539373165320a316465383138636532343463633236
37623064393838353962386262643230303438323065356133373930646331623731656163623333
3431353332343530650a373038366364316135383063356531633066343434623631303166626532
9562
ansible_become: yes
ansible_become_method: enable
**group_vars/ios.yml**
.. code-block:: yaml
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: myiosuser
ansible_ssh_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
34623431313336343132373235313066376238386138316466636437653938623965383732373130
3466363834613161386538393463663861636437653866620a373136356366623765373530633735
34323262363835346637346261653137626539343534643962376139366330626135393365353739
3431373064656165320a333834613461613338626161633733343566666630366133623265303563
8472
ansible_become: yes
ansible_become_method: enable
**group_vars/vyos.yml**
.. code-block:: yaml
ansible_connection: network_cli
ansible_network_os: vyos
ansible_user: myvyosuser
ansible_ssh_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
39336231636137663964343966653162353431333566633762393034646462353062633264303765
6331643066663534383564343537343334633031656538370a333737656236393835383863306466
62633364653238323333633337313163616566383836643030336631333431623631396364663533
3665626431626532630a353564323566316162613432373738333064366130303637616239396438
9853
.. FIXME FUTURE Gundalow - Link to network auth & proxy page (to be written)
.. warning:: Never store passwords in plain text.
The "Vault" feature of Ansible allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plain text in your playbooks or roles. These vault files can then be distributed or placed in source control. See :doc:`playbooks_vault` for more information.
:ansible_connection:
Ansible uses the ansible-connection setting to determine how to connect to a remote device. When working with Ansible Networking, set this to ``network_cli`` so Ansible treats the remote node as a network device with a limited execution environment. Without this setting, Ansible would attempt to use ssh to connect to the remote and execute the Python script on the network device, which would fail because Python generally isn't available on network devices.
:ansible_network_os:
Informs Ansible which Network platform this hosts corresponds to. This is required when using ``network_cli`` or ``netconf``.
:ansible_user: The user to connect to the remote device (switch) as. Without this the user that is running ``ansible-playbook`` would be used.
Specifies which user on the network device the connection
:ansible_ssh_pass:
The corresponding password for ``ansible_user`` to log in as. If not specified SSH key will be used.
:ansible_become:
If enable mode (privilege mode) should be used, see the next section.
:ansible_become_method:
Which type of `become` should be used, for ``network_cli`` the only valid choice is ``enable``.
Privilege escalation
^^^^^^^^^^^^^^^^^^^^
Certain network platforms, such as eos and ios, have the concept of different privilege modes. Certain network modules, such as those that modify system state including users, will only work in high privilege states. Ansible version 2.5 added support for ``become`` when using ``connection: network_cli``. This allows privileges to be raised for the specific tasks that need them. Adding ``become: yes`` and ``become_method: enable`` informs Ansible to go into privilege mode before executing the task, as shown here:
**group_vars/eos.yml**
.. code-block:: yaml
ansible_connection: network_cli
ansible_network_os: eos
ansible_become: yes
ansible_become_method: enable
For more information, see the :ref:`using become with network modules<become-and-networks>` guide.
Jump hosts
^^^^^^^^^^
If the Ansible Controller doesn't have a direct route to the remote device and you need to use a Jump Host, please see the :ref:`Ansible Network Proxy Command <network_delegate_to_vs_ProxyCommand>` guide for details on how to achieve this.
Playbook
--------
Collect data
^^^^^^^^^^^^
Ansible facts modules gather system information 'facts' that are available to the rest of your playbook.
Ansible Networking ships with a number of network-specific facts modules. In this example, we use the ``_facts`` modules :ref:`eos_facts <eos_facts>`, :ref:`ios_facts <ios_facts>` and :ref:`vyos_facts <vyos_facts>` to connect to the remote networking device. As the credentials are not explicitly passed via module arguments, Ansible uses the username and password from the inventory file.
Ansible's "Network Fact modules" gather information from the system and store the results in facts prefixed with ``ansible_net_``. The data collected by these modules is documented in the `Return Values` section of the module docs, in this case :ref:`eos_facts <eos_facts>` and :ref:`vyos_facts <vyos_facts>`. We can use the facts, such as ``ansible_net_version`` late on in the "Display some facts" task.
To ensure we call the correct mode (``*_facts``) the task is conditionally run based on the group defined in the inventory file, for more information on the use of conditionals in Ansible Playbooks see :ref:`the_when_statement`.
Example
=======
In this example, we will create an inventory file containing some network switches, then run a playbook to connect to the network devices and return some information about them.
**Create an inventory file**
First, create a file called ``inventory``, containing:
.. code-block:: ini
[switches:children]
eos
ios
vyos
[eos]
eos01.example.net
[ios]
ios01.example.net
[vyos]
vyos01.example.net
**Create a playbook**
Next, create a playbook file called ``facts-demo.yml`` containing the following:
.. code-block:: yaml
- name: "Demonstrate connecting to switches"
hosts: switches
gather_facts: no
tasks:
###
# Collect data
#
- name: Gather facts (eos)
eos_facts:
when: ansible_network_os == 'eos'
- name: Gather facts (ops)
ios_facts:
when: ansible_network_os == 'ios'
- name: Gather facts (vyos)
vyos_facts:
when: ansible_network_os == 'vyos'
###
# Demonstrate variables
#
- name: Display some facts
debug:
msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
- name: Facts from a specific host
debug:
var: hostvars['vyos01.example.net']
- name: Write facts to disk using a template
copy:
content: |
#jinja2: lstrip_blocks: True
EOS device info:
{% for host in groups['eos'] %}
Hostname: {{ hostvars[host].ansible_net_version }}
Version: {{ hostvars[host].ansible_net_version }}
Model: {{ hostvars[host].ansible_net_model }}
Serial: {{ hostvars[host].ansible_net_serialnum }}
{% endfor %}
IOS device info:
{% for host in groups['ios'] %}
Hostname: {{ hostvars[host].ansible_net_version }}
Version: {{ hostvars[host].ansible_net_version }}
Model: {{ hostvars[host].ansible_net_model }}
Serial: {{ hostvars[host].ansible_net_serialnum }}
{% endfor %}
VyOS device info:
{% for host in groups['vyos'] %}
Hostname: {{ hostvars[host].ansible_net_version }}
Version: {{ hostvars[host].ansible_net_version }}
Model: {{ hostvars[host].ansible_net_model }}
Serial: {{ hostvars[host].ansible_net_serialnum }}
{% endfor %}
dest: /tmp/switch-facts
run_once: yes
###
# Get running configuration
#
- name: Backup switch (eos)
eos_config:
backup: yes
register: backup_eos_location
when: ansible_network_os == 'eos'
- name: backup switch (vyos)
vyos_config:
backup: yes
register: backup_vyos_location
when: ansible_network_os == 'vyos'
- name: Create backup dir
file:
path: "/tmp/backups/{{ inventory_hostname }}"
state: directory
recurse: yes
- name: Copy backup files into /tmp/backups/ (eos)
copy:
src: "{{ backup_eos_location.backup_path }}"
dest: "/tmp/backups/{{ inventory_hostname }}/{{ inventory_hostname }}.bck"
when: ansible_network_os == 'eos'
- name: Copy backup files into /tmp/backups/ (vyos)
copy:
src: "{{ backup_vyos_location.backup_path }}"
dest: "/tmp/backups/{{ inventory_hostname }}/{{ inventory_hostname }}.bck"
when: ansible_network_os == 'vyos'
Running the playbook
--------------------
To run the playbook, run the following from a console prompt:
.. code-block:: console
ansible-playbook -i inventory facts-demo.yml
This should return output similar to the following:
.. code-block:: console
PLAY RECAP
eos01.example.net : ok=7 changed=2 unreachable=0 failed=0
ios01.example.net : ok=7 changed=2 unreachable=0 failed=0
vyos01.example.net : ok=6 changed=2 unreachable=0 failed=0
Next, look at the contents of the file we created containing the switch facts:
.. code-block:: console
cat /tmp/switch-facts
You can also look at the backup files:
.. code-block:: console
find /tmp/backups
If `ansible-playbook` fails, please follow the debug steps in :doc:`network_debug_troubleshooting`.
Implementation Notes
====================
Demo variables
--------------
Although these tasks are not needed to write data to disk, they are used in this example to demonstrate some methods of accessing facts about the given devices or a named host.
Ansible ``hostvars`` allows you to access variables from a named host. Without this we would return the details for the current host, rather than the named host.
For more information, see :ref:`magic_variables_and_hostvars`.
Get running configuration
-------------------------
The :ref:`eos_config <eos_config>` and :ref:`vyos_config <vyos_config>` modules have a ``backup:`` option that when set will cause the module to create a full backup of the current ``running-config`` from the remote device before any changes are made. The backup file is written to the ``backup`` folder in the playbook root directory. If the directory does not exist, it is created.
To demonstrate how we can move the backup file to a different location, we register the result and move the file to the path stored in ``backup_path``.
Note that when using variables from tasks in this way we use double quotes (``"``) and double curly-brackets (``{{...}}`` to tell Ansible that this is a variable.
Troubleshooting
===============
If you receive an connection error please double check the inventory and Playbook for typos or missing lines. If the issue still occurs follow the debug steps in :doc:`network_debug_troubleshooting`.
.. seealso::
* :doc:`intro_network`
* :doc:`intro_inventory`
* :ref:`Vault best practices <best-practices-for-variables-and-vaults>`

View file

@ -0,0 +1,549 @@
.. _network_debug_troubleshooting:
***************************************
Network Debug and Troubleshooting Guide
***************************************
Introduction
============
Starting with Ansible version 2.1, you can now use the familiar Ansible models of playbook authoring and module development to manage heterogeneous networking devices. Ansible supports a growing number of network devices using both CLI over SSH and API (when available) transports.
This section discusses how to debug and troubleshoot network modules in Ansible 2.3.
How to troubleshoot
===================
This section covers troubleshooting issues with Network Modules.
Errors generally fall into one of the following categories:
:Authentication issues:
* Not correctly specifying credentials
* Remote device (network switch/router) not falling back to other other authentication methods
* SSH key issues
:Timeout issues:
* Can occur when trying to pull a large amount of data
* May actually be masking a authentication issue
:Playbook issues:
* Use of ``delegate_to``, instead of ``ProxyCommand``. See :ref:`network proxy guide <network_delegate_to_vs_ProxyCommand>` for more information.
* Not using ``connection: local``
.. warning:: ``unable to open shell``
The ``unable to open shell`` message is new in Ansible 2.3, it means that the ``ansible-connection`` daemon has not been able to successfully
talk to the remote network device. This generally means that there is an authentication issue. See the "Authentication and connection issues" section
in this document for more information.
.. _enable_network_logging:
Enabling Networking logging and how to read the logfile
-------------------------------------------------------
**Platforms:** Any
Ansible 2.3 features improved logging to help diagnose and troubleshoot issues regarding Ansible Networking modules.
Because logging is very verbose it is disabled by default. It can be enabled via the :envvar:`ANSIBLE_LOG_PATH` and :envvar:`ANSIBLE_DEBUG` options on the ansible-controller, that is the machine running ansible-playbook.
Before running ``ansible-playbook`` run the following commands to enable logging::
# Specify the location for the log file
export ANSIBLE_LOG_PATH=~/ansible.log
# Enable Debug
export ANSIBLE_DEBUG=True
# Run with 4*v for connection level verbosity
ansible-playbook -vvvv ...
After Ansible has finished running you can inspect the log file which has been created on the ansible-controller:
.. code::
less $ANSIBLE_LOG_PATH
2017-03-30 13:19:52,740 p=28990 u=fred | creating new control socket for host veos01:22 as user admin
2017-03-30 13:19:52,741 p=28990 u=fred | control socket path is /home/fred/.ansible/pc/ca5960d27a
2017-03-30 13:19:52,741 p=28990 u=fred | current working directory is /home/fred/ansible/test/integration
2017-03-30 13:19:52,741 p=28990 u=fred | using connection plugin network_cli
...
2017-03-30 13:20:14,771 paramiko.transport userauth is OK
2017-03-30 13:20:15,283 paramiko.transport Authentication (keyboard-interactive) successful!
2017-03-30 13:20:15,302 p=28990 u=fred | ssh connection done, setting terminal
2017-03-30 13:20:15,321 p=28990 u=fred | ssh connection has completed successfully
2017-03-30 13:20:15,322 p=28990 u=fred | connection established to veos01 in 0:00:22.580626
From the log notice:
* ``p=28990`` Is the PID (Process ID) of the ``ansible-connection`` process
* ``u=fred`` Is the user `running` ansible, not the remote-user you are attempting to connect as
* ``creating new control socket for host veos01:22 as user admin`` host:port as user
* ``control socket path is`` location on disk where the persistent connection socket is created
* ``using connection plugin network_cli`` Informs you that persistent connection is being used
* ``connection established to veos01 in 0:00:22.580626`` Time taken to obtain a shell on the remote device
.. note: Port None ``creating new control socket for host veos01:None``
If the log reports the port as ``None`` this means that the default port is being used.
A future Ansible release will improve this message so that the port is always logged.
Because the log files are verbose, you can use grep to look for specific information. For example, once you have identified the ```pid`` from the ``creating new control socket for host`` line you can search for other connection log entries::
grep "p=28990" $ANSIBLE_LOG_PATH
Isolating an error
------------------
**Platforms:** Any
As with any effort to troubleshoot it's important to simplify the test case as much as possible.
For Ansible this can be done by ensuring you are only running against one remote device:
* Using ``ansible-playbook --limit switch1.example.net...``
* Using an ad-hoc ``ansible`` command
`ad-hoc` refers to running Ansible to perform some quick command using ``/usr/bin/ansible``, rather than the orchestration language, which is ``/usr/bin/ansible-playbook``. In this case we can ensure connectivity by attempting to execute a single command on the remote device::
ansible -m eos_command -a 'commands=?' -i inventory switch1.example.net -e 'ansible_connection=local' -u admin -k
In the above example, we:
* connect to ``switch1.example.net`` specified in the inventory file ``inventory``
* use the module ``eos_command``
* run the command ``?``
* connect using the username ``admin``
* inform ansible to prompt for the ssh password by specifying ``-k``
If you have SSH keys configured correctly, you don't need to specify the ``-k`` parameter
If the connection still fails you can combine it with the enable_network_logging parameter. For example::
# Specify the location for the log file
export ANSIBLE_LOG_PATH=~/ansible.log
# Enable Debug
export ANSIBLE_DEBUG=True
# Run with 4*v for connection level verbosity
ansible -m eos_command -a 'commands=?' -i inventory switch1.example.net -e 'ansible_connection=local' -u admin -k
Then review the log file and find the relevant error message in the rest of this document.
.. For details on other ways to authenticate, see LINKTOAUTHHOWTODOCS.
.. _unable_to_open_shell:
Category "Unable to open shell"
===============================
**Platforms:** Any
The ``unable to open shell`` message is new in Ansible 2.3. This message means that the ``ansible-connection`` daemon has not been able to successfully talk to the remote network device. This generally means that there is an authentication issue. It is a "catch all" message, meaning you need to enable :ref:`log_path` to find the underlying issues.
For example:
.. code-block:: none
TASK [prepare_eos_tests : enable cli on remote device] **************************************************
fatal: [veos01]: FAILED! => {"changed": false, "failed": true, "msg": "unable to open shell"}
or:
.. code-block:: none
TASK [ios_system : configure name_servers] *************************************************************
task path:
fatal: [ios-csr1000v]: FAILED! => {
"changed": false,
"failed": true,
"msg": "unable to open shell",
}
Suggestions to resolve:
Follow the steps detailed in enable_network_logging_.
Once you've identified the error message from the log file, the specific solution can be found in the rest of this document.
Error: "[Errno -2] Name or service not known"
---------------------------------------------
**Platforms:** Any
Indicates that the remote host you are trying to connect to can not be reached
For example:
.. code-block:: yaml
2017-04-04 11:39:48,147 p=15299 u=fred | control socket path is /home/fred/.ansible/pc/ca5960d27a
2017-04-04 11:39:48,147 p=15299 u=fred | current working directory is /home/fred/git/ansible-inc/stable-2.3/test/integration
2017-04-04 11:39:48,147 p=15299 u=fred | using connection plugin network_cli
2017-04-04 11:39:48,340 p=15299 u=fred | connecting to host veos01 returned an error
2017-04-04 11:39:48,340 p=15299 u=fred | [Errno -2] Name or service not known
Suggestions to resolve:
* If you are using the ``provider:`` options ensure that it's suboption ``host:`` is set correctly.
* If you are not using ``provider:`` nor top-level arguments ensure your inventory file is correct.
Error: "Authentication failed"
------------------------------
**Platforms:** Any
Occurs if the credentials (username, passwords, or ssh keys) passed to ``ansible-connection`` (via ``ansible`` or ``ansible-playbook``) can not be used to connect to the remote device.
For example:
.. code-block:: yaml
<ios01> ESTABLISH CONNECTION FOR USER: cisco on PORT 22 TO ios01
<ios01> Authentication failed.
Suggestions to resolve:
If you are specifying credentials via ``password:`` (either directly or via ``provider:``) or the environment variable :envvar:`ANSIBLE_NET_PASSWORD` it is possible that ``paramiko`` (the Python SSH library that Ansible uses) is using ssh keys, and therefore the credentials you are specifying are being ignored. To find out if this is the case, disable "look for keys". This can be done like this:
.. code-block:: yaml
export ANSIBLE_PARAMIKO_LOOK_FOR_KEYS=False
To make this a permanent change, add the following to your ``ansible.cfg`` file:
.. code-block:: ini
[paramiko_connection]
look_for_keys = False
Error: "connecting to host <hostname> returned an error" or "Bad address"
-------------------------------------------------------------------------
This may occur if the SSH fingerprint hasn't been added to Paramiko's (the Python SSH library) know hosts file.
When using persistent connections with Paramiko, the connection runs in a background process. If the host doesn't already have a valid SSH key, by default Ansible will prompt to add the host key. This will cause connections running in background processes to fail.
For example:
.. code-block:: yaml
2017-04-04 12:06:03,486 p=17981 u=fred | using connection plugin network_cli
2017-04-04 12:06:04,680 p=17981 u=fred | connecting to host veos01 returned an error
2017-04-04 12:06:04,682 p=17981 u=fred | (14, 'Bad address')
2017-04-04 12:06:33,519 p=17981 u=fred | number of connection attempts exceeded, unable to connect to control socket
2017-04-04 12:06:33,520 p=17981 u=fred | persistent_connect_interval=1, persistent_connect_retries=30
Suggestions to resolve:
Use ``ssh-keyscan`` to pre-populate the known_hosts. You need to ensure the keys are correct.
.. code-block:: shell
ssh-keyscan veos01
or
You can tell Ansible to automatically accept the keys
Environment variable method::
export ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD=True
ansible-playbook ...
``ansible.cfg`` method:
ansible.cfg
.. code-block:: ini
[paramiko_connection]
host_key_auto_add = True
.. warning: Security warning
Care should be taken before accepting keys.
Error: "No authentication methods available"
--------------------------------------------
For example:
.. code-block:: yaml
2017-04-04 12:19:05,670 p=18591 u=fred | creating new control socket for host veos01:None as user admin
2017-04-04 12:19:05,670 p=18591 u=fred | control socket path is /home/fred/.ansible/pc/ca5960d27a
2017-04-04 12:19:05,670 p=18591 u=fred | current working directory is /home/fred/git/ansible-inc/ansible-workspace-2/test/integration
2017-04-04 12:19:05,670 p=18591 u=fred | using connection plugin network_cli
2017-04-04 12:19:06,606 p=18591 u=fred | connecting to host veos01 returned an error
2017-04-04 12:19:06,606 p=18591 u=fred | No authentication methods available
2017-04-04 12:19:35,708 p=18591 u=fred | connect retry timeout expired, unable to connect to control socket
2017-04-04 12:19:35,709 p=18591 u=fred | persistent_connect_retry_timeout is 15 secs
Suggestions to resolve:
No password or SSH key supplied
Clearing Out Persistent Connections
-----------------------------------
**Platforms:** Any
In Ansible 2.3, persistent connection sockets are stored in ``~/.ansible/pc`` for all network devices. When an Ansible playbook runs, the persistent socket connection is displayed when verbose output is specified.
``<switch> socket_path: /home/fred/.ansible/pc/f64ddfa760``
To clear out a persistent connection before it times out (the default timeout is 30 seconds
of inactivity), simple delete the socket file.
Timeout issues
==============
Timeouts
--------
Persistent connection idle timeout:
For example:
.. code-block:: yaml
2017-04-04 12:19:05,670 p=18591 u=fred | persistent connection idle timeout triggered, timeout value is 30 secs
Suggestions to resolve:
Increase value of presistent connection idle timeout.
.. code-block:: yaml
export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=60
To make this a permanent change, add the following to your ``ansible.cfg`` file:
.. code-block:: ini
[persistent_connection]
connect_timeout = 60
Command timeout:
For example:
.. code-block:: yaml
2017-04-04 12:19:05,670 p=18591 u=fred | command timeout triggered, timeout value is 10 secs
Suggestions to resolve:
Options 1:
Increase value of command timeout in configuration file or by setting environment variable.
Note: This value should be less than persistent connection idle timeout ie. connect_timeout
.. code-block:: yaml
export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=30
To make this a permanent change, add the following to your ``ansible.cfg`` file:
.. code-block:: ini
[persistent_connection]
command_timeout = 30
Option 2:
Increase command timeout per task basis. All network modules support a
timeout value that can be set on a per task basis.
The timeout value controls the amount of time in seconds before the
task will fail if the command has not returned.
For example:
.. FIXME: Detail error here
Suggestions to resolve:
.. code-block:: yaml
- name: save running-config
ios_command:
commands: copy running-config startup-config
provider: "{{ cli }}"
timeout: 30
Some operations take longer than the default 10 seconds to complete. One good
example is saving the current running config on IOS devices to startup config.
In this case, changing the timeout value form the default 10 seconds to 30
seconds will prevent the task from failing before the command completes
successfully.
Note: This value should be less than persistent connection idle timeout ie. connect_timeout
Persistent socket connect timeout:
For example:
.. code-block:: yaml
2017-04-04 12:19:35,708 p=18591 u=fred | connect retry timeout expired, unable to connect to control socket
2017-04-04 12:19:35,709 p=18591 u=fred | persistent_connect_retry_timeout is 15 secs
Suggestions to resolve:
Increase the value of the persistent connection idle timeout.
Note: This value should be greater than the SSH timeout value (the timeout value under the defaults
section in the configuration file) and less than the value of the persistent
connection idle timeout (connect_timeout).
.. code-block:: yaml
export ANSIBLE_PERSISTENT_CONNECT_RETRY_TIMEOUT=30
To make this a permanent change, add the following to your ``ansible.cfg`` file:
.. code-block:: ini
[persistent_connection]
connect_retry_timeout = 30
Playbook issues
===============
This section details issues are caused by issues with the Playbook itself.
Error: "invalid connection specified, expected connection=local, got ssh"
-------------------------------------------------------------------------
**Platforms:** Any
Network modules require that the connection is set to ``local``. Any other
connection setting will cause the playbook to fail. Ansible will now detect
this condition and return an error message:
.. code-block:: yaml
fatal: [nxos01]: FAILED! => {
"changed": false,
"failed": true,
"msg": "invalid connection specified, expected connection=local, got ssh"
}
To fix this issue, set the connection value to ``local`` using one of the
following methods:
* Set the play to use ``connection: local``
* Set the task to use ``connection: local``
* Run ansible-playbook using the ``-c local`` setting
Error: "Unable to enter configuration mode"
-------------------------------------------
**Platforms:** eos and ios
This occurs when you attempt to run a task that requires privileged mode in a user mode shell.
For example:
.. code-block:: yaml
TASK [ios_system : configure name_servers] *****************************************************************************
task path:
fatal: [ios-csr1000v]: FAILED! => {
"changed": false,
"failed": true,
"msg": "unable to enter configuration mode",
}
Suggestions to resolve:
Add ``authorize: yes`` to the task. For example:
.. code-block:: yaml
- name: configure hostname
ios_system:
provider:
hostname: foo
authorize: yes
register: result
If the user requires a password to go into privileged mode, this can be specified with ``auth_pass``; if ``auth_pass`` isn't set, the environment variable :envvar:`ANSIBLE_NET_AUTHORIZE` will be used instead.
Add ``authorize: yes`` to the task. For example:
.. code-block:: yaml
- name: configure hostname
ios_system:
provider:
hostname: foo
authorize: yes
auth_pass: "{{ mypasswordvar }}"
register: result
Proxy Issues
============
.. _network_delegate_to_vs_ProxyCommand:
delegate_to vs ProxyCommand
---------------------------
The new connection framework for Network Modules in Ansible 2.3 that uses ``cli`` transport
no longer supports the use of the ``delegate_to`` directive.
In order to use a bastion or intermediate jump host to connect to network devices over ``cli``
transport, network modules now support the use of ``ProxyCommand``.
To use ``ProxyCommand``, configure the proxy settings in the Ansible inventory
file to specify the proxy host.
.. code-block:: ini
[nxos]
nxos01
nxos02
[nxos:vars]
ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q bastion01"'
With the configuration above, simply build and run the playbook as normal with
no additional changes necessary. The network module will now connect to the
network device by first connecting to the host specified in
``ansible_ssh_common_args``, which is ``bastion01`` in the above example.
.. note:: Using ``ProxyCommand`` with passwords via variables
By design, SSH doesn't support providing passwords via environment variables.
This is done to prevent secrets from leaking out, for example in ``ps`` output.
We recommend using SSH Keys, and if needed an ssh-agent, rather than passwords, where ever possible.

View file

@ -0,0 +1,65 @@
.. _networking_working_with_command_output:
**********************************************
Working with Command Output in Network Modules
**********************************************
Conditionals in Networking Modules
===================================
Ansible allows you to use conditionals to control the flow of your playbooks. Ansible networking command modules use the following unique conditional statements.
* ``eq`` - Equal
* ``neq`` - Not equal
* ``gt`` - Greater than
* ``ge`` - Greater than or equal
* ``lt`` - Less than
* ``le`` - Less than or equal
* ``contains`` - Object contains specified item
Conditional statements evaluate the results from the commands that are
executed remotely on the device. Once the task executes the command
set, the ``wait_for`` argument can be used to evaluate the results before
returning control to the Ansible playbook.
For example::
---
- name: wait for interface to be admin enabled
eos_command:
commands:
- show interface Ethernet4 | json
wait_for:
- "result[0].interfaces.Ethernet4.interfaceStatus eq connected"
In the above example task, the command :code:`show interface Ethernet4 | json`
is executed on the remote device and the results are evaluated. If
the path
:code:`(result[0].interfaces.Ethernet4.interfaceStatus)` is not equal to
"connected", then the command is retried. This process continues
until either the condition is satisfied or the number of retries has
expired (by default, this is 10 retries at 1 second intervals).
The commands module can also evaluate more than one set of command
results in an interface. For instance::
---
- name: wait for interfaces to be admin enabled
eos_command:
commands:
- show interface Ethernet4 | json
- show interface Ethernet5 | json
wait_for:
- "result[0].interfaces.Ethernet4.interfaceStatus eq connected"
- "result[1].interfaces.Ethernet4.interfaceStatus eq connected"
In the above example, two commands are executed on the
remote device, and the results are evaluated. By specifying the result
index value (0 or 1), the correct result output is checked against the
conditional.
The ``wait_for`` argument must always start with result and then the
command index in ``[]``, where ``0`` is the first command in the commands list,
``1`` is the second command, ``2`` is the third and so on.