mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-08 22:33:25 +00:00
Network Getting started docs (#36337)
* first draft of getting started guide
This commit is contained in:
committed by
John R Barker
parent
b96ab46566
commit
51a010a696
37
docs/docsite/rst/network/getting_started/basic_concepts.rst
Normal file
37
docs/docsite/rst/network/getting_started/basic_concepts.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
***************************************
|
||||
Basic Concepts
|
||||
***************************************
|
||||
|
||||
These concepts are common to all uses of Ansible, including network automation. You need to understand them to use Ansible for network automation. This basic introduction provides the background you need to follow the examples in this guide.
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
Control Node
|
||||
================================================================================
|
||||
|
||||
Any machine with Ansible installed. You can run commands and playbooks, invoking ``/usr/bin/ansible`` or ``/usr/bin/ansible-playbook``, from any control node. You can use any computer that has Python installed on it as a control node - laptops, shared desktops, and servers can all run Ansible. However, you cannot use a Windows machine as a control node. You can have multiple control nodes.
|
||||
|
||||
Managed Nodes
|
||||
================================================================================
|
||||
|
||||
The network devices (and/or servers) you manage with Ansible. Managed nodes are also sometimes called "hosts". Ansible is not installed on managed nodes.
|
||||
|
||||
Inventory
|
||||
================================================================================
|
||||
|
||||
A list of managed nodes. An inventory file is also sometimes called a "hostfile". Your inventory can specify information like IP address for each managed node. An inventory can also organize managed nodes, creating and nesting groups for easier scaling. To learn more about inventory, see :doc:`the Working with Inventory<../../user_guide/intro_inventory>` pages.
|
||||
|
||||
Modules
|
||||
================================================================================
|
||||
|
||||
The units of code Ansible executes. Each module has a particular use, from administering users on a specific type of database to managing VLAN interfaces on a specific type of network device. You can invoke a single module with a task, or invoke several different modules in a playbook. For an idea of how many modules Ansible includes, take a look at the :doc:`list of all modules<../../modules/modules_by_category>` or the :doc:`list of network modules<../../modules/list_of_network_modules>`.
|
||||
|
||||
Tasks
|
||||
================================================================================
|
||||
|
||||
The units of action in Ansible. You can execute a single task once with an ad-hoc command.
|
||||
|
||||
Playbooks
|
||||
================================================================================
|
||||
|
||||
Ordered lists of tasks, saved so you can run those tasks in that order repeatedly. Playbooks can include variables as well as tasks. Playbooks are written in YAML and are easy to read, write, share and understand. To learn more about playbooks, see :doc:`../../user_guide/playbooks_intro`.
|
||||
253
docs/docsite/rst/network/getting_started/first_inventory.rst
Normal file
253
docs/docsite/rst/network/getting_started/first_inventory.rst
Normal file
@@ -0,0 +1,253 @@
|
||||
***********************************************
|
||||
Build Your Inventory
|
||||
***********************************************
|
||||
|
||||
A fully-featured inventory file can serve as the source of truth for your network. Using an inventory file, a single playbook can maintain hundreds of network devices with a single command. This page shows you how to build an inventory file, step by step.
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
Basic Inventory
|
||||
==================================================
|
||||
|
||||
First, group your inventory logically. Best practice is to group servers and network devices by their What (application, stack or microservice), Where (datacenter or region), and When (development stage):
|
||||
|
||||
- **What**: db, web, leaf, spine
|
||||
- **Where**: east, west, floor_19, building_A
|
||||
- **When**: dev, test, staging, prod
|
||||
|
||||
Avoid spaces, hyphens, and preceding numbers (use ``floor_19``, not ``19th_floor``) in your group names. Group names are case sensitive.
|
||||
|
||||
This tiny example data center illustrates a basic group structure. You can group groups using the syntax ``metagroupname:children`` and listing groups as members of the metagroup. Here, the group ``network`` includes all leafs and all spines; the group ``datacenter`` includes all network devices plus all webservers.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
[leafs]
|
||||
leaf01
|
||||
leaf02
|
||||
|
||||
[spines]
|
||||
spine01
|
||||
spine02
|
||||
|
||||
[network:children]
|
||||
leafs
|
||||
spines
|
||||
|
||||
[webservers]
|
||||
webserver01
|
||||
webserver02
|
||||
|
||||
[datacenter:children]
|
||||
network
|
||||
webservers
|
||||
|
||||
|
||||
Add Variables to Inventory
|
||||
================================================================================
|
||||
|
||||
Next, you can set values for many of the variables you needed in your first Ansible command in the inventory, so you can skip them in the ansible-playbook command. In this example, the inventory includes each network device's IP, OS, and SSH user. If your network devices are only accessible by IP, you must add the IP to the inventory file. If you access your network devices using hostnames, the IP is not necessary.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
[leafs]
|
||||
leaf01 ansible_host=10.16.10.11 ansible_network_os=vyos ansible_user=my_vyos_user
|
||||
leaf02 ansible_host=10.16.10.12 ansible_network_os=vyos ansible_user=my_vyos_user
|
||||
|
||||
[spines]
|
||||
spine01 ansible_host=10.16.10.13 ansible_network_os=vyos ansible_user=my_vyos_user
|
||||
spine02 ansible_host=10.16.10.14 ansible_network_os=vyos ansible_user=my_vyos_user
|
||||
|
||||
[network:children]
|
||||
leafs
|
||||
spines
|
||||
|
||||
[servers]
|
||||
server01 ansible_host=10.16.10.15 ansible_user=my_server_user
|
||||
server02 ansible_host=10.16.10.16 ansible_user=my_server_user
|
||||
|
||||
[datacenter:children]
|
||||
leafs
|
||||
spines
|
||||
servers
|
||||
|
||||
Group Variables within Inventory
|
||||
================================================================================
|
||||
|
||||
When devices in a group share the same variable values, such as OS or SSH user, you can reduce duplication and simplify maintenance by consolidating these into group variables:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
[leafs]
|
||||
leaf01 ansible_host=10.16.10.11
|
||||
leaf02 ansible_host=10.16.10.12
|
||||
|
||||
[leafs:vars]
|
||||
ansible_network_os=vyos
|
||||
ansible_user=my_vyos_user
|
||||
|
||||
[spines]
|
||||
spine01 ansible_host=10.16.10.13
|
||||
spine02 ansible_host=10.16.10.14
|
||||
|
||||
[spines:vars]
|
||||
ansible_network_os=vyos
|
||||
ansible_user=my_vyos_user
|
||||
|
||||
[network:children]
|
||||
leafs
|
||||
spines
|
||||
|
||||
[servers]
|
||||
server01 ansible_host=10.16.10.15
|
||||
server02 ansible_host=10.16.10.16
|
||||
|
||||
[datacenter:children]
|
||||
leafs
|
||||
spines
|
||||
servers
|
||||
|
||||
Variable Syntax
|
||||
================================================================================
|
||||
|
||||
The syntax for variable values is different in inventory, in playbooks and in ``group_vars`` files, which are covered below. Even though playbook and ``group_vars`` files are both written in YAML, you use variables differently in each.
|
||||
|
||||
- In an inventory file you **must** use the syntax ``key=value`` for variable values: ``ansible_network_os=vyos``.
|
||||
- In any file with the ``.yml`` or ``.yaml`` extension, including playbooks and ``group_vars`` files, you **must** use YAML syntax: ``key: value``
|
||||
|
||||
- In ``group_vars`` files, use the full ``key`` name: ``ansible_network_os: vyos``.
|
||||
- In playbooks, use the short-form ``key`` name, which drops the ``ansible`` prefix: ``network_os: vyos``
|
||||
|
||||
|
||||
Move Group Variables to ``group_vars`` Files
|
||||
================================================================================
|
||||
|
||||
As your inventory grows, you may want to group devices by platform and move shared variables out of the main inventory file into a set of group variable files. This reduces duplication further and sets the stage for managing devices on multiple platforms in a single inventory file. The directory tree for this setup looks like this:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
.
|
||||
├── first_playbook.yml
|
||||
├── inventory
|
||||
├── group_vars
|
||||
└── vyos.yml
|
||||
|
||||
The group name must match the file name in your ``group_vars`` directory. In this example, Ansible will load the file ``group_vars/vyos.yml`` when it finds the group ``[vyos]`` in the inventory. So this inventory:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
[vyos_leafs]
|
||||
leaf01 ansible_host=10.16.10.11
|
||||
leaf02 ansible_host=10.16.10.12
|
||||
|
||||
[vyos_spines]
|
||||
spine01 ansible_host=10.16.10.13
|
||||
spine02 ansible_host=10.16.10.14
|
||||
|
||||
[vyos:children]
|
||||
vyos_leafs
|
||||
vyos_spines
|
||||
|
||||
[network:children]
|
||||
vyos
|
||||
|
||||
[servers]
|
||||
server01 ansible_host=10.16.10.15
|
||||
server02 ansible_host=10.16.10.16
|
||||
|
||||
[datacenter:children]
|
||||
vyos
|
||||
servers
|
||||
|
||||
works with this ``group_vars/vyos.yml`` content:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ansible_connection: network_cli
|
||||
ansible_network_os: vyos
|
||||
ansible_user: my_vyos_user
|
||||
|
||||
|
||||
With this setup, you can run first_playbook.yml with only two flags:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-playbook -i inventory -k first_playbook.yml
|
||||
|
||||
With the ``-k`` flag, you provide the SSH password(s) at the prompt. Alternatively, you can store SSH and other secrets and passwords securely in your group_vars files with ``ansible-vault``.
|
||||
|
||||
|
||||
Protecting Sensitive Variables with ``ansible-vault``
|
||||
================================================================================
|
||||
|
||||
The ``ansible-vault`` command provides encryption for files and/or individual variables like passwords. This tutorial uses SSH passwords for an example. You can use the commands below to encrypt other sensitive information, such as database passwords, privilege-escalation passwords and more.
|
||||
|
||||
First you must create a password for ansible-vault itself. Then you can encrypt dozens of different passwords across your Ansible project. You can access all those secrets with a single password (the ansible-vault password) when you run your playbooks. Here's a simple example.
|
||||
|
||||
Create a file and write your password for ansible-vault to it:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
echo "my-ansible-vault-pw" > ~/my-ansible-vault-pw-file
|
||||
|
||||
Encrypt the ssh password for your VyOS network devices, pulling your ansible-vault password from the file you just created:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-vault encrypt_string --vault-id my_user@~/my-ansible-vault-pw-file 'VyOS_SSH_password' --name 'ansible_ssh_pass'
|
||||
|
||||
If you prefer to type your vault password rather than store it in a file, you can request a prompt:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-vault encrypt_string --vault-id my_user@prompt 'VyOS_SSH_password' --name 'ansible_ssh_pass'
|
||||
|
||||
and type in the vault password for ``my_user``.
|
||||
|
||||
The :option:`--vault-id <ansible-playbook --vault-id>` flag allows different vault passwords for different users or different levels of access. The output includes the user name ``my_user`` from your ``ansible-vault`` command and uses the YAML syntax ``key: value``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible_ssh_pass: !vault |
|
||||
$ANSIBLE_VAULT;1.2;AES256;my_user
|
||||
66386134653765386232383236303063623663343437643766386435663632343266393064373933
|
||||
3661666132363339303639353538316662616638356631650a316338316663666439383138353032
|
||||
63393934343937373637306162366265383461316334383132626462656463363630613832313562
|
||||
3837646266663835640a313164343535316666653031353763613037656362613535633538386539
|
||||
65656439626166666363323435613131643066353762333232326232323565376635
|
||||
Encryption successful
|
||||
|
||||
Copy this output into your ``group_vars/vyos.yml`` file, which now looks like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ansible_connection: network_cli
|
||||
ansible_network_os: vyos
|
||||
ansible_user: my_vyos_user
|
||||
ansible_ssh_pass: !vault |
|
||||
$ANSIBLE_VAULT;1.2;AES256;my_user
|
||||
66386134653765386232383236303063623663343437643766386435663632343266393064373933
|
||||
3661666132363339303639353538316662616638356631650a316338316663666439383138353032
|
||||
63393934343937373637306162366265383461316334383132626462656463363630613832313562
|
||||
3837646266663835640a313164343535316666653031353763613037656362613535633538386539
|
||||
65656439626166666363323435613131643066353762333232326232323565376635
|
||||
|
||||
To run a playbook with this setup, drop the ``-k`` flag and add a flag for your ``vault-id``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-playbook -i inventory --vault-id my_user@~/my-ansible-vault-pw-file first_playbook.yml
|
||||
|
||||
Or with a prompt instead of the vault password file:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-playbook -i inventory --vault-id my_user@prompt first_playbook.yml
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
Vault content can only be decrypted with the password that was used to encrypt it. If you want to stop using one password and move to a new one, you can update and re-encrypt existing vault content with ``ansible-vault rekey myfile``, then provide the old password and the new password. Copies of vault content still encrypted with the old password can still be decrypted with old password.
|
||||
|
||||
For more details on building inventory files, see :doc:`the introduction to inventory<../../user_guide/intro_inventory>`; for more details on ansible-vault, see :doc:`the full Ansible Vault documentation<../../user_guide/vault>`.
|
||||
|
||||
Now that you understand the basics of commands, playbooks, and inventory, it's time to explore some more complex Ansible Network examples.
|
||||
157
docs/docsite/rst/network/getting_started/first_playbook.rst
Normal file
157
docs/docsite/rst/network/getting_started/first_playbook.rst
Normal file
@@ -0,0 +1,157 @@
|
||||
***************************************************
|
||||
Run Your First Command and Playbook
|
||||
***************************************************
|
||||
|
||||
Put the concepts you learned to work with this quick tutorial. Install Ansible, execute a network configuration command manually, execute the same command with Ansible, then create a playbook so you can execute the command any time on multiple network devices.
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
Prerequisites
|
||||
==================================================
|
||||
|
||||
Before you work through this tutorial you need:
|
||||
|
||||
- Ansible 2.5 (or higher) installed
|
||||
- One or more network devices that are compatible with Ansible
|
||||
- Basic Linux command line knowledge
|
||||
- Basic knowledge of network switch & router configuration
|
||||
|
||||
Install Ansible
|
||||
==================================================
|
||||
|
||||
Install Ansible using your preferred method. See :doc:`../../installation_guide/intro_installation`. Then return to this tutorial.
|
||||
|
||||
Confirm the version of Ansible (must be >= 2.5):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible --version
|
||||
|
||||
|
||||
Establish a Manual Connection to a Managed Node
|
||||
==================================================
|
||||
|
||||
To confirm your credentials, connect to a network device manually and retrieve its configuration. Replace the sample user and device name with your real credentials. For example, for a VyOS router:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ssh my_vyos_user@vyos.example.net
|
||||
show config
|
||||
exit
|
||||
|
||||
This manual connection also establishes the authenticity of the network device, adding its RSA key fingerprint to your list of known hosts. (If you have connected to the device before, you have already established its authenticity.)
|
||||
|
||||
|
||||
Run Your First Network Ansible Command
|
||||
==================================================
|
||||
|
||||
Instead of manually connecting and running a command on the network device, you can retrieve its configuration with a single, stripped-down Ansible command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible all -i vyos.example.net, -c network_cli -u my_vyos_user -k -m vyos_facts -e ansible_network_os=vyos
|
||||
|
||||
The flags in this command set seven values:
|
||||
- the host group(s) to which the command should apply (in this case, all)
|
||||
- the inventory (-i, the device or devices to target - without the trailing comma -i points to an inventory file)
|
||||
- the connection method (-c, the method for connecting and executing ansible)
|
||||
- the user (-u, the username for the SSH connection)
|
||||
- the SSH connection method (-k, please prompt for the password)
|
||||
- the module (-m, the ansible module to run)
|
||||
- an extra variable ( -e, in this case, setting the network OS value)
|
||||
|
||||
NOTE: If you use ``ssh-agent`` with ssh keys, Ansible loads them automatically. You can omit ``-k`` flag.
|
||||
|
||||
|
||||
Create and Run Your First Network Ansible Playbook
|
||||
==================================================
|
||||
|
||||
If you want to run this command every day, you can save it in a playbook and run it with ansible-playbook instead of ansible. The playbook can store a lot of the parameters you provided with flags at the command line, leaving less to type at the command line. You need two files for this - a playbook and an inventory file.
|
||||
|
||||
1. Download :download:`first_playbook.yml <sample_files/first_playbook.yml>`, which looks like this:
|
||||
|
||||
.. literalinclude:: sample_files/first_playbook.yml
|
||||
:language: YAML
|
||||
|
||||
The playbook sets three of the seven values from the command line above: the group (``hosts: all``), the connection method (``connection: network_cli``) and the module (in each task). With those values set in the playbook, you can omit them on the command line. The playbook also adds a second task to show the config output. When a module runs in a playbook, the output is held in memory for use by future tasks instead of written to the console. The debug task here lets you see the results in your shell.
|
||||
|
||||
2. Run the playbook with the command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos first_playbook.yml
|
||||
|
||||
The playbook contains one play with two tasks, and should generate output like this:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos first_playbook.yml
|
||||
|
||||
PLAY [First Playbook]
|
||||
***************************************************************************************************************************
|
||||
|
||||
TASK [Gathering Facts]
|
||||
***************************************************************************************************************************
|
||||
ok: [vyos.example.net]
|
||||
|
||||
TASK [Get config for VyOS devices]
|
||||
***************************************************************************************************************************
|
||||
ok: [vyos.example.net]
|
||||
|
||||
TASK [Display the config]
|
||||
***************************************************************************************************************************
|
||||
ok: [vyos.example.net] => {
|
||||
"failed": false,
|
||||
"msg": "The hostname is vyos and the OS is VyOS"
|
||||
}
|
||||
|
||||
3. Now that you can retrieve the device config, try updating it with Ansible. Download :download:`first_playbook_ext.yml <sample_files/first_playbook_ext.yml>`, which is an extended version of the first playbook:
|
||||
|
||||
.. literalinclude:: sample_files/first_playbook_ext.yml
|
||||
:language: YAML
|
||||
|
||||
The extended first playbook has four tasks in a single play. Run it with the same command you used above. The output shows you the change Ansible made to the config:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos first_playbook_ext.yml
|
||||
|
||||
PLAY [First Playbook]
|
||||
************************************************************************************************************************************
|
||||
|
||||
TASK [Gathering Facts]
|
||||
***********************************************************************************************************************************
|
||||
ok: [vyos.example.net]
|
||||
|
||||
TASK [Get config for VyOS devices]
|
||||
**********************************************************************************************************************************
|
||||
ok: [vyos.example.net]
|
||||
|
||||
TASK [Display the config]
|
||||
*************************************************************************************************************************************
|
||||
ok: [vyos.example.net] => {
|
||||
"failed": false,
|
||||
"msg": "The hostname is vyos and the OS is VyOS"
|
||||
}
|
||||
|
||||
TASK [Update the hostname]
|
||||
*************************************************************************************************************************************
|
||||
changed: [vyos.example.net]
|
||||
|
||||
TASK [Get changed config for VyOS devices]
|
||||
*************************************************************************************************************************************
|
||||
ok: [vyos.example.net]
|
||||
|
||||
TASK [Display the changed config]
|
||||
*************************************************************************************************************************************
|
||||
ok: [vyos.example.net] => {
|
||||
"failed": false,
|
||||
"msg": "The hostname is vyos-changed and the OS is VyOS"
|
||||
}
|
||||
|
||||
PLAY RECAP
|
||||
************************************************************************************************************************************
|
||||
vyos.example.net : ok=6 changed=1 unreachable=0 failed=0
|
||||
|
||||
|
||||
This playbook is useful. However, running it still requires several command-line flags. Also, running a playbook against a single device is not a huge efficiency gain over making the same change manually. The next step to harnessing the full power of Ansible is to use an inventory file to organize your managed nodes into groups with information like the ``ansible_network_os`` and the SSH user.
|
||||
23
docs/docsite/rst/network/getting_started/index.rst
Normal file
23
docs/docsite/rst/network/getting_started/index.rst
Normal file
@@ -0,0 +1,23 @@
|
||||
**************************************************
|
||||
An Introduction to Network Automation with Ansible
|
||||
**************************************************
|
||||
|
||||
Ansible modules support a wide range of vendors, device types, and actions, so you can manage your entire network with a single automation tool. With Ansible, you can:
|
||||
|
||||
- Automate repetitive tasks to speed routine network changes and free up your time for more strategic work
|
||||
- Leverage the same simple, powerful, and agentless automation tool for network tasks that operations and development use
|
||||
- Separate the data model (in a playbook or role) from the execution layer (via Ansible modules) to manage heterogeneous network devices
|
||||
- Benefit from community and vendor-generated sample playbooks and roles to help accelerate network automation projects
|
||||
- Communicate securely with network hardware over SSH or HTTPS
|
||||
|
||||
Who should use this guide?
|
||||
================================================================================
|
||||
|
||||
This guide is intended for network engineers using Ansible for the first time. If you understand networks but have never used Ansible, work through the guide from start to finish.
|
||||
|
||||
This guide is also useful for experienced Ansible users automating network tasks for the first time. You can use Ansible commands, playbooks and modules to configure hubs, switches, routers, bridges and other network devices. But network modules are different from Linux/Unix and Windows modules, and you must understand some network-specific concepts to succeed. If you understand Ansible but have never automated a network task, start with the second section.
|
||||
|
||||
This guide introduces basic Ansible concepts and guides you through your first Ansible commands, playbooks and inventory entries.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
@@ -0,0 +1,85 @@
|
||||
******************************************
|
||||
Beyond the Basics
|
||||
******************************************
|
||||
|
||||
This page introduces some concepts that help you manage your Ansible workflow: roles, directory structure, and source control. Like the Basic Concepts at the beginning of this guide, these intermediate concepts are common to all uses of Ansible. This page also offers resources for learning more.
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
Beyond Playbooks: Moving Tasks and Variables into Roles
|
||||
================================================================================
|
||||
|
||||
Roles are sets of Ansible defaults, files, tasks, templates, variables, and other Ansible components that work together. As you saw on the Working with Playbooks page, moving from a command to a playbook makes it easy to run multiple tasks and repeat the same tasks in the same order. Moving from a playbook to a role makes it even easier to reuse and share your ordered tasks. For more details, see the :doc:`documentation on roles<../../user_guide/playbooks_reuse_roles>`. You can also look at :doc:`Ansible Galaxy<../../reference_appendices/galaxy>`, which lets you share your roles and use others' roles, either directly or as inspiration.
|
||||
|
||||
A Typical Ansible Filetree
|
||||
================================================================================
|
||||
|
||||
Ansible expects to find certain files in certain places. As you expand your inventory and create and run more network playbooks, keep your files organized in your working Ansible project directory like this:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
.
|
||||
├── backup
|
||||
│ ├── vyos.example.net_config.2018-02-08@11:10:15
|
||||
│ ├── vyos.example.net_config.2018-02-12@08:22:41
|
||||
├── first_playbook.yml
|
||||
├── inventory
|
||||
├── group_vars
|
||||
│ ├── vyos.yml
|
||||
│ └── eos.yml
|
||||
├── roles
|
||||
│ ├── static_route
|
||||
│ └── system
|
||||
├── second_playbook.yml
|
||||
└── third_playbook.yml
|
||||
|
||||
The ``backup`` directory and the files in it get created when you run modules like ``vyos_config`` with the ``backup: yes`` parameter.
|
||||
|
||||
|
||||
Tracking Changes to Inventory and Playbooks: Source Control with Git
|
||||
================================================================================
|
||||
|
||||
As you expand your inventory, roles and playbooks, you should place your Ansible projects under source control. We recommend ``git`` for source control. ``git`` provides an audit trail, letting you you track changes, roll back mistakes, view history and share the workload of managing, maintaining and expanding your Ansible ecosystem. There are plenty of tutorials and guides to using ``git`` available.
|
||||
|
||||
Resources and Next Steps
|
||||
================================================================================
|
||||
|
||||
Text
|
||||
--------
|
||||
|
||||
Read more about Ansible for Network Automation:
|
||||
|
||||
- Network Automation on the `Ansible website <http://ansible.com/overview/networking>`_
|
||||
- Ansible Network `Blog posts <http://ansible.com/blog/topic/networks>`_
|
||||
|
||||
Events (on Video and in Person)
|
||||
--------------------------------
|
||||
|
||||
All sessions at Ansible events are recorded and include many Network-related topics (use Filter by Category to view only Network topics). You can also join us for future events in your area. See:
|
||||
|
||||
- `Recorded AnsibleFests <https://www.ansible.com/resources/videos>`_
|
||||
- `Recorded AnsibleAutomates <https://www.ansible.com/resources/webinars-training>`_
|
||||
- `Upcoming Ansible Events <https://www.ansible.com/community/events>`_ page.
|
||||
|
||||
GitHub Repos
|
||||
----------------
|
||||
|
||||
Ansible hosts module code, examples, demonstrations, and other content on GitHub. Anyone with a GitHub account is able to create Pull Requests (PRs) or issues on these repos:
|
||||
|
||||
- `Network-Automation <https://github.com/network-automation>`_ is an open community for all things network automation
|
||||
- `Ansible <https://github.com/ansible/ansible>`_ is the main codebase, including code for network modules
|
||||
|
||||
Email
|
||||
--------
|
||||
|
||||
Join the Ansible Network Community email list:
|
||||
|
||||
- email ansible-network@redhat.com and we will get you added right away
|
||||
|
||||
IRC
|
||||
--------
|
||||
|
||||
Join us on Freenode IRC:
|
||||
|
||||
- ``#ansible-network`` Freenode channel
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
************************************************************
|
||||
How Network Automation is Different
|
||||
************************************************************
|
||||
|
||||
Network automation leverages the basic Ansible concepts, but there are important differences in how the network modules work. This introduction prepares you to understand the exercises in this guide.
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
Execution on the Control Node
|
||||
================================================================================
|
||||
|
||||
Unlike most Ansible modules, network modules do not run on the managed nodes. From a user's point of view, network modules work like any other modules. They work with ad-hoc commands, playbooks, and roles. Behind the scenes, however, network modules use a different methodology than the other (Linux/Unix and Windows) modules use. Ansible is written and executed in Python. Because the majority of network devices can not run Python, the Ansible network modules are executed on the Ansible control node, where ``ansible`` or ``ansible-playbook`` runs.
|
||||
|
||||
Execution on the control node shapes two other differences in how network modules function:
|
||||
|
||||
- Network modules do not run every task in a playbook. They request current config first, compare current config to the state described by the task or playbook, and execute a task only if it changes the state of the managed node.
|
||||
|
||||
- Network modules that offer a backup option write the backup files onto the control node. With Linux/Unix modules, where a configuration file already exists on the managed node(s), the backup file gets written by default in the same directory as the new, changed file. Network modules do not update configuration files on the managed nodes, because network configuration is not written in files. Network modules write backup files on the control node, in the `backup` directory under the playbook root directory.
|
||||
|
||||
Multiple Communication Protocols
|
||||
================================================================================
|
||||
|
||||
Because network modules execute on the control node instead of on the managed nodes, they can support multiple communication protocols. The communication protocol (XML over SSH, CLI over SSH, API over HTTPS) selected for each network module depends on the platform and the purpose of the module. Some network modules support only one protocol; some offer a choice. The most common protocol is CLI over SSH. You set the communication protocol with the ``ansible_connection`` variable:
|
||||
|
||||
.. csv-table::
|
||||
:header: "Value of ansible_connection", "Protocol", "Requires"
|
||||
:widths: 30, 10, 10
|
||||
|
||||
"network_cli", "CLI over SSH", "network_os setting"
|
||||
"netconf", "XML over SSH", "network_os setting"
|
||||
"local", "depends on provider", "provider setting"
|
||||
|
||||
Beginning with Ansible 2.5, we recommend using ``network_cli`` or ``netconf`` for ``ansible_connection`` whenever possible. For details on using API over HTTPS connections, see the platform-specific pages.
|
||||
|
||||
|
||||
Modules Organized by Network Platform
|
||||
================================================================================
|
||||
|
||||
A network platform is a set of network devices with a common operating system that can be managed by a collection of modules. The modules for each network platform share a prefix, for example:
|
||||
|
||||
- Arista: ``eos_``
|
||||
- Cisco: ``ios_``, ``iosxr_``, ``nxos_``
|
||||
- Juniper: ``junos_``
|
||||
- VyOS ``vyos_``
|
||||
|
||||
All modules within a network platform share certain requirements. Some network platforms have specific differences - see the platform-specific documentation for details.
|
||||
|
||||
|
||||
Privilege Escalation: `authorize` and `become`
|
||||
================================================================================
|
||||
|
||||
Several network platforms support privilege escalation, where certain tasks must be done by a privileged user. This is generally known as ``enable`` mode (the equivalent of ``sudo`` in \*nix administration). Ansible network modules offer privilege escalation for those network devices that support it. However, different platforms use privilege escalation in different ways.
|
||||
|
||||
Network platforms that support ``connection: network_cli`` and privilege escalation use the top-level Ansible parameter ``become: yes`` with ``become_method: enable``. For modules in these platforms, a ``group_vars`` file would look like:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ansible_connection: network_cli
|
||||
ansible_network_os: ios
|
||||
ansible_become: yes
|
||||
ansible_become_method: enable
|
||||
|
||||
We recommend using ``network_cli`` connections whenever possible.
|
||||
|
||||
Some network platforms support privilege escalation but cannot use ``network_cli`` connections yet. This includes all platforms in older versions of Ansible (< 2.5) and HTTPS connections using ``eapi`` in version 2.5. With these connections, you must use a ``provider`` dictionary and include ``authorize: yes`` and ``auth_pass: my_enable_password``. For that use case, a ``group_vars`` file looks like:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ansible_connection: local
|
||||
ansible_network_os: eos
|
||||
# provider settings
|
||||
eapi:
|
||||
authorize: yes
|
||||
auth_pass: " {{ secret_auth_pass }}"
|
||||
port: 80
|
||||
transport: eapi
|
||||
use_ssl: no
|
||||
|
||||
And you use the ``setting`` variable in your play(s) or task(s):
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
tasks:
|
||||
- name: provider demo with eos
|
||||
eos_banner:
|
||||
banner: motd
|
||||
text: |
|
||||
this is test
|
||||
of multiline
|
||||
string
|
||||
state: present
|
||||
provider: "{{ eapi }}"
|
||||
|
||||
For more information, see :ref:`Become and Networks<become-network>`
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
|
||||
- name: Network Getting Started First Playbook
|
||||
connection: network_cli
|
||||
hosts: all
|
||||
tasks:
|
||||
|
||||
- name: Get config for VyOS devices
|
||||
vyos_facts:
|
||||
gather_subset: all
|
||||
|
||||
- name: Display the config
|
||||
debug:
|
||||
msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
|
||||
- name: Network Getting Started First Playbook Extended
|
||||
connection: network_cli
|
||||
hosts: all
|
||||
tasks:
|
||||
|
||||
- name: Get config for VyOS devices
|
||||
vyos_facts:
|
||||
gather_subset: all
|
||||
|
||||
- name: Display the config
|
||||
debug:
|
||||
msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
|
||||
|
||||
- name: Update the hostname
|
||||
vyos_config:
|
||||
backup: yes
|
||||
lines:
|
||||
- set system host-name vyos-changed
|
||||
|
||||
- name: Get changed config for VyOS devices
|
||||
vyos_facts:
|
||||
gather_subset: all
|
||||
|
||||
- name: Display the changed config
|
||||
debug:
|
||||
msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
|
||||
36
docs/docsite/rst/network/index.rst
Normal file
36
docs/docsite/rst/network/index.rst
Normal file
@@ -0,0 +1,36 @@
|
||||
******************************
|
||||
Ansible for Network Automation
|
||||
******************************
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Ansible Network modules extend 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.
|
||||
|
||||
For documentation on using a particular network module, consult the :doc:`list of all network modules<../modules/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<../modules/network_maintained>`.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:caption: Getting Started
|
||||
|
||||
getting_started/index
|
||||
getting_started/basic_concepts
|
||||
getting_started/network_differences
|
||||
getting_started/first_playbook
|
||||
getting_started/first_inventory
|
||||
getting_started/intermediate_concepts
|
||||
|
||||
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:caption: User Guide
|
||||
|
||||
user_guide/index
|
||||
user_guide/network_best_practices_2.5
|
||||
user_guide/network_debug_troubleshooting
|
||||
user_guide/network_working_with_command_output
|
||||
|
||||
15
docs/docsite/rst/network/user_guide/index.rst
Normal file
15
docs/docsite/rst/network/user_guide/index.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
************************************************
|
||||
User Guide to to Network Automation with Ansible
|
||||
************************************************
|
||||
|
||||
More content coming soon!
|
||||
|
||||
Who should use this guide?
|
||||
================================================================================
|
||||
|
||||
This guide is intended for network engineers using Ansible for automation. It covers advanced topics. If you understand networks and Ansible, this guide is for you. You may read through the entire guide if you choose, or use the links below to find the specific information you need.
|
||||
|
||||
If you're new to Ansible, or new to using Ansible for network automation, start with the :doc:`Getting Started Guide<../getting_started/index>`.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
@@ -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:`../installation_guide/intro_installation` for more information.
|
||||
* One or more network devices that are compatible with Ansible.
|
||||
* Basic understanding of YAML :doc:`../reference_appendices/YAMLSyntax`.
|
||||
* Basic understanding of Jinja2 Templates. See :doc:`../user_guide/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:`../user_guide/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-network>` 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:`../network/index`
|
||||
* :doc:`../user_guide/intro_inventory`
|
||||
* :ref:`Vault best practices <best_practices_for_variables_and_vaults>`
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,605 @@
|
||||
.. _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.
|
||||
|
||||
.. _socket_path_issue:
|
||||
|
||||
Category "socket_path issue"
|
||||
============================
|
||||
|
||||
**Platforms:** Any
|
||||
|
||||
The ``socket_path does not exist or cannot be found`` and ``unable to connect to socket`` messages are new in Ansible 2.5. These messages indicate that the socket used to communicate with the remote network device is unavailable or does not exist.
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
fatal: [spine02]: FAILED! => {
|
||||
"changed": false,
|
||||
"failed": true,
|
||||
"module_stderr": "Traceback (most recent call last):\n File \"/tmp/ansible_TSqk5J/ansible_modlib.zip/ansible/module_utils/connection.py\", line 115, in _exec_jsonrpc\nansible.module_utils.connection.ConnectionError: socket_path does not exist or cannot be found\n",
|
||||
"module_stdout": "",
|
||||
"msg": "MODULE FAILURE",
|
||||
"rc": 1
|
||||
}
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
fatal: [spine02]: FAILED! => {
|
||||
"changed": false,
|
||||
"failed": true,
|
||||
"module_stderr": "Traceback (most recent call last):\n File \"/tmp/ansible_TSqk5J/ansible_modlib.zip/ansible/module_utils/connection.py\", line 123, in _exec_jsonrpc\nansible.module_utils.connection.ConnectionError: unable to connect to socket\n",
|
||||
"module_stdout": "",
|
||||
"msg": "MODULE FAILURE",
|
||||
"rc": 1
|
||||
}
|
||||
|
||||
Suggestions to resolve:
|
||||
|
||||
Follow the steps detailed in :ref:`enable network logging <enable_network_logging>`.
|
||||
|
||||
If the identified error message from the log file is:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
2017-04-04 12:19:05,670 p=18591 u=fred | command timeout triggered, timeout value is 10 secs
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
2017-04-04 12:19:05,670 p=18591 u=fred | persistent connection idle timeout triggered, timeout value is 30 secs
|
||||
|
||||
Follow the steps detailed in :ref:`timeout issues <timeout_issues>`
|
||||
|
||||
|
||||
.. _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:logging`a_note_about_logging` 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 `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:
|
||||
|
||||
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:: console
|
||||
|
||||
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:: console
|
||||
|
||||
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 `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.
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user