So you want to start with Network Automation…

As we all know, things in networking are changing rapidly and so is changing the needed skillset for those who manage networks.

I’m definitely not an expert (I’m far from it) but lately many people asked me how to start with Network Automation. Now I’ve just received a message from a LinkedIn’s friend asking for something like this and I suddenly realized this would be a nice topic to write about ūüôā

In this post I’ll briefly summarize what you need to start your journey (or, at least, what I used to start mine).

Python

Even if we may be still far to deploy Software Defined Networks everywhere, software managed networks are a real thing and Python is the core of them.

Python is a pretty well-know programming language which is loved for its¬†ease of learning. I’ve studied C and Java at university and hated both of them, while I simply love Python ūüôā

There are plenty of available resources for those who wish to study for free and the following is a little list of stuff I’ve personally used:

  • CodeAcademy: really nice course to start your journey. It let you approach the language in a very practical way. Anyway, it does not dig very deep into the language.
  • Coursera: the website is full of Python courses, from the basics to more advanced topics. I’ve attended a couple of them and I really appreciated them.
  • How to think like a computer scientist: this was the very first Python resource I’ve ever used. It is a very well written book covering all the foundation in a pretty deep and clear way.
  • Dive Into Python: this is a more advanced book for those of you who are¬†hungry of knowledge.

I’m sure the list of someone else would look completely different since there are so many resources out there. So just pick one of them and start ūüôā

APIs

Networking vendors have developed specialized APIs to help engineers interact with their devices. I’ll introduce some of them within this section.

Juniper PyEZ

Juniper¬†is working hard on automation and has developed the PyEZ library, supported by almost every JunOS device. Once you installed all the requirements, it’s really easy to start talking to your remote device:


>>> from jnpr.junos import Device
>>> from jnpr.junos.utils.config import Config
>>> from pprint import pprint
>>> my_device = Device(host='172.16.1.1', user='gabriele', password='gabriele')
>>> my_device.open()
Device(172.16.1.1)
>>> pprint(my_device.facts)
{'2RE': False,
'HOME': '/var/home/gabriele',
'domain': None,
'fqdn': 'Router1',
'hostname': 'Router1',
'ifd_style': 'CLASSIC',
'model': 'olive',
'personality': 'UNKNOWN',
'serialnumber': '',
'switch_style': 'NONE',
'vc_capable': False,
'version': '12.1R1.9',
'version_info': junos.version_info(major=(12, 1), type=R, minor=1, build=9)}

Here there are some other practical reference about it:

Cisco

Cisco is working toward enabling automation in today’s network as well (of course).

Cisco NX-API

If you want to talk to Cisco NX-OS devices, you can use their NX-API.

Jason Edelman did an awesome work on both introducing NX-API here and developing another API called pycsco that simplifies working with Cisco NX-OS switches that support NX-API.

Here you can also find the latest reference from Cisco itself: NX-API book.

Cisco IOS-XR

Elisa Jasinska¬†developed an API¬†to help interact with Cisco devices running IOS-XR. It’s called¬†pyIOSXR.

Arista EOS

If you want to use Arista EOS, you can pick eAPI. You can also find some references here and on Packet Pushers.

Netmiko

Another super useful tool is Netmiko. It’s not a¬†specialized¬†API but instead it’s used to send commands to network devices and retrieve their output. That’s a great resource for those who want to start with network automation and I’ve extensively used it in pretty much every¬†project I’ve done.

In addition, the list of supported devices is huge:

Cisco IOS
Cisco IOS-XE
Cisco ASA
Cisco NX-OS
Cisco IOS-XR
Cisco WLC (limited testing)
Arista vEOS
HP ProCurve
HP Comware (limited testing)
Juniper Junos
Brocade VDX (limited testing)
F5 LTM (experimental)
Huawei (limited testing)
A10 (limited testing)
Avaya ERS (limited testing)
Avaya VSP (limited testing)
OVS (experimental)
Enterasys (experimental)
Extreme (experiemental)
Fortinet (experimental)
Alcatel-Lucent SR-OS (experimental)

Netmiko’s been developed by¬†Kirk Byers¬†and he also wrote an amazing post on how to use it. Thank you Kirk ūüôā

NAPALM

This name shouldn’t sound new to you! ūüėČ

In fact, I’ve extensively talked about NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) in my previous¬†post.

If you didn’t read it, repent, go read it and come back here ūüôā

Automation tools: Ansible

Like NAPALM, this shouldn’t sound new! I’ve talked about Ansible in two of my previous posts (here and here).

