In this lesson we’ll be going over the Junos automation stack, and an overview of the tools that are available for automating Juniper devices.
First up, let’s take a look at the Junos automation stack. I know that this graphic is a little busy, we’re going to spend a little bit of time and discuss how this is laid out and what it really means.
First I wanted to make sure we have a definition for API, that it is an Application Programming Interface. It’s a system used for programmatically interfacing with a service. What this means is, us as the programmers or administrators are able to write code to programmatically interface with some device to perform administrative functions, rather than just at the CLI.
So, rather than being at the console by plugging in, or SSH into the device, we are actually writing scripting tools to be able to automate our actions. With this ability it really opens up a wide range of things that can be done to make your day-to-day life easier, and make your work quicker. When we can automate repetitive tasks, we’re spending less time doing the menial mundane things, and more time figuring out really value-added problems for your network and your customers.
Let’s take a look at this large block diagram of the Junos Automation Stack. Starting at the bottom, we have our routing engine and packet forwarding engine as our base layer. This is the physical compute hardware of the Junos network devices. Junos OS runs on top of our routing engine. The mgd process or management daemon, as discussed in the Juniper OS Fundamentals lesson, this is where all of our management processes happen.
Above the mgd process, so on top of that, runs the XML API. This is really the largest part of our automation stack, where things start really getting interesting. Certain things run on top of our XML API, like the CLI. When we’re actually sitting at the console and typing in commands, the CLI translates that to and from XML, so that it interfaces with the XML API!
This is so huge because it means at the core of our interactions with Junos are APIs, where our manual command line interface that we are interfacing with as as humans typing at the console, that this is really just a front-end to an API on the device. Juniper has built APIs and automation into their system from the beginning, to make sure that from the bottom layer that we are able to automate our tasks.
Moving up another layer, we have NETCONF. This communication standard is also a really large portion of our automation stack here. NETCONF is a standards-based protocol for doing programmatic interfacing and remote management of network devices. That’s right, I said it is standards-based, so that is not Juniper specific. We’ll talk more about NETCONF later in this lesson, as well as the other items in the automation stack.
Moving right along, to an overview here of the XML API, the largest API for our Junos devices. So, the XML API is used for both off-box and on-box automation. What this means is you can actually write and store scripts on-box, on your physical device, and have them be executed by either operational mode commands, or triggered by some events, or even triggered at each commit. There are different ways to trigger and activate your scripts that are stored on-box, and only run individually on that physical box, whereas off-box is where you’d have some management server, like an Ansible management server or even just scripts run from your workstation managing potentially many devices at once.
On-box scripting can be done through several script types:
- Operational Scripts
- Event Scripts
- Commit Scripts
- SNMP Scripts
Operational scripts are executed by entering an operational mode command. Event scripts that are triggered by some event, a particular event log or correlation of events in the log. Commit scripts are triggered by each commit. Finally, SNMP scripts allow for the creation of custom SNMP OIDs
Off-box automation with the XML API is generally done over NETCONF, defined in RFC 6241, if you’re interested to look into that a little more, it usually operates over SSH version 2. NETCONF can be performed over other protocols as well like Telnet.
NETCONF is supported by all Juniper devices. The way a NETCONF request is formatted, we have our RPC tag opening to indicate that we are running some remote procedure call, and we submit this XML, which we go over in much more detail in a later lesson.
We have our RPC here of <get-software-information>, and we have the open and close tag, it’s an empty tag. We are sending this over SSH through a NETCONF session, and we get some response. That response is going to look like the XML response above, where we have our RPC reply tags encapsulating our full reply, and then we have our <software-information> and <junos-version> etc. I ended up trimming out much of the response for brevity.
Luckily, we do have tools available to be able to parse this information easily, which will make working with NETCONF a whole lot easier, though on the base level this is really what it looks like in the background. It’s opening an SSH session to our device and it is sending this text for our request and this is the type of text that it’s getting in response for our reply, and then that is parsed to be able to get it into a format that we can actually use within our scripts.
Trying to type in all of those XML RPCs and parse the RPC replies when working with NETCONF in a script is going to be really problematic, so this is why we have NETCONF libraries available for various programming languages, and ones that Juniper has even developed and supports themselves to make it work much easier. Programming interactions with NETCONF would be very difficult without some abstraction modules or libraries.
Ruby and Python, although they are very popular, they do have open source support which means that Juniper JTAC does not officially support the library. Ruby is very easy to install, and has a lot of features, it has limited support though and some dependencies.
Python is really the most popular because it is the most popular scripting language in the world currently. Java and Pearl though are officially supported by JTAC and these are available on the Juniper website.
Java is unique in that it has zero dependencies, it’s a single .jar file for the NETCONF library and no other dependent packages. Pearl however is really the most difficult to install, but it is the most mature and oldest API from Juniper; so it is the most well understood and well known. If you’re an enterprise and are really looking for the most stable language to work with NETCONF for your Juniper devices, then Pearl might be the way to go.
Junos PyEZ, so this is meaning ‘PythonEZ’. It’s a micro-framework developed by Juniper and it is open source. It’s used to interface with Junos via NETCONF and automatically parses XML RPC replies. It is really easy to use, it works on any Juniper device running Junos 11.4 or later. We’re up to a much later version than that now (version 22 currently), most of your devices out there will run at least 11.4.
PyEZ is an open source library and it contains file system utilities, providing programmatic access to administrative functions to move or rename files, we can even do software upgrades using PyEZ.
PyEZ is often what’s used in the background of automation management systems so like Ansible and Salt, to perform their automation with Juniper devices.
So, speaking of Ansible and Salt, these are automation management platforms. Many different platforms exist and the ones that we’re touching on here are Ansible, Salt, Puppet and Chef. Now, Puppet and Chef we’re only going to mention in this lesson here and talk about very briefly as you should be aware of what their difference is from Ansible and Salt but other than that you don’t need to know much about how they actually work for the JNCIA-DevOps.
Features that are common to automation management platforms are that they manage multiple devices at the same time and that they are very scalable. These automation platforms are intended to go from individual devices, all the way up to thousands of devices and be able to handle that very well.
They are declarative in nature, which means we specify the desired state and the automation management system takes care of how to get to that state. The actual commands that are run or configuration commands that are entered to get to the desired state are handled by our automation management platform. They will all obtain operational state information. The XML API via NETCONF is primarily used as the communication method for juniper devices. So, let’s go ahead and just take a brief look at each of these.
First up: Ansible
One of Ansible’s big features that it is agentless. This means that a piece of software does not need to run on our individual device, we don’t need to go installing some agent or client on our Juniper devices, because we are interfacing using NETCONF over SSH, and it does that from the Ansible Management Server.
The 10,000ft view of the architecture of Ansible is it’s got playbooks and plugins. It uses Python, because Ansible is written in Python.
The module library, these are the official Juniper developed modules and this is not an exhaustive list but these are some that will then be run to execute tasks to obtain information from our devices that the Ansible Management Server is managing.
Ansible requires minimal coding skills as all the playbooks, which are the files that are used to define the device state or the modules that we want to run, these are all written in YAML. We’ll be taking a closer look at what YAML looks like and how to write YAML files in a later lesson.
So, moving on to: Salt
Salt is very similar to Ansible in that it is also agentless. Salt has a Salt Master, and uses this concept of the message bus. Now, for Salt it requires running a Junos Proxy Minion in order to interface with each individual Junos device, which limits its scalability for Juniper device management.
It supports several operation, like fact gathering, configuration management, RPC execution, software installation and copying files to and from the device. Saltstack, the developers of Salt, really pride themselves on being “event driven infrastructure”, which this is where the message bus comes into play.
The message bus is a high throughput messaging system to be able to have event reaction and event driven infrastructure. Taking events from our Junos Proxy Minion, which in turn is directly connected to our juniper devices, and turning that into reactive events or reactive operations performed on the devices.
Next up: Puppet
Puppet and Chef are both agent-based. Puppet has this concept of the Puppet Master, it uses ‘netdev’, which is a Puppet module stored on the Puppet Master. The device running the Puppet agent downloads netdev via SSL onto our device. The Puppet agent is written in Ruby, and we have our NETCONF Ruby gem, and our ruby interpreter in the jpuppet SDK package. So, jpuppet is actually the puppet agent that is running on our device, and it uses the ruby interpreter in that package to run the NETCONF gem and interface with the Juniper XML API on that device.
Finally, we’re going to take a brief look at Chef
As mentioned, this is also agent-based, which means it needs the chef sdk package installed on our network device.
Something important to note with both Puppet and Chef, because they require having an agent installed, they’re not compatible with all Juniper devices. If you’re looking for maximum compatibility, Ansible or Salt are the way to go.
Chef is also written in Ruby, and uses the NETCONF Ruby gem to interface with the Juniper XML API. The Chef server runs Recipes. Recipes define what tasks to execute on our managed devices or what state to bring the device to.
This lesson is just a very high level overview to give a taste of the automation tools that are available to us and how Juniper has built automation into their devices from the very beginning. In later lessons we’ll take a deeper dive into some of these tools, and how to use them!