ACI Config Backup via Python

The configuration backup/rollback tool in ACI is a great feature that has saved my ass many times.

Any time I start making changes, I go do a one-time backup. If I get too far down a wrong path, I can easily rollback to that snapshot to set the fabric right again.

One thing that always bugged me though, was the inability to give that backup a customizable, user-friendly name.

I discovered this week that if we trigger that backup via the cobra SDK, we can assign any name we want. Here is the code, which is also available on my Github page.

#!/usr/bin/env python

# list of packages that should be imported for this code to work
import cobra.model.fabric
import cobra.model.pol
import cobra.model.config
import credentials
from cobra.internal.codec.xmlcodec import toXMLStr
import requests.packages.urllib3

def take_backup ():
#Login to APIC
ls ='https://'+credentials.ACI_login["ipaddr"], credentials.ACI_login["username"], credentials.ACI_login["password"])
md =

polUni = cobra.model.pol.Uni('')
fabricInst = cobra.model.fabric.Inst(polUni)

backup = cobra.model.config.ExportP(fabricInst, name="backup_created_with_python", snapshot="true", adminSt="triggered")

c =


Palo Alto and NSX Configuration

VMware NSX offers a distributed firewall that applies security policy across your virtual environment and allows for what VMware has coined “micro-segmentation.” Additionally, you can add Palo Alto virtual firewalls to gain further visibility and Next-Gen Firewall capabilities. I recently deployed this in a lab environment and at a customer site. Here is an overview of my experience and understanding.

The Palo Alto documentation for inserting the PAN virtual appliance into the NSX data plane is pretty good. It gives you the step-by-step on “how” to configure it. The thing I find lacking in Palo Alto documentation is the “why.”

For all the qualms I have with Cisco, much of their documentation does a good job explaining the theory behind a certain feature or technology. I find that understanding the why, makes the actual configuration step-by-step instructions more sensible.

That being said, I can expound on a few things in configuring PAN and NSX that is not explicitly mentioned, but came in handy for me understanding what we are doing.

First, the basic overview of service insertion for this scenario.

We are going to establish a connection between Panorama and NSX manager. We are going to tell NSX what traffic to send to the PAN device for inspection. We are going to set up policies in PAN to do that inspection.

To deploy PAN with NSX, you’ll need a license for every ESXi host that is going to have a virtual firewall. You will also need the Palo Alto centralized management console, which is called Panorama. Lastly, you will need a web server that can host the .ovf and .vmdk files that make up the PAN virtual appliance.

An overview of the setup:

We are going to tell NSX manager where it can download the .OVF file for the virtual appliance and where to pull the license file. We are also going to define an IP pool for the management IP of the virtual appliances.

Once all that information is populated, in vCenter networking and security we pick on which hosts we want the virtual appliance installed. Once those are installed correctly, those will show up in Panorama.

We then create security groups in NSX using either dynamic or static membership. We create a distributed firewall rule in NSX to define which traffic is redirected to the Palo Alto appliances.

In Panorama, we define security policies based on the security groups we created in NSX.

This is an important point, the Palo Alto only inspects the traffic you redirect. You can also create exceptions in NSX to specifically define traffic you don’t want redirected.  So you could have an any-any redirect rule, but then define a smaller subset of traffic to not redirect.

My thinking is that if there is traffic you know you would block anyway, it doesn’t make sense to redirect that to the PAN to block, just block it in the distributed firewall in NSX.

One other thing that I ran into during installation is the pre- and post-rules in Panorama. When creating your security policies you have the option for pre- and post-rules. What does that mean?

Panorama only manages the policies that it creates. When the PAN NSX virtual appliance is installed, there is a local policy installed that is a deny all. If you create a post-rule policy in Panorama, that policy will be placed after the local deny all rule, so all traffic will be denied. When creating policies for the NSX virtual PAN, you must create pre-rule policies that will be placed above the local rules.


It might be hard to see in the image, but there is a yellow line between the PAN-NSX policy and the default-deny policy. The PAN-NSX policy is the one created in Panorama as a pre-rule. The default-deny is the local policy.



APIC Failure Testing

I had an interesting conversation the other day about failure of the APICs within an ACI fabric. This particular customer had been burned by another vendor’s fabric solution with regards to failure or upgrade scenarios. I mentioned that the APICs could all blow up and the data plane of the fabric would keep chugging along. This customer said, “I want to see it. I want to pull the power to the controllers and see it.”

I realized that I had been saying this scenario was possible for a while now, but I had never explicitly tested it. I figured I had better ensure this behavior before I have my customer come out and pull the plug on my APICs.

Here is the setup. I have two EPGs on either side of an F5 LTM. This LTM is doing a simple round robin load balancing of some apache web servers. In my test, I am pinging the virtual server on the LTM. I also tested that I could get to the web pages served by the pool defined in the LTM.



I am advertising the bridge domain subnet ( associated with F5 Outside EPG via an L3 Out.

Starting a ping to all three controllers and the VS on the LTM appliance ( I can ping all four addresses. I can also access web pages from servers in the Web EPG that are load balanced by the LTM.

I logged into the CIMC of all three controllers and did a reboot. At this point I lost pings to all three controllers as expected. I did, however, keep my pings to the VS and I was still able to access web pages.


Now I have proof that the APIC failures do not affect data plane traffic. I can rest easy the next time a customer questions that statement.

Update yer APICs (To Live and Die in ACI)

A scenario I ran across last week that I anticipate coming up again: new ACI fabric install and the version of code on the switches is newer than the code on the APICs. In this case the APICs won’t recognize the leaf switches, so I can’t add them to the fabric.

All of the equipment was fresh out of the box, everything was cabled correctly. I did the initial setup on the APICs, but when I went to start adding members to the fabric, there was nothing. I consoled into the leaf switches, a pair of 93180YC-EX, to see what version of code they had. They are running 12.1, which would equal something in the 2.1 code train.

The APICs were running 1.0 code, well before the 93180s were introduced as a product. So it made sense that it wouldn’t recognize them. So how do we get them to talk?

I thought maybe I could downgrade the switches to a lower version. I copied code and moved it into the bootflash directory and tried to run the script to get them to boot into that older version of code. That did not work and I didn’t want to start changing too much with the boot order for fear of bricking a switch.

The second option is to upgrade the APICs, but I can’t upgrade them via the normal means because my fabric isn’t built meaning that my APICs haven’t formed a cluster as of yet.

The process to upgrade the APICs in a standalone fashion is actually pretty straightforward.

  • Assuming you’ve downloaded the APIC code (2.0(2g) in my case), access the server via CIMC.
  • Login to the CIMC and launch KVM console.
  • Once in there, click on activate virtual media and map the CD/DVD to the ISO file you’ve downloaded.
  • Next reboot the server and press F6 during the bootup process to manually select boot location. Choose your mapped virtual media.
  • Follow the on-screen prompts to install the new OS.

In my case it took about 30-45 minutes to load the new OS. Once the new image is installed it will bring you to the initial fabric startup screen again.

One warning is that you will need Java to launch the KVM console. That always brings it own joys.

I imagine this scenario will present itself more often as new switches are introduced into the nexus 9K line.

There is a Cisco reference document here.

UCS and ACI VLAN Creation (Secret San Jose)

To follow-up on the previous post about the UCS Python tool. Here is the script I wrote to create the VLAN pool within UCS and ACI.

The script takes an argument for a VLAN range (for example 100-199).

It takes that VLAN range and creates the VLAN pool in ACI. It also creates those VLANs in UCSM.

It them takes those VLANs and applies them to the vnic templates for the A fabric and B fabric of UCS. The template names would need to be modified to match your environment.

Updating ACI Python SDK

Leaving this here for future reference.

After the ACI fabric is upgraded, you must update the egg files in your acicobra SDK.

The egg files are available on your upgraded controller.



Download the egg files to wherever you store them on your system. Mine are in /home/bob/Cobra.

Once the files are downloaded, uninstall the current acicobra and reinstall the new version.

bob@UbuntuBob:~/Cobra$ pip uninstall acicobra

bob@UbuntuBob:~/Cobra$ sudo easy_install -Z ./acimodel-2.1_1h-py2.7.egg

bob@UbuntuBob:~/Cobra$ sudo easy_install -Z ./acicobra-2.1_1h-py2.7.egg



Cisco UCS Python Conversion

I am working on a project to automate VLAN pools used in ACI and UCS. When you are using a standard DVS (not AVS) with ACI, you define a pool of VLANs that the DVS will use when creating port groups. These port groups are created when you associate an EPG with a VMM domain.

In UCS, it is easy to create a VLAN pool with many members. On the LAN tab, under VLANs, you can specify a range of VLAN IDs. The sucky part comes when you want to add those VLAN IDs to a VNIC. This is the purpose of the script I want to build–to automate the addition of those VLAN IDs to the VNIC and add them to the ACI VLAN pool. The first step for me is figuring out how to add those VLANs to UCS via python.

There is an SDK named  UCSMSDK that you can install through pip. There is a function within this SDK that will take actions performed within UCSM and convert it to python code.

First I install the package.

sudo pip install ucsmsdk

I then run a simple script to log the UCSM actions. This script defines our login credentials, opens the GUI, then runs the convert to ucs python function.

from ucsmsdk.ucshandle import UcsHandle
from ucsmsdk.utils.ucsguilaunch import ucs_gui_launch
from ucsmsdk.utils.converttopython import convert_to_ucs_python
# login to UCS
handle = UcsHandle("", 'admin', 'ucspassword')
# launch the GUI
#launch the convert to ucs python function

The terminal screen will log any actions and spit out the equivalent python code.

In this case I added vlan 2001 and 2002 to a vnic named Env7-gst-A. It converted those GUI actions to a python script. I can then take this code and convert it into a useful script to create VLAN IDs in bulk.

from ucsmsdk.mometa.vnic.VnicLanConnTempl import VnicLanConnTempl
from ucsmsdk.mometa.vnic.VnicEtherIf import VnicEtherIf

mo = VnicLanConnTempl(parent_mo_or_dn="org-root", templ_type="updating-template", nw_ctrl_policy_name="CDP-Enable", descr="", stats_policy_name="default", admin_cdn_name="", switch_id="A", pin_to_group_name="", mtu="9000", policy_owner="local", qos_policy_name="", ident_pool_name="Mac-Pool-Fabric-A", cdn_source="vnic-name", name="Env7-gst-A")
mo_1 = VnicEtherIf(parent_mo_or_dn=mo, default_net="no", name="PYTHON2001")
mo_2 = VnicEtherIf(parent_mo_or_dn=mo, default_net="no", name="PYTHON2002")
handle.add_mo(mo, True)


Note: I use Ubuntu for most of my python work. I had to install Java to get this to work. This method will not work with the HTML5 GUI, only the Java version.

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer

These resources were used to research this process:

Installing Java in Ubuntu.

The UCSMSDK documentation.