Anyway, those posts could be difficult to understand if you’re completely new. In this case, don’t worry, you definitely can¬†be guided by Kirk and Jason (these two guys are awesome!):

  • Kirk wrote a very nice guide introducing Ansible playbooks and templates, splitting it into 3 parts (Part1, Part2, Part3). This is what I used to write my first blog post on Ansible (see just above).
  • Jason extensively wrote about Ansible basics¬†(this post is precious for those who just started to use the tool) and other more advanced applications as well (here, here and here).

Have I already said that these two are awesome? ūüôā

Fast-paced Courses

Last but not least, if you really want to boost your automation skills and have enough resources (or you’re lucky enough to receive support from your company) you¬†may want to attend live classes on Network Automation.

Jason Edelman si¬†delivering an awesome¬†Network Programming and Automation¬†course all around the world. It covers everything you need to move from novice, writing your first “Hello World!” in Python, to NetOps Ninja developing a working network automation Flask app.

During the course you’ll not just sit there listening to Jason, but you’ll go through 10+ hours of labs too. I’ve reviewed the whole lab section and it took me almost the full 10 hours to complete it (and I was not new to most of the topics!). So I think you can expect to spend at least 2 extra hours on this.

Summarizing: 4 days digging deep on Python and Network Automation including some cool tools like Ansible + 12 hours of practical labs + guidance from Jason Edelman, one of the most expert guy on the field =¬†How cool is this? ¬†ūüėÄ

tweet

Here it is the course schedule for the first part of the next year. Don’t¬†miss it! ūüėČ

 Conclusion

These are just some of the available¬†resource I used to start my journey with NetOps. There are tons of more resources out there¬†if you want to start practicing Network Automation or simply improve your coding skills so you have no excuses! Choose what¬†you want and just start! ūüôā

start

 

A Cisco, a Juniper, a Vyatta Router…and an Ansible Playbook

Here we are, 2.5 months are passed since I started this challenge¬†and it’s time to do some kind of review and summary of what I’ve done during this time:

  • I’ve publised 9 blog posts (with this one being the 9th)
  • I’ve published 2 interviews with engineers from Google and Cisco (another interview is already completed and I’ll post it soon)
  • I’ve completed a Coursera’s course about Python
  • I’ve achieved the Juniper JNCIA certification
  • I’ve achieved the Vyatta BCVRE certification
  • I’ve started to study and practice network automation and Linux skills

I’m quite satisfied so far, but my last goal is still too far and I need to work harder if I want to reach it.

In regards to the list above, I decided to build a little virtual lab to make some practice (and have fun ūüôā ). Specifically, I’m going to build a network with a Cisco router, a Juniper router and a Vyatta one. Then, I’m going to automatically generate EBGP configurations for each of them using Ansible and, lastly, push them to¬†the devices using a Python library.


ANSIBLE

Ansible is a great tool used to automate many kind of tasks, including the configuration and maintainance of IT infrastructure. It can also be used to help network engineers to simplify their day-to-day work and what we’ll see during¬†this post is just a veeeeeery little use case. This is the first time I play with it but I’m really interested in digging deeper.

Ansible Playbook’s key components I’ve used are:

  • Roles: in my case, I’ve used only one role,¬†router.
  • Tasks:¬†once the role is defined, Ansible will look for any¬†tasks to be completed.
  • Templates: a template is, basically, a model. I this case it’ll be a router configuration model.
  • Vars:¬†Ansible will build the actual configuration based on the defined model, using some values identified as vars

I’m pretty sure that this explanation is far to be clear at this time, but you can find many useful information on the official documentation website.


LAB SCENARIO

lab

The network is built using GNS3 and its VirtuaBox integration. This network includes:

  • A Cisco router:¬†Cisco IOS Software, 3600 Software (C3640-JK9S-M), Version 12.4(16)
  • A Juniper router:¬†JunOS Olive 12.1R1.9 (in VirtualBox)
  • A Vyatta router:¬†Brocade Vyatta 5415 vRouter 6.7 R9T60 (in VirtualBox)
  • A Linux machine: Ubuntu (in VirtualBox)

The devices are minimally configured, as shown here below where only the important configuration section, including interface configurations, are highlighted. In addition to this, I’ve enabled and configured SSH access for the user gabriele.

CISCO CONFIGURATION

interface FastEthernet0/0
 ip address 172.16.2.1 255.255.255.0
 duplex auto
 speed auto
!
interface FastEthernet1/0
 ip address 172.16.3.1 255.255.255.0
 duplex auto
 speed auto
!
interface FastEthernet2/0
 ip address 172.16.1.1 255.255.255.0
 duplex auto
 speed auto
!

JUNIPER CONFIGURATION

[edit]
gabriele@Router1# show interfaces
em0 {
   unit 0 {
      family inet {
         address 172.16.4.1/24;
        }
    }
}
em1 {
   unit 0 {
      family inet {
         address 172.16.3.2/24;
        }
    }
}

VYATTA CONFIGURATION

[edit]
gabriele@vyatta# show interfaces
   ethernet eth0 {
   address 172.16.2.2/24
   duplex auto
   hw-id 08:00:27:d2:5f:38
   smp_affinity auto
   speed auto
 }
   ethernet eth1 {
   address 172.16.4.2/24
   duplex auto
   hw-id 08:00:27:58:e3:1c
   smp_affinity auto
   speed auto
 }

ANSIBLE CONFIGURATION

My project’s directory tree looks like this:


gabriele@gabriele-VirtualBox:~/Desktop/BGP$ find . -type d
.
./roles
./roles/router
./roles/router/vars
./roles/router/tasks
./roles/router/templates

Inside the tasks subdirectory there is a file named main.yml


---
- name: Generate configuration files
 template: src=router_cisco.j2 dest=/home/gabriele/Desktop/BGP/{{item.hostname}}.txt
 with_items: cisco_template

- name: Generate configuration files
 template: src=router_juniper.j2 dest=/home/gabriele/Desktop/BGP/{{item.hostname}}.txt
 with_items: juniper_template

- name: Generate configuration files
 template: src=router_vyatta.j2 dest=/home/gabriele/Desktop/BGP/{{item.hostname}}.txt
 with_items: vyatta_template

The “—” pattern at the beginning of the file indicates it is a YAML file. The field called¬†name¬† indicates the name of the tasks that have to be execute: generation of 3 template based on the structure of something called¬†cisco_template, juniper_template¬†and¬† vyatta_template.¬†Where are those models?

They resides inside the template directory..


gabriele@gabriele-VirtualBox:~/Desktop/BGP/roles/router/templates$ ls
router_cisco.j2 router_juniper.j2 router_vyatta.j2


..and they appear as follows.

router_cisco.j2


configure terminal
{% for interface in cisco_loopback %}
interface {{interface.name}}
ip address {{interface.address}} {{interface.mask}}
{% endfor %}

router bgp {{item.as}}
{% for neighbor in cisco_neighbors %}
neighbor {{neighbor.id}} remote-as {{neighbor.as}}
{% endfor %}
{% for loopback in cisco_loopback %}
network {{loopback.network}} mask {{loopback.mask}}
{% endfor %}


juniper_template.j2


configure
set protocols bgp group external-peers type external
set routing-options autonomous-system {{item.as}}
{% for neighbor in juniper_neighbors %}
set protocols bgp group external-peers neighbor {{neighbor.id}} peer-as {{neighbor.as}}
{% endfor %}
{% for loopback in juniper_loopback %}
set interface lo0 unit 0 family inet address {{loopback.address}}
set policy-options prefix-list Loopback {{loopback.network}}
{% endfor %}
set policy-options policy-statement ebgp term 1 from prefix-list Loopback
set policy-options policy-statement ebgp term 1 then accept
set protocols bgp group external-peers export ebgp
commit


vyatta_template.j2


configure
set protocols bgp {{item.as}}
{% for neighbor in vyatta_neighbors %}
set protocols bgp {{item.as}} neighbor {{neighbor.id}} remote‚Äźas {{neighbor.as}}
{% endfor %}
{% for loopback in vyatta_loopback %}
set interface loopback lo address {{loopback.address}}
set protocols bgp {{item.as}} network {{loopback.network}}
{% endfor %}
commit


These are Jinja2 files and, basically, are a set of configuration commands with something “strange”¬†inside. In fact, all the things inside curly braces are variable that Ansible will use to build the actual models.

So, for exampe, the snippet below means that somewhere (inside the vars directory) exists an iterable called vyatta_loopback which can be looped and its values as and network are assigned to the template.


{% for loopback in vyatta_loopback %}
set interface loopback lo address {{loopback.address}}
set protocols bgp {{item.as}} network {{loopback.network}}
{% endfor %}

One last thing should be examinated: the vars directory. Anyway, in this stage it is empty. Why? Because I decided to let the user to dinamically configure it using a Python script.


BGP Script

The whole project, including the Python script can be found here.

We can choose to execute the AutomateBGP.py in 2 ways:

  • including some options like¬†username¬†and¬†password¬†to be used for the SSH connection to the devices,¬†and a file_name¬†containing devices’ IP addresses and platform.
  • if we execute it without including any parameters, the script will ask us to insert all the missing values.

After this, the user will be asked to insert some information about Loopback interfaces (address, network and mask), BGP AS and BGP neighbors.

