The CSR1000v is a great option for a virtual router, especially with SDWAN and especially as a customer endpoint within a service provider network. Automating the deployment of the CSR VM is a pretty simple thing to do with something like Ansible, but this can leave us with an unconfigured router forcing us to do some basic configuration through the hypervisor console to get basic ssh reachability. Let’s take a look at automating the SDWAN CSR1000v configuration without ever logging in.
When deploying a CSR1000v for SDWAN (or regular IOS XE for that matter) Cisco gives a few options for configuring a few basic elements during the deployment of the OVA. Sometimes these basic options can be enough, however we can take this further by adding our own custom configuration properties. One way we can do this is by deconstructing the OVA file, modifying some if its contents, and then putting it all back together. In this post I will be going over how to modify the SDWAN CSR1000v OVA to help with configuration automation. I am hoping to get the basic idea across to everyone, however having a basic understand of VMWare vCenter and XML document structure may help.
Extracting the Contents of the OVA
The first thing we need to do is extract the contents of the OVA. Think of the OVA as a zip file with multiple files inside that ultimatley instruct VMWare how to build the virtual machine. To do this, you can simply extract the files like you would any regular tar file. In macOS or Linux, the command is usually this:
tar -xzf csr1000v-ucmk184.108.40.206.ova
An easy way to remember the flags for this command is to think “Xtract Ze File!”. Once complete you will see a few files, see below.
Modifying the OVF
The first thing we want to do is modiy the OVF file, in this case “csr1000v-ucmk220.127.116.11.ovf”. This file contains several instructions for creating the VM, however we are focusing on the part that injects router configuration into the CSR. When deploying and OVA on VMware, you have probably noticed toward the end of the process it will give a sort of form asking for things like “Router Name”, “Management IP”, “Username” etc. This OVF file is where those come from. There are several built in parameters that Cisco has put in by default which you can take a look at to get an idea of how to build your own parameters. Something to note however, I have not had luck using my own paramaters in addition to the built in paramaters. Meaning, if I use the built in “Router Name” parameter while also trying to use my own custom “DNS Server” paramater, I get mixed results where sometimes one or the other doesn’t actually work. If you are going to use custom paramaters, I recomend using ONLY custom parameters. That means that you will likley need to create some custom paramaters for ones that already exist. You should be able to open the OVF file in any text editor, it is just an XML document. See the below image as an example of the opened OVF:
The custom paramaters have a few required fields. ovf:key, ovf:type, ovf:userConfigurable, and ovf:value. While not required, I also recomend setting the ovf:Label value as well. See below for an example custom property:
<ovf:Property ovf:key="ios-config-0001" ovf:type="string" ovf:userConfigurable="true" ovf:value="interface GigabitEthernet1"> <ovf:Label>WAN1 Interface</ovf:Label> </ovf:Property> <ovf:Property ovf:key="ios-config-0002" ovf:type="string" ovf:userConfigurable="true" ovf:value="ip address 192.168.255.2 255.255.255.248"> <ovf:Label>WAN1 Interface IP</ovf:Label> </ovf:Property>
ovf:key must always be “ios-config-000x”. The number represents the order in which to execute commands. Think of this as you normally would when configuring an IOS device by hand. You don’t need to use “conf t” here, but to configure an IP address on an interface you must first issue the “interface GigabitEthernet1” command followed by the “ip address 192.168.255.2 255.255.255.248”.
ovf:type enforces the value’s type. This also be “string” in this case.
ovf:userConfigurable lets you set wether the user can configure this property when deploying the OVA, with the options being either true or false. If you choose false to disable the users ability to configure then you will need to set a value as I have above.
ovf:value this lets you set the value of the property, which is the CLI command you wish to run. You could set this to an empty string (ovf:value=””) if you don’t want to have a default value and want the user to configure their own value during OVA deployment
ovf:Label This is just a label for the property. This helps with describing what the property is. It is also what shows up during the OVA deplyoment as the label on the form when configuring the VM.
I recommend placing your new properties near the end of the ovf file, under the existing Cisco built ones. See below:
Now something odd we have to change is the ovf:instance key in the OVF. This property is most likely already set to 1, however we need to change it to ovf:instance=””, an empty string. When importing the OVA into vmware, I have noticed that it likes to append a “.1” to the end of every ovf:key. This makes the custom properties not work at all.
Preparing the OVA for Repackagaing
Since we have modified the contents of the OVF file, we need to recalculate the checksum and update the manifest file (in this case, csr1000v-ucmk18.104.22.168.mf). Take a look at the manifest file to double check the algorithm it is using, in my example it is using SHA256. Here is what you will see in the manifest file:
We need to recalculate the checksum on the ovf file, you may need to search for the proper command for your OS but here are a couple examples:
shasum -a 256 csr1000v-ucmk22.214.171.124.ovf
Either way, you should get an output similar to this:
Take this value and replace the old one in the manifest file for the OVF, and save it:
Finalizing the OVA
Now we just need to repackage all the files back into an OVA. To do this we can use a tool provided by vmware called OVFTOOL. They do require you to log in, however I was able to download it for free. You can find the OVFTOOL here.
Something to note, in macOS the .dmg installer did not add any pointers in PATH to the location of the executable. You could do this yourself, or just specify the path when running the commands. The executable was installed into
/Applications/ovf-tool/ on my mac. The Linux version of the installer allowed for the commands to be ran from anywhere.
To repackage the OVA you simply need to open a terminal, navigate to the directory in which you originally extracted the OVA and run this command:
ovftool --allowExtraConfig "csr1000v-ucmk126.96.36.199.ovf" "CUSTOM-csr1000v-ucmk188.8.131.52.ova"
The first file you specify is the modified ovf and the second file you specify is the name you wish to use for saving the OVA. Note that you may need to delete/move the original OVA, or choose a different name when running this command. The command will fail if there is a duplicate file name in the directory.
Now, when deploying the OVA in vCenter you will see your custom properties near the end of the Customize Template screen, under the Cisco Built in ones:
The final thing I would like to leave you with is the below sample of an Ansible playbook. Although we put default values in the ovf file, they can be overridden with different values when executing an Ansible playbook to deploy a CSR:
While there are certainly other ways to assist with automating CSR1000v configuration, I hope you have found this method interesting. If you enjoyed this, you may also be interested in my post on Deploying CSR1000v with Cisco SDWAN — check it out!