Ansible for Arista EoS

This is a continuation of my previous blog on Arista Eapi. Ansible provides a recipe driven approach to manage servers/switches, I have covered Ansible in some of my previous blogs. In this blog, I will cover the following:

  • Ansible modules for Arista device
  • Ansible galaxy eos role for Arista device

There are 2 approaches to use Ansible with Arista device. Following picture from Arista illustrates this point:

arista2

  • The first approach is called remote approach from Ansible perspective. Here the ansible python script is transferred to Arista device using ssh and the python script is executed on the Arista device which connects locally to the device using Pyeapi which in turn talks through eapi.
  • The second approach is called local approach from Ansible perspective. Here the Ansible python script is run locally in the client machine which in turn talks to Pyeapi library which in turn talks to the remote device using eapi.
  • Typically, network devices dont allow running scripts directly on the device. In that case, only second option would be possible. In Arista’s case, there are no restrictions like this and both the approaches can be used for Ansible based automation.

Ansible modules are recipes for pre-defined functionality. Typically, these recipes take certain arguments and execute in an idempotent way where configuration changes are made if needed. Using a set of recipes, we can define how the end system configuration should look like. Following initial set of Ansible modules are available for Arista devices.

  • eos_command – sends a list of EOS commands to the node and returns the output
  • eos_vlan – provides configuration and state management of VLAN resources
  • eos_switchport – provides configuration and state management of switchport resources
  • eos_interface – provides configuration and state management for interfaces
  • eos_portchannel – provides configuration and state management for port-channel interfaces
  • eos_vxlan – provides configuration and state management for VxLAN tunnel interfaces
  • eos_ipv4interface – provides configuration and state management for IP interfaces

More modules like mlag, acl are available now.

Prerequisites:

  • Install Ansible on the client linux machine. In my case, client linux machine is running Ubuntu 14.04 and Ansible 1.8.4.
  • Enable Eapi on the Arista device, I covered this in the previous blog.
  • For approach 1, its needed to have password less ssh access.

More details on prerequisites are covered here.

Installing Arista Ansible modules:

To get latest Arista Ansible modules, we need to get this from github.

git clone https://github.com/arista-eosplus/ansible-eos.git

Approach 1(Remote approach):

For this approach, it is needed to install pyeapi on Arista device. First, download the library to local linux machine and then transfer to Arista device and then install it. If the Arista device has direct internet connectivity, we can download directly.
Transfer from local to remote Arista device:

scp ~/Downloads/pyeapi-0.3.0.tar.gz ansible@10.10.10.11:/tmp
scp path/netaddr-0.7.14.tar.gz  ansible@10.10.10.11:/tmp

Install from Arista linux shell:

sudo pip install /tmp/netaddr-0.7.14.tar.gz 
sudo pip install /tmp/pyeapi-0.3.0.tar.gz 

I installed netaddr since that was a prerequisite for pyeapi. It is also needed to define eapi credentials in the Arista device.

Following example shows creating vlans using Ansible vlan module.

ansible 10.10.10.11 -M ~/arista/ansible-eos/library/ -u ansible -m eos_vlan.py -a "vlanid=1001 state=present debug=yes"

Following example shows executing raw CLI using eos_command.py module.

ansible 10.10.10.11 -M ~/arista/ansible-eos/library/ -u ansible -m eos_command.py -a "commands='show version' debug=yes"

Following is a sample playbook with 2 tasks. The first task gets version and lldp neighbors, second task creates vlan 100. I have 2 switches defined in eos-grp in “/etc/ansible/hosts”. These tasks gets applied to both switches.

---
# Use remote approach
- hosts: eos-grp
  remote_user: ansible

  tasks:
  - name: show version
    eos_command:
    args: {commands: '{{ item }}' }
    with_items:
          - show version
          - show lldp neighbors
    register: eos_command_output

  - debug: var=eos_command_output

  - name: create vlan 100
    eos_vlan: vlanid=100
              name=vlan100
              state=present 

Following is a partial output(I have truncated the results):

$ ansible-playbook -M ~/arista/ansible-eos/library/ playbook7.yml 

PLAY [eos-grp] **************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [10.10.10.12]
ok: [10.10.10.11]

TASK: [show version] ********************************************************** 
changed: [10.10.10.12] => (item=show version)
changed: [10.10.10.11] => (item=show version)
changed: [10.10.10.12] => (item=show lldp neighbors)
changed: [10.10.10.11] => (item=show lldp neighbors)