screen

Now that we have all the information we needed, we can go back to the vars directory, where the script creates a new main.yml file containing all the variables needed by Ansible to build the templates.


---
cisco_template:
- { hostname: cisco_template, as: 10 }

cisco_loopback:
- { name: lo0, address: 1.1.1.1, network: 1.1.1.0, mask: 255.255.255.0 }
- { name: lo1, address: 11.11.11.11, network: 11.11.11.0, mask: 255.255.255.0 }

cisco_neighbors:
- { id: 172.16.2.2, as: 30 }
- { id: 172.16.3.2, as: 20 }

juniper_template:
- { hostname: juniper_template, as: 20 }

juniper_loopback:
- { name: 1, address: 2.2.2.2/24, network: 2.2.2.0/24 }
- { name: 2, address: 22.22.22.22/24, network: 22.22.22.0/24 }

juniper_neighbors:
- { id: 172.16.3.1, as: 10 }
- { id: 172.16.4.2, as: 30 }

vyatta_template:
- { hostname: vyatta_template, as: 30 }

vyatta_loopback:
- { name: 1, address: 3.3.3.3/24, network: 3.3.3.0/24 }

vyatta_neighbors:

- { id: 172.16.2.1, as: 10 }
- { id: 172.16.4.1, as: 20 }

The next step is to let Ansible generate all the configuration template.


os.system("ansible-playbook site.yml")

This line of code has the effect to create 3 new text files: cisco_template.txt, juniper_template.txt, vyatta_template.txt.


PLAY [Generate router configuration files] ************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [router | Generate configuration files] *********************************
changed: [localhost] => (item={'as': 10, 'hostname': 'cisco_template'})

TASK: [router | Generate configuration files] *********************************
changed: [localhost] => (item={'as': 20, 'hostname': 'juniper_template'})

TASK: [router | Generate configuration files] *********************************
changed: [localhost] => (item={'as': 30, 'hostname': 'vyatta_template'})

PLAY RECAP ********************************************************************
localhost : ok=4 changed=3 unreachable=0 failed=0

cisco_template.txt


configure terminal
interface lo0
ip address 1.1.1.1 255.255.255.0
interface lo1
ip address 11.11.11.11 255.255.255.0

router bgp 10
neighbor 172.16.2.2 remote-as 30
neighbor 172.16.3.2 remote-as 20
network 1.1.1.0 mask 255.255.255.0
network 11.11.11.0 mask 255.255.255.0

juniper_template.txt


configure
set protocols bgp group external-peers type external
set routing-options autonomous-system 20
set protocols bgp group external-peers neighbor 172.16.3.1 peer-as 10
set protocols bgp group external-peers neighbor 172.16.4.2 peer-as 30
set interface lo0 unit 0 family inet address 2.2.2.2/24
set policy-options prefix-list Loopback 2.2.2.0/24
set interface lo0 unit 0 family inet address 22.22.22.22/24
set policy-options prefix-list Loopback 22.22.22.0/24
set policy-options policy-statement ebgp term 1 from prefix-list Loopback
set policy-options policy-statement ebgp term 1 then accept
set protocols bgp group external-peers export ebgp
commit

vyatta_template.txt


configure
set protocols bgp 30
set protocols bgp 30 neighbor 172.16.2.1 remote‚Äźas 10
set protocols bgp 30 neighbor 172.16.4.1 remote‚Äźas 20
set interface loopback lo address 3.3.3.3/24
set protocols bgp 30 network 3.3.3.0/24
commit


PUSH IT!

One last step remains to complete the lab: pushing the configuration to the devices. I used Paramiko¬†to do so. It is a useful Python library to interact with network devices. I’ve written a¬†run_command()¬†function to split each template in single commands and then pushing them. Once the configuration is completed, the script informs you about the accomplishment.


def run_commands(ip_address, user, password, commandList, platform, buffer=5000):
    """ this function runs the specified commands on the node. """
    print "Configuring " + ip_address
    remote_conn_pre = paramiko.SSHClient()
    remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    remote_conn_pre.connect(ip_address, username=user, password=password)
    remote_conn = remote_conn_pre.invoke_shell()
    if platform == "cisco":
        remote_conn.send("enable\n")
        time.sleep(1)
        remote_conn.send(password+'\n')
        time.sleep(1)
    commands = commandList.split('\n')
    for com in commands:
        remote_conn.send(com+'\n')
        time.sleep(1)
        output = remote_conn.recv(buffer)

LET’S VERIFY

Now we can verify that everything has gone well (click the images to watch them larger)

Cisco

show

Juniper

show1

Vyatta

show2


CONCLUSIONS

It’s been really funny to code for this lab. If you look at the code, you’ll see it isn’t well optimized at all and it can be improved to catch exception, errors, adding use cases and so on. Anyway, my goal with this lab was to start playing with Ansible and to write some code, but it’d be too lenghty trying to optimize it at the moment.

I’m really interested in this kind of stuff so I’m always looking for new ideas to make some practice. Any kind of suggestion, tips or feedbacks are highly appreciated ūüôā

Bye!

Brocade Certified vRouter Engineer

I know I said that I’d have been focused on Linux skills during this month, but then I was reached out by this video from Brocade:

As the video explains, Brocade is giving the possibility to enroll in a free virtual course and obtain the Brocade Certified vRouter Engineer (BCVRE)¬†certification view a free voucher! In addition, the Brocade’s ads promote the certification as NFV (Network Function Virtualization)¬†related and this made it so interesting to me. So, I couldn’t help to start working on it.


Exam preparation

Exam objectives and informations can be found here

Brocade’s free course is organized into small video lectures (25 minutes circa each) for a total of 5 hours course. There is also a free study guide which can be used to¬†review some key topics and configurations. In addition to all of this Brocade has made available, for a 60-days trial, a vRouter image for you to make practice with its CLI.


Personal study experience

I enjoyed learning somenthing about Brocade products, but at the same time I’m quite disappointed with Brocade’s statement about the NFV nature of the course. In fact, the exam is not designed around NFV at all, if it were not for the virtual nature of the vRouter itself.

The exam is pretty simple being at an associted level. I only had to learn some vRouter features and the new CLI “language”. The latter is similar to Junos OS from Juniper and I had no problem with it since I passed my JNCIA exam one month ago.


Final impressions

My overall mood about the certification is pretty positive but now I feel the need to advance my knowledge on a more “vertical” direction. I will do so through the JNCIS¬†cert.

Now (this time I promise ūüôā ) I will focus more on Linux and Automation skills. In particular, I’m working on an network automation project so the next post will be about it.

Stay tuned ūüôā

First Milestone Reached: JNCIA Certified

Good news over here: today I passed the JNCIA exam, the first milestone of my Project:Me10 journey! ūüėÄ

I’m reeeeeally happy about that! I had no experience with Juniper products and at first I found it a little bit difficult to start typing in Junos (I used to think in IOS ūüôā ) but, once this first obstacle has been overcome, the preparation has been pretty easy.

Junos OS is an interesting platform and the JNCIA exam is focused on convincing you about this (succeeding). A nice thing about the Juniper Network Certification Program, is that you can obtain a 50% voucher over the exam prize passing a practice test on their website. That’s great! I only spent 50$ for my JNCIA exam!

My only complaint¬†is about the exam blueprint¬†which¬†lacks of focus on¬†major networking protocols and technologies. The certification is designed to be an introduction to Juniper’s world, but I thought I was gonna find more¬†CCNA-like contents. That’s why I can’t wait to start my JNCIS journey (which is the second milestone of the Project), in which I’ll find some interesting topics like IS-IS, BGP and High Availability (among many others).

But first I’ll take a little break and I’ll work on some Linux and Network Automation skills (and projects ūüôā ).

Stay tuned.

P.S.

Few weeks ago I’ve also won a 10$ Amazon Gift Card solving a game posted by David Swafford¬†(Datacenter Network Engineer at Facebook) in a network automation focused group on Facebook, which required to parse this command output in order to obtain a dictionary of port-channel numbers to their member interfaces (my solution here).

Nothing special, but something is better than nothing ūüėÄ

Update

Here it is a little update about my jouney.

As stated into the first post, my first milestone for¬†this challenge will be achieving the Juniper JNCIA certification and during the past days I’ve started to¬†study. In order to do so, I’m using several resources:

  • Junos as a Second Language-WBT:¬†I’ve already completed this mini-course whose focus is to¬†make easier the transition from other vendor based CLI (Cisco IOS) to Junos.
  • CBT Nuggets: Interesting video lectures held by Scott Morris discussing all the JNCIA exam objects.
  • Juniper Fast Track¬†stuff, including a free JNCIA study guide from Juniper itself.
  • GNS3 with Olive support, in order to emulate some simple network and get used to¬†the new configuration environment and syntaxt.

Although I’ve not yet dived deep into the subject, I think Junos has some really cool features like the separation between Control Plane and Data Plane, inner modularity with processes memory separation (so that no single fail would affect the whole system), FreeBSD based (so that it feel like working with Linux).

At the same time, I’m using this¬†Coursera course¬†as a refresher for my Python not-that-awesome skills.