Break out the popcorn and candy for the conclusion to my exploration of Network Service based automation and how we’re using it within DevNet Sandbox as part of our own internal automation strategy. In Part 1 the focus was on what consuming network services was like after they were built, and everyone immediately started asking me –
“But Hank, how do I BUILD something like this?!?”
You didn’t think I’d leave you hanging did you?
In Part 2 we’ll take a look the development process. I walk you through the 4 steps in service creation.
- Generation of the pseudo code for what you want the experience to be like (there’s a reason we looked at experience in Part 1)
- Building the data model for your new service.
- Generating network configuration templates for final device configurations
- Using Python to combine the data model with the templates
- Much rejoicing!
Code that goes along with this Part 2 is up on DevNet Code Exchange. Check it out.
I hope you enjoyed Part 2 and the dive into service creation. If you didn’t catch Part 1, it’s available for you to review and watch anytime – bring your own popcorn.
Oh.. and don’t forget to checkout the previous blogs in the series
- NetDevOps Invades DevNet Sandbox
- Detecting Network Abuse with Automation
- Some Real World Network Automation Lessons Learned
- Preparing to Automate a New Data Center for DevNet Sandbox
If the idea behind using Cisco NSO and Network Services has you intrigued, don’t forget you can download Cisco NSO for FREE from DevNet to test out for non-production use right now. And here are some other handy links for more resources.
- NetDevOps Live! Episode introducing Cisco NSO
- Cisco NSO Learning Labs
- Cisco NSO Developer Hub Community
Thanks for stopping by, please do let me know what you think about the work we are doing, and any questions you might have. You can use the comments here, or find me over on Twitter @hfpreston or on LinkedIn. Until next time!
If you’re more a “read” than “watch” content consumer, here’s the transcript from the video.
Hey everybody. Hank with DevNet here, back for part two in Network Service Based Automation. In part one we took a look at the experience of automating and managing your network configuration with a service based approach. And into this part we’re going to look at what it takes to actually build that approach that’s there. If you haven’t watched part one first, I highly suggest taking a look at it because it’ll set the context for what we’re after in today’s part two video. All right, let’s jump right in.
Now the service that we’re going to be looking at designing is the VLAN tenant service. Now the VLAN tenant service actually sits on top of our VLAN fabric. Here in our drawing we can see that I’ve got my data center. And a reminder, these are the actual services we’re using to manage the DevNet sandbox and data center infrastructure. And so our VLAN fabric in this picture here is called internal, and it controls the switches that make up all of the elements for this network. And so these are going to be switch pairs. So a series of Nexus switches that are arranged in a pair that have VPC relationships, the VLAN fabric service takes care of building all of that for us.
The VLAN fabric service also connects out to any kind of independent switches that may have different hosts and things connected to it. And that VLAN fabric can actually extend all the way out into things like your compute environment with Cisco UCS to manage VLANs and VNIC templates in your UCS infrastructure, and even into VMware to manage and make sure that the port groups for any networks and VLANs are automatically created inside of the DVs and V switches that are there. And so our VLAN fabric is kind of that underlay structure. What we’re going to design is a VLAN tenant service that can sit on top of that to deliver, actually end to host pieces that are there. So here in our drawing. The internal VLAN fabric is kind of made up of all of these. And what I want to do is kind of be able to spin up with ease, tenants such as our tenant admin here and our tenant shared service. Both of these tenants will sit on top of our VLAN fabric, so the same physical infrastructure, but will have separate layer two and layer three constructs. So VRFs, VLANs, SPIs, all of that is going to be separate and we want our VLAN tenant service to manage that. So that’s our goal.
Now when I sit down to work on a new service, the place I start is kind of the end state. What do I want it to feel like? What do I want the experience for the network developers and engineers that are going to consume the service to look like? And so I just start with a blank text editor, then I start out with what I’m going to call just pseudocode or pseudo experience.
Now as we mentioned in the first video, the actual network service delivers with CLI as well as an API. But we’ll start out with the CLI style experience because it’ll be mimicked in the API. And so we want a VLAN tenant, so we’re going to say, okay, I want to be able to create a VLAN tenant and that tenant’s going to have a name, we’ll call it NSO part two. Now that VLAN tenant rumor has to sit on top of a fabric and so we’re going to refer to the fabric. We have to call out which fabric in our data center because we might have more than one, does this connect to. So we’ll say fabric production.
Now that VLAN tenant may have multiple networks, right? If we think about our data center environment for our production applications, maybe we have multiple networks that are there. And so we’ll say network app servers one is perhaps the first network we want to create. And each network is going to need a VLAN ID. So VLAN ID, we’ll say 88 in this case. Now, networks need to have a network range or a prefix that goes along with it. So we’ll say, okay, well the network for this network, we could name it differently but in kind of the pseudocode approach, we’ll start out with just this. 10, one, 45, zero and we’ll say it’s a slash 24. So that indicates the actual kind of IP space that’s there.
Now this lays out the details of the, the VLAN network that’s there. We’ve got a name, we’ve got an ID, but we want to connect things into this, right? We’re going to need to connect into ours. And so we’ll say, okay, well we need to have some connections into our VLAN network that’s here. And these connections are going to be connected to a pair of switches. So we’ll say connections on switch pair, leaf 01.
And then how would we refer to those connections? These might be physical interfaces. And so we’ll say interface, let’s say 1/10 as an example interface. And on that interface, maybe we want to put a description. So we’ll say description, DB server. And then in this case, this is going to be an access port, right? We have to indicate what type is it, is it an access, is that a trunk? All right. So we’ve indicated how we can build an interface, but there might be more than one so we need to make sure that we can support a list of interfaces. So maybe interface 1/11 is another one, so description, DB2 server, and then mode access.
Now there’s other types of things we might connect into our network, right? Rather than just specific physical interfaces. What about port-channels? So maybe we need to create a port-channel connection as well, so we’ll say port-channel, we’ll say, okay, we need a port-channel number so 32. In this case that poor-channel, we might want to give it a description as well, so description we’ll call this one a data server. And then in this case, maybe this one’s a trunk port because it’s got lots of different networks that are attached off of this single data server that’s there. Maybe it’s a hypervisor host, just something that needs to be a trunk. Now a port-channel needs to have interfaces, member interfaces that go out there as well. So we’ll say, well this port-channel is interface, we’ll say nine and then interface 1/11.
So we can see the point of this phase is really just kind of feel like what would we want the experience of consuming this service, to kind of give us a model, a framework that we’re going to use to build our data model. And we’ve got our first network in there, but we’ve got to remember in our tenant we also want to be able to support other ones. So maybe we will just indicate here in our pseudocode that we want management stuff and then this one will be VLAN 89 and it would need a different network, 10, one, 46, zero, 204. And then this one would also have some connections. I can’t type today. Connections switch. I’m going to say this one’s management switch.
So here we can see we call that a difference in our data model. A period connections switch pairs, so this would be a pair of switches that have kind of redundant links for everything connected to them. Down here we want to also potentially support just basic independent single switches, so we’ve got to switch with management switch, and then this would have another interface. Maybe this one’s kind of a catalyst style switch or an iOS style switch. So it’s got different interface ideas that go through, and we’ll give this one a description as well of we’ll say leaf one, will be maybe it’s the management port for this leaf, and mode access. All right.
So again, this phase is all just about kind of freedom of expression. What are we trying to accomplish? So I’ve designed a basic kind of, what I’m after for this. And this gives me a starting point for my service. I always start with the end state or at least a goal for an end state. Now what do we do with this kind of pseudocode or the pseudo experience that we have? Well now we’re going to go and actually create our NSO package, our baseline in which we’re going to use these pieces that are there. Now, as I mentioned, Network Service Based Automation, there’s lots of different ways you could do it. What we’re using in dividend sandbox, and what this example is showing is using Cisco NSO, which is kind of a very powerful tool for this type of a piece.
Now one of the things that’s nice about Cisco NSO is it provides us a lot of like helpful characteristics and helpful scripts to kind of speed along the development process. So I’m going to open up my terminal, and now I’m going to go through and say, okay, I’m going to create a new package for our VLAN tenant service. And so NSO gives me a nice, convenient NCS make package command. And then we’re going to say we want it to be a service skeleton. Basically give me a starting point, a skeleton for a Python and template. And then we’re going to call it our VLAN tenant. So we’ll go ahead and run this. And what it actually creates is a directory called VLAN tenant. And then inside of that directory, has everything necessary to construct the basics of our service and it gives us starting points go through.
Now if we go and we actually look at some of these pieces and what’s there, so I’ll expand this out inside of a browser window over here, it makes it a bit easier to see. So we’ve got a couple of directories. We’ve got our Python directory, source directory, templates directory and test if we are going to build some tests for it. Now to build our service we’re going to tackle each one of these, the source, the Python and the templates. We’re going to start out with the source directory. And what’s inside the source is YANG. This is where model driven programmability and this is our first kind of touch is network automation engineers. What we’re going to build and work with YANG, not just to consume it, but to construct our own. Because that’s how we turn that pseudocode into an actual CLI and API experience that goes through, is by taking that basic functional model that we just mocked up, and we create a YANG model that kind of represents what we’re seeing in that case that’s there.
And so when we use the NCS make package, it gave us a starting point that we can work with. So let’s go ahead and open up this starting VLAN tenant YANG file. So here we have it here and we can see that everything that’s shown on the screen right now is automatically created by that NCS make package command for me. It gives me a starting point, and we can see it’s a YANG file. Now, if you’ve worked with NETCONF and RESTCONF and YANG before, maybe you’ve heard me talk about how YANG’s not something that a typical network engineer’s going to write themselves, which is true. But when we start to move from network engineer and to network automation developer, now we’re building these experiences that other engineers might use, and so we’re going to start to manipulate and write some of our own YANG. But don’t let that scare you, it’s really not that complicated. I was shocked by how easy it was to kind of convert these pseudocode pieces into a YANG model. So let me show you how that works.
So inside of our service skeleton, we can go ahead and start to customize this as what we’re after. And you can see there’s some pieces that are in here. So we’ve got a description that starts out with blah, blah, blah. So we’ll give it our go ahead and we’ll say this is our super cool VLAN tenant service, and we can see the revision date that’s there. We’ll set this to actually today’s date and will say 2019 10:07. And then here we’ll say the initial revision and you know there will be more revisions. All right, now we get down into the actual model itself, so we can see, okay, I’ve got my list of VLAN tenant. What we’re using is we’re going to try to replicate what we built from our pseudocode, I’m going to flip over here again, right? So we had VLAN tenant and we’re going to have a list because potentially we’d have lots of VLAN tenants that are there.
So our model starts out with list VLAN and tenant, that’s super handy. Let’s go ahead and continue kind of down this to mock up what our actual experience would be, and I’ll flip back and forth occasionally as we see it. We’ll start out, you can see that it fills in some basic descriptions and so I’m going to say, okay, this is to describe a new VLAN based tenant for the network. Now every list inside of there needs a way to uniquely identify, that’s what a key is. And so we can see our VLAN tenant is going to be keyed off of name. Again, that’s the default the skeleton built for us, but I agree with that. The VLAN tenant, they should be keyed off of by a name. And then we’re going to change here instead of a unique service ID we’ll say this is going to be the name of the tenant. And a string is an appropriate type there.
Now we get down and we can see below here there’s some pieces. So the service point, this is actually how it links us back into the Python code that is going to be executed when this service is created. We’ll see more on that in a minute, but we’ll just leave that where it is. And then this part down here, these bits, these are kind of just placeholders, examples that the skeleton gave us of different things your service might need. Note it expects, maybe you’re going to want to be able to talk to a list of devices. You want to apply this service to a set of devices so it gives us a template for a device, and then we can see there’s a template for just an IPv4 address. I’m just going to kind of put some carriage returns in there and keep those there so I can always refer back to them as examples. But we’ll start to build what are parts of our services are actually going to be.
Now the first thing our service needs if we remember, we’ll flip back here again, is fabric production. We need to say what fabric is this service going to be connected to. And so we’ll say, okay, we’re going to create a new leaf. Remember a leaf in YANG is just a property, so leaf fabric, and then everything inside these curly braces is going to describe the things about this leaf. Now here, our fabric is we want to refer back to a fabric that’s already existing inside of our system. So the tenant sits on top of a fabric. And so the type of leaf that this is is what’s called a leafref or leaf reference. It’s a reference to some other leaf in the system, it’s a way to kind of connect between different parts of our YANG models.
So I’ll go ahead and say, okay, that’s a type leafref. And now I need to say what type of or what reference are we going to connect into? And so in this case we’re going to refer back to a VLAN fabric element in the service that’s there. Now to do that, we’re going to say path equals, and then we just give it the path to the VLAN fabrics. And so we’ll say VLAN fabric: VLAN fabric. All right, now a couple of things on this. This VLAN fabric: VLAN fabric. So this is where it’s actually pulling in to another YANG model that’s out there. Now to refer to that, we have to import that model in. If you’ve done work with Python before, you’ve imported libraries to use them. We’re going to do a similar thing here.
And so I’m going to scroll back up to the top, we can see that we already had some imports that were based in for us. We imported the IETF-inet-types, so we can use things like IPv4 addresses and prefixes. We can see there’s some Tail-f ones that come in from that kind of NSO basic fundamentals, and then there’s some NCS pieces. We’re going to put another one in here. We’re going to say import. And then we’re going to import the VLAN fabric. And we’re going to kind of prefix it as VLAN fabric. So when we refer to any leaf or model or list from the VLAN fabric module or YANG model, we’re going to kind of prefix it with that VLAN fabric. Which is why, when I did the leafref down here, I said VLAN fabric colon.
And so inside of that service there’s a list called VLAN fabric. And now what I really need to refer back to is the actual VLAN fabric name. So inside of there we’ll get VLAN fabric once more: Name. So the idea here is if we think about it, inside of the VLAN fabric model, there is a list that says VLAN fabric, ours says tenant. And then the key for that VLAN fabric is called Name. And then there’s a leaf called Name. And so in essence we’re referring back to that same type of a structure here, but to link back to our fabric. And that we just need to end with a semi-colon at the end of that. That’s one of the more complicated pieces that we have to see, but as you kind of work with your YANG models and see how they refer to each other, it’s not that bad. We’re just going to kind of refer back and connect these dots together.
And before we go further, I want to make a point. The video today is not intended to be kind of an all out end to end lesson on how to design your own services. It’s more to show the experience, what goes into kind of building these things that are there. I look for other tutorials, other videos and lessons out there and there’s tons of great stuff on DevNet for NSO development as it goes through. This is again just to give you a taste of what it’s like to build a Network Service Based Automation. All right, so we’ve referred to our fabric. Now let’s dive into the next piece, which is where we get into the meat of it, the actual networks that are there. And so you can see that again, we’re going to want to have a list of networks underneath of our tenant and that network is going to have a name, it’s going to have a VLAN ID, it’s going to have a prefix that goes through. So let’s tackle these first bits that are there.
All right, so we’re going to make another list, this list is inside a VLAN tenant. We’re going to call this one list will be network. And then this list is going to need a key. And so we’ll say, let me scroll up a little. We’ll say this list is good, it’s key for this list will also be, we’ll call it name, so it’ll be the name of the network. Now that key, we have to have a leaf that refers back to it, so leaf of name. And in this case the type of this will just be string, in the end of it it’s going to turn into our VLAN name when it’s actually programmed to the switches, so just a string will be good.
The next one is we need a leaf for VLAN ID. And this one is going to be a type not a string, but a UInt16. UInt stands for unsigned integer and then 16 is kind of how many bits that go through. So YANG defines these types of data types. There’s strings that we’ve seen, there’s Booleans for true false, and then there’s a series of integers and numbers that we can use. An unsigned integer, 16 bits long is anywhere from zero to 65000, definitely more integers than I could use for VLAN IDs, which kind of has a spectrum in the 4000 range. But a UInt eight only goes up to 255, so UInt 16 as the right data type to use for a VLAN ID. But I don’t want somebody to put it in kind of a VLAN ID of 16000 that wouldn’t be valid. And so YANG lets me go through and say, okay, well the appropriate range for this leaf is, we could potentially say one, but I don’t want anybody to pick VLAN one or two. We’ll force people to pick between starting with VLAN 10 and we’ll say, you know what? You can go up to VLAN 4000. That’s what we’re going to allow for this leaf that goes through.
So we’ve set that up. Excuse me. So we’ve got our name, we’ve got our VLAN ID, what else did we need? Yeah, that’s right, the network. And so now we’re going to do leaf network. In this case, the type is going to be Inet, IPv4 prefix. And as a reminder, Inet this is referring back to another YANG model. We imported that in, it was done for us with the skeleton. If I scroll back up here, you can see the prefix of all these helpful things from VS code. The prefix of Inet refers to the IETF-inet-types, which is a series of just fundamental types that come from the IETF RFC for YANG. There’s several different ones, handy ones that are in there.
So we’re going to use the Inet IPv4 prefix in this case. So that’s where this is coming from. All right, so we’ve got our network in place. The next piece we need to do is to kind of define out what our connections are, so the connections that are going to go through. And so we’ll show what some of these look like as it goes in. So to do a connections, let me go back real quick. So remember when we talked about our connections, we’ve got two different types of connections we might go after. We’ve got connections that are switch pair, so a pair of matched up switches in kind of a primary secondary type of a setup. Or we might have a connection that’s just a single switch that’s there. And so this connections, I need to be able to contain two different types of lists. Well, what I can do is create a container called connections. And now inside of here I can create my lists. So the first one we’ll do is we’ll say list switch, we’ll do the simpler one first. List switch.
So it’s a list. Remember every list needs to have a way to uniquely identify an element, so we’ll say key of ID and then leaf ID. I’m in the wrong one. I got ahead of myself. The key is going to be named, I’m looking at my cheat sheet and looked too far down. So the key for our switch is going to be name. And then the leaf is going to be name. Now. In this case, we actually have switches that are part of NSO that we can refer back to, so similar to like we used a leafref with the fabric to refer to one. We’re going to use a leafref to refer to our device. So we’ll do type leafref, and then the path in this case is going to be, we’ll say, okay, we’re going to go to NCS. So the root NSO, we’ll say devices, NCS device, NCS name.
Now the NCS colon is just indicating which of the YANG models we’re referring to. In this case it’s the base NCS. And then it’s devices device name, that’s how we kind of read through that model that’s there. Throw a semi-colon at the end. Now on this connection of a switch we’re going to have a list of interfaces that are connected to this tenant. So we’ll do list interface. I spelled it wrong there. List interface. Here’s where that key ID, so our interface ID will be our key in this case. And then the leaf ID. In this case, we’ll just say it’s a type string, and so this is where that whole like one slash one or one zero one that’s the interface ID that’s going to go through on there.
Now after that we might want to give our leaf our interface description, so we can do at leaf description. In this case it’ll be type string. And then the last bit, remember what we had here was this mode, access versus trunk. And so we only have two types of modes we want to support and so we’ll do our leaf mode, and then the type we’re going to use here is a type that’s built in the YANG called enumeration. Enumeration is basically choices. I want to provide a series of choices and then that’s what the consumer can pick. And so one of our choices will be access and then another one will be trunk. Now I can set a default, maybe if I don’t want to make everybody specify it every time, I want to make it easier and we think that most of the time these connections are going to be access, so we’ll say. Default will be access.
So we would continue creating our YANG model like this to match up with what our interfaces or what our pseudocode for the interface was. I’m not going to go through it all, but you get the gist. Now a couple of things you might be thinking, Hank, this seems like really complicated, why do I have to go through all this effort? Maybe you’re comparing it to when you’re doing kind of automation with other tools, kind of basic Python and Jinja templates or maybe Ansible playbooks and YAML. Now the value behind taking the time to describe what your interface is in this YANG model, is that this is going to make sure that your network service the inputs are all correct.
For example, when somebody specifies the network address that’s here, it has to be an IPv4 prefix. And so this will actually make sure that the input is a valid prefix. If somebody puts in something like Bob. Bob is clearly not an IPv4 prefix. It would fail and the system would tell us that’s not a valid input and it wouldn’t try to program the network in appropriately. But what if they put something in that’s not as obviously wrong as Bob, maybe for their network, they go through and say, okay for this network is going to be a small sub net, maybe it’s a slash let’s say 29. And so they put an address in like 10.1.1.13/29. And you flip through that real quick you might say, okay, that looks fine, but that’s actually not a valid prefix. Dot 13/29 isn’t an actual network address. And so by specifying that this has to be an IPv4 prefix, the model will make sure that the inputs are all valid.
Other things like our VLAN IDs, we were able to put in our range to specify what we actually wanted in our leaf references. So this is one of those areas where Network Service Based Automation is definitely a step above kind of those entry level network automation. What you like to call kind of the first round of network automation, the basic creating VLANs and templates and little pieces that are there. Network Service Based Automation is when your goal for your automation routines are a bit more complicated, there’s more involved than just creating a single VLAN or a single interface. There’s lots of things we have to accomplish. And so taking the time to build a proper data scheme or upfront and data model, make sure that the automation works much better because we’re proving, we’re trusting, we’re testing things upfront as it goes through.
So this is definitely not something that I would recommend or expect anybody to do as kind of their first entry into network automation. But as network automation becomes more sophisticated, this is the direction we head into. So enough of that, we’ve gone ahead, we’ve specked out our YANG model that goes through. Our next piece for this is to actually say, okay, well what do we need to construct? What is the final state? And the final state that we have to actually build is network configurations, on network devices that are there. And so we need to construct templates, configuration templates that we’re going to use. And to create those templates there’s lots of ways we can do it. The way I always go through is when I’m designing a new network service, the first thing I do is I go configure the end state by hand, the old way. CLI or maybe another API, but basically go touch the devices and configure exactly what I’m after.
So in this case, what we’re after is creating a layer two and layer three VLAN element. So I think VLANs and SVIs and all of the requisite configuration necessary for our templates that are there. So what I’ve done is I’ve gone ahead and created a sample VLAN and an SVI that mimics our standard for what we’re after that we can use as the basis for our templates. So let’s look at those. So I’m going to jump into NCS, NSO. And so we’re going to look at the running configuration for the sample VLAN that’s there on one of my switches. So show running config, devices device, leaf 01-1. And then we’re going to say, show me the configuration and I want to see the NX: VLAN 13, 13.
So it rolled over here, but again, this is just an NSO command here, show running config, devices device leaf 01-1 config NX: VLAN 13, 13. And so here we can see this is the basic configuration for a VLAN on a Nexus device. The NX colon is because this is a Nexus device. If this was an iOS device, it’d be iOS colon, an XR device would be iOS XR colon and so on and so forth. So this is the configuration that’s there. Now, the templates that we’re going to use for our network services are not CLI kind of clear text templates, there’s a bunch of reasons why those are not optimal for a network automation. The biggest one is validation, making sure that things are accurate, and exactly what we’re after. An NSO because it’s kind of fundamentally based in model driven programmability and mostly NETCOMF. XML is the best template format to use. And the more I work with network automation, the more I’ve come to love XML, believe it or not.
And so what we’re going to do here is, I want to see that same running configuration but display it to me in XML. So here I’ve gotten an XML, and we can see the same configuration. So I’ve got a config block devices, device, leaf 101, and then we can see the configuration, we can see there’s a VLAN list with an ID of 13, 13. There’s a name that’s in there. So this shows me what the configuration for a VLAN looks like on a Nexus switch. And I want to take this and turn this into my template. So I’m going to go ahead and copy everything between the config blocks. So this is going to be our starting point, so I’ve copied that off. Now where I put this is remember back in our service skeleton we had that templates directory. I’ll expand that out and see that I’ve got my VLAN tenant template that goes through. I open that file up, we can see that it gives me a nice skeleton.
Now the top levels here are config template and you can see config template, and then we’ve got devices between it. What I’m going to do is I’m going to actually replace everything between the devices with what I just copied out of NSO. And so now I can say, okay, here’s my template for a new VLAN. I’ve got devices, device and then the name is here, and then I’ve got the VLAN ID is here, and then the VLAN name is here. What I need to do is I need to take this and just try to put variables into those spaces that I need to adjust. And so underneath here I’m going to say, okay, I’m going to put a new variable in here. The way we indicate variables inside of NSO is with curly braces and then dollar sign, and we’ll say this is going to the device name. For the VLAN list our ID is going to have a variable of dollar sign, VLAN ID and then here are going to say dollar sign VLAN name.
So what have we done? We took our base template that we got right out of NSO and again, the way we created it was just manually configuring this new VLAN with CLI configurations. I copied the XML version of that into my starting point for my template and then I just stuck some variables in here to go through. Now the source, the data for these variables are going to come from the instances of our model. So we’re going to say things like, remember our connections switch, leaf leaf 101 or leaf 01. So that leaf 01 becomes this device name. And then VLAN ID 13, 13 that VLAN ID value would go in here. And then the network of whatever we called it, that becomes our VLAN name and it sits in.
So the fact that it was XML, that was all generated for me. All I needed to do was go through that and figure out where I wanted to replace individual variables for the data that’s in there. And we do the same thing with the SVI pieces. And so if we look at the running config for an SVI. So I’m back over here to NSO and so we’ll say, okay, instead of NX VLAN, we’ll say interface VLAN 13, 13. So this is what my configuration, this is how we configure our basic interfaces in sandbox, no shutdown. There’s some VRF stuff. We’ve got our IP address that’s in here, OSPF is turned on. We’ve got [inaudible 00:31:23] is configured with the bits that are in there.
So that’s our config. I can go ahead and run that again, display XML. And so this gives me the actual XML that I would use to create this. And then I could just replace things like the IP address with kind of the calculated IP addresses that we need. So this is how we create our templates. So we’ve seen our YANG model, we’ve now seen how we could create the templates. The next piece is actually combining the two together, and this is where Python comes in. So what I’m going to show you is some of the real service code that we’re using for our services inside of DevNet sandbox. But before we look at the final code, let me show you what the service skeleton gives us. And we’re back at the start, what I ran was, make package, NCS make package, Python and template and then we gave it a name.
The Python piece creates the service skeleton for the Python base code for our service just like it created the skeleton code for our YANG as well as our template. And so this is the configuration or the initial code that’s created. What’s really nice about this is it’s again just a place to fill in the blanks for what we’re going to update. So down here we can see class, service callbacks. The idea here is every time a new service is created, every time a new instance of our VLAN tenant is created, this service create code is going to run. Now there’s a lot of comments inside here that are handy, so as you kind of go through your development you know it’s through there. But the only bit that’s really kind of interesting and necessary is right here in this service create piece from lines 13 down to 20. And so if we look at it, what is the code going to do? Well, it’s going to log something. So it’s going to log out to an actual Python log that you can monitor when you’re doing your development to any point, to see what’s going on in your code.
It then creates a variables object that can be used to send variables into those templates that we had. And so we can see it creates an instance of NCS template variables. It then shows how you add a value for a variable. So you have VARs.add dummy, and then it’s just putting in the local host IP address. We then say, okay, I need to create a template object so that I can actually apply configuration templates. And then we use that to apply a template called VLAN-tenant-template. So this is that XML template we were just looking at. And then we pass in the variables that we’re after.
Now with that little bit of code, now all we have to do is actually put our own logic again, pull out our values for our service from our definition, from that YANG model. So things like the network prefix, someone’s going to configure that, we pull that into our Python code and then we can use that to pass it in. Same thing with VLAN IDs and names. So let’s look at a chunk of the actual Python code behind the real VLAN tenant service we use in sandbox. So the piece I want to look at is the bit of code that actually processes through to all of those networks. Remember, every mainland tenant can have any number of networks and that network is going to have a name, VLAN name. It’s going to have a VLAN ID, it’s going to have a network which is the prefix or the IP space that’s attached to it. And then it’s going to have some number of connections that are there.
And so this is the code that takes that information and starts to inject that into the templates that we just looked at. And so inside of here we can see that I’ve got, I’m going to loop over the network. So for network in service.network service.network, our service is VLAN tenant, dot network is going to be the networks that are underneath that tenant. So we’re going to loop through them one at a time and repeat this bit of code. I’m doing a self.log, basically putting it out there so as I’m monitoring the execution of the Python code, I can see where I am at any given point. I then create a variables object, to that I’m going to use to pass all the variables in, and then we can see that I’ve got my VLAN ID, I’ve got my VLAN name.
Where do the values come from? Well, they come from that network service.VLAN ID. Remember our network had a leaf called VLAN ID, with NCS in building our Python code here, it’s very easy to get access to all those leaf values. It’s just using properties inside of our Python objects. So network.VLAN ID refers back to the VLAN ID that was inputted by the user when they created a new instance of the VLAN tenant. Similarly, network.name is going to be that network name that can be used as our VLAN name. If I scroll down, we can see that we’re actually going to go through and say, okay, for pair in switch pairs. We will go ahead and apply VLAN new, using the detail that was there to the specific device that came out. So the Python code behind here, again, not that complicated. We’re taking data out using just basic object notation, network.VLAN ID, network.name. We’re then using that and adding them to variables that’ll be used inside of our template. And then we go ahead and we apply it.
Now our Python code, we just process through our model is one bit at a time applying to whatever number of templates we need to achieve the goal that we’re after. And that’s how we actually make the magic of network service automation. Now obviously there’s a lot more that you can go into, there’s some interesting logic and processing that can go through. There’s different types of data types that you can use in YANG, there’s constraints. But the fundamentals of network service automation development is what we see in here. Now to end the video today, let’s actually go back and rerun and create a new instance of a tenant using that model or using this VLAN tenant service. Now that we’ve seen how the pieces go together.
All right, I’m back in NSO, let’s go ahead and jump into config mode, and we’re going to go ahead and configure our new tenant based on our pseudo code. So VLAN tenant, NSO part two. We’ll say that this one’s going to be on a fabric. And if I hit tab, we can see that that leafref actually gives me the ability to tap completion and NSO shows me what are valid inputs based on what I’ve got so far. So I’m going to say my fabric will be production. Next I can go through and start to create my networks. So network app servers one, and then we’ll say this one’s going to have VLAN ID of 88. The prefix will be network 10, one, 45, zero/24.
Next we jump into the connections. What’s actually going to be connected here? And we’ll say connections switch pair, leaf. And you can see if I tab it fills in and then I can tab it again and say, okay, well, which pair? Leaf 01, leaf 02. We’ll say leaf 01. And then I can say, what are the actual connections that are in here? And we’ll say interface 1/78. I’m trying to pick one that I know isn’t in use. 1/78. I’ll say description, DB server. You’ve got to put it in quotes. And then we’ll say this one’s a mode. Actually, if I just hit question and you can see access and trunker in there, so I can go ahead and say access, and then we’ll do interface 1/79, and we’ll say this one will be description DB two server and so on.
So we would go ahead and put all of the bits that are in there, and then I’m just going to exit back to the actual top level of tenant. And so if I go through and say, okay, well what do we actually push? Or what have I configured? So show config, here’s the configuration we’ve entered. So I didn’t do the full pseudo code but enough of it that we can see VLAN tenant, NSO, all these pieces and again, that’s driven by that YANG model that we assembled. Now I want to turn this into final actual network configuration code. And that’s what the template does. Remember we brought our templates so it takes this service input, an uses those templates to generate actual final network device pieces, and then it uses the Python to kind of bring all those things together.
Now I can see those final device configurations by doing a commit dry run, and then I can say out format native. Natives has showed me the actual Native configuration for the devices that’s going to be pushed. If I run that, it processes through all of the templates and all of the service pieces that are there and then this is what’s the configuration is going to be pushed out based on those templates. And so what do we have? So admin V switch, this is just a layer two switch inside the fabric. Remember I didn’t refer to it but because I linked back to a fabric called production, every switch in that fabric, every switch in my data center fabric will get this VLAN added to it. So VLAN 88 with the appropriate name, and then we can see device FIO2. I didn’t even mention this as we went through. I mentioned inside of our manuscripts of a fabric, but my fabric is more than just Cisco network switches. Our UCS environment is part of our network as well.
So we can see to add this new network into that fabric means that I have to go into that fabric interconnect and update the VLANs and the VNIC templates appropriately. And so what we can see in here is underneath org management VNIC template called ESXI trunk A. So the A side of my ESXI host, that adapter is going to go ahead and have app servers. Apparently I misspelled it when I typed it, but app servers one is going to be added as a VLAN that’s there. And then if I scroll down, we actually see down here underneath ethernet uplinks, the VLAN app servers one misspelled with VLAN ID of 88 gets added. So this shows that network service is more than just kind of what we might traditionally have thought of our network fabric. This is actually extending out into UCS. And this would also extend out into my VMware environment and in the final production piece, but I’m just running this in a demo environment where I don’t have V center connected.
Then we get down into leaf 01-1. Now leaf 01-1 is what we call our border, it’s where all the SVIs, it’s where the layer three bits happen. And so what we can see in here, we get our VLAN is added as we would expect, the VRF for NSO part two. So every tenant will get a VRF created. So the VRF context is set up. And then interface VLAN 88 is configured and then it’s automatically configured. Now what I told the service was the prefix that I wanted to use, and then my template has a standard. We have a standard inside of our environment that says, okay, the first address inside of a network will be used for HSRP. The second address will be put on the primary switch. The third address will be put on the secondary switch, which is how this HSRP address as well as the actual interface addresses were automatically calculated based on that information.
And then down here we can see where interface ethernet 1/78 and ethernet 1/79 are configured as they were described inside of the connections block for our service with the standard bits that are there, including even jumbo frames, which is something we need, didn’t have to refer to that at all, that was part of the actual service configurations.
Now if I scroll through, we can see leaf 102 is configured as well, as well as the rest of the leafs inside of the fabric are all configured with the information that’s there. All right, this video went way longer than I expected, but what I hope was if you stuck with me is you got a chance to see kind of that network service automation development process, we have the way that we can see, okay, we start out again with our pseudocode. What are we trying to accomplish? From there, we go ahead and we actually turn our pseudocode into an API. We worked a lot with a CLI based API but that same YANG model is automatically converted and exposes a RESTCONF or a rest based API for this service as well.
Same YANG model, no extra work, we automatically get that rest API. So we had our pseudocode, we had our YANG model and then we went ahead and we grab what are the actual final configs that we needed using the XML conversion that NSO gave us, show me my running config displayed as XML and then that was the basis for our templates and we just put in our variables where needed. And then finally we took a look at the Python code that combines the service information that’s given, and then turns that information into the variables that’s needed for the templates to create it and then we saw it in action.
All right. If you enjoyed this please let me know in the comments on the video over on the blog or just reach out to me out on Twitter or LinkedIn. Network automation is this area that I think every engineer is excited about, and what we’re starting to see is organizations move from kind of that introductory that kind of kicking the tires on automation with lab functionality and maybe basic little atomic actions like create this VLAN or do this other piece. And the need to move to more robust types of automation where we consider all of the elements of the data center and what it means to deliver a service that’s there.
And I really believe this model of kind of Network Service Based Automation, where it’s not atomic feature base but it’s actual service based. What are we trying to accomplish? Is when we’ll start to see the true power of network automation for us. And again, Cisco NSO is not the only tool where you could use to do this style of automation strategy, but I think it’s a great one to go through, and I love the fact that it’s designed kind of where a network engineer’s workflow in mind. A lot of the skills that we have factor directly into it. All right. That’s enough for now. I’ll talk to you guys next time. Thanks.
We’d love to hear what you think. Ask a question or leave a comment below.
And stay connected with Cisco DevNet on social!
Visit the new Developer Video Channel