TASK: [debug var=eos_command_output] ****************************************** 
ok: [10.10.10.11] => {
    "eos_command_output": {
        "changed": true, 
        "msg": "All items completed", 
        "results": [
            {
                "changed": true, 
                "invocation": {
                    "module_args": "", 
                    "module_name": "eos_command"
                }, 
                "item": "show version", 
                "output": [
                    {
                        "command": "show version", 
                        "encoding": "json", 
                        "result": {
                            "architecture": "i386", 
.
.
ok: [10.10.10.12] => {
    "eos_command_output": {
        "changed": true, 
        "msg": "All items completed", 
        "results": [
            {
                "changed": true, 
                "invocation": {
                    "module_args": "", 
                    "module_name": "eos_command"
                }, 
                "item": "show version", 
                "output": [
                    {
                        "command": "show version", 
                        "encoding": "json", 
                        "result": {
                            "architecture": "i386", 
.
.
}

TASK: [create vlan 100] ******************************************************* 
changed: [10.10.10.12]
changed: [10.10.10.11]

PLAY RECAP ******************************************************************** 
10.10.10.11                : ok=3    changed=1    unreachable=0    failed=0   
10.10.10.12                : ok=3    changed=1    unreachable=0    failed=0 

Approach 2(Local approach):

Following is an example of Ansible local adhoc approach to create vlans.

ansible 10.10.10.11 -M ~/arista/ansible-eos/library/ -c local -m eos_command.py -a "connection=veos01 commands='show version' debug=yes"

Following is an example of Ansible playbook local approach to get version and lldp neighbors. It is necessary to define eapi credentials for the devices mentioned in egrp in the local machine.

---
# Use local approach
- hosts: egrp
  remote_user: ansible
  connection: local

  tasks:
  - name: show version and lldp neighbors
    eos_command: connection={{ inventory_hostname }}
    args: {commands: '{{ item }}' }
    with_items:
          - show version
          - show lldp neighbors
    register: eos_command_output

  - debug: var=eos_command_output

Ansible Galaxy EoS role:

Ansible Galaxy is a library of pre-defined roles. The roles contain a list of pre-requisites that needs to be executed as part of the role. For example, there is a need to install eapi library and jsonrpc library for running Ansible modules. This can be put as part of bootstrap task list.

To install eos role, execute the following command:

ansible-galaxy install arista.eos

After this, we would see the following “arista.eos” present under “/etc/ansible/roles” with the following directory structure.

CHANGELOG.md  defaults  files  handlers  library  LICENSE  meta  README.md  tasks  vars

The library contains the modules and the tasks contain any bootstrapping needed.

Following is a sample playbook to create vlan 100 with eos role.

- name: eos nodes
  hosts: eos-grp
  gather_facts: no
  sudo: true
  user: ansible

  roles:
    - role: arista.eos

  tasks:
    - name: create a vlan
      eos_vlan: name=myvlan vlanid=100 state=configured
                eapi_username=arista
                eapi_password=arista
                eapi_hostname={{ inventory_hostname }}

Following is the output:

PLAY [eos nodes] ************************************************************** 

TASK: [arista.eos | check if running on eos node] ***************************** 
ok: [10.10.10.11]
ok: [10.10.10.12]

TASK: [arista.eos | collect eos facts] **************************************** 
ok: [10.10.10.11]
ok: [10.10.10.12]

TASK: [arista.eos | include eos variables] ************************************ 
ok: [10.10.10.12]
ok: [10.10.10.11]

TASK: [arista.eos | check for working directory] ****************************** 
ok: [10.10.10.12]
ok: [10.10.10.11]

TASK: [arista.eos | create source] ******************************************** 
skipping: [10.10.10.11]
skipping: [10.10.10.12]

TASK: [arista.eos | check if pip is installed] ******************************** 
ok: [10.10.10.11]
ok: [10.10.10.12]

TASK: [arista.eos | copy pip extension to node] ******************************* 
skipping: [10.10.10.12]
skipping: [10.10.10.11]

TASK: [arista.eos | create tmp config file to load pip] *********************** 
skipping: [10.10.10.11]
skipping: [10.10.10.12]

TASK: [arista.eos | load pip eos extension] *********************************** 
skipping: [10.10.10.11]
skipping: [10.10.10.12]

TASK: [arista.eos | copy required libraries to node] ************************** 
ok: [10.10.10.12] => (item=eapilib-0.1.0.tar.gz)
ok: [10.10.10.11] => (item=eapilib-0.1.0.tar.gz)

TASK: [arista.eos | install required libraries] ******************************* 
ok: [10.10.10.11] => (item=eapilib-0.1.0.tar.gz)
changed: [10.10.10.12] => (item=eapilib-0.1.0.tar.gz)

TASK: [arista.eos | install jsonrpclib] *************************************** 
skipping: [10.10.10.11]
skipping: [10.10.10.12]

TASK: [arista.eos | install required libraries and dependencies] ************** 
skipping: [10.10.10.12] => (item=eapilib-0.1.0.tar.gz)
skipping: [10.10.10.11] => (item=eapilib-0.1.0.tar.gz)

TASK: [create a vlan] ********************************************************* 
ok: [10.10.10.11]
ok: [10.10.10.12]

PLAY RECAP ******************************************************************** 
10.10.10.11                : ok=9    changed=0    unreachable=0    failed=0   
10.10.10.12                : ok=9    changed=1    unreachable=0    failed=0  

I specifically deleted eapi library in 10.10.10.12 node, thats why we see “changed=1” for 10.10.10.12 node.

When its needed to manage a single device, scripts using Eapi and Pyeapi would suffice. Ansible helps with managing a large number of devices and Ansible modules play an important role there. The Ansible modules for Arista devices available now covers only basic configuration/monitoring, this can be expanded based on the use case.

References:

Pictures used in this blog are from references.

Advertisements

2 thoughts on “Ansible for Arista EoS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s