Cisco Modeling Labs-Zero Touch Provisioning Lab Part 1
There are plenty of docs on ZTP with Cisco, but many of the guides I found referenced outdated or invalid links/ labs. The only up to date lab I could find required Cisco dCloud, which comes at a cost. I decided that I wanted to explore ZTP on CML and learned a few things along the way. This will be a several part guide that will first start with a general overview of the lab and then walking through the actions required to get an image that supports ZTP.
Lab Topology
Our lab will consist of five items. I’ll give a quick explanation of each item in this post and follow on posts will have detailed guides on configuring each lab item.

Lab Items
- CSR1000v-ztp: Will serve as our fresh router looking to pull a configuration (custom image created below)
- ZTP-Server: Will host our configuration (Ubuntu)
- L2-SW: Provides general connectivity (IOL-L2)
- WAN-RTR: Provides DHCP and NATs outbound traffic (IOL)
- WAN: Provides external access so our ZTP Server can pull necessary packages
ZTP Router Details
The first thing to know about our ZTP Router is that the default CML image WILL NOT work for our lab. Due to it being the original image, we are unable to edit the node to disable provisioning to allow for ZTP booting. We’ll have to create several items from scratch to disable provisioning. I’ll walk you through those steps below:
Step 1: Create a new Node Definition
Because stock Node and Image Definitions cannot be edited, we first need to create a new Node Definition where provisioning is disabled. There are several settings in this section and I chose to mostly copy what the original CSR Node Definition had. Below is a list of each of the settings I used with the important items bolded:
- ID: General name
- Description: General description
- Nature: router
- Image Definition: LEAVE BLANK FOR NOW
- Description (Markdown): General description
- Prefix: Any prefix you chose
- Icon: router
- Label: Any label you chose
- Linux Native Simulation: KVM
- Simulation Driver: csr1000v
- Disk Driver: VirtIO
- Memory: 3072
- CPUs: 1
- CPU Limit: 20
- CPU Model: Leave Blank
- Network Driver: VMXNet3
- Data Disk Size: Leave Blank
- Boot Disk Size: Leave Blank
- Video Model: No Video Adapter
- Video Memory: Leave Blank
- EFI Boot: Disabled
- Estimated Resource Usage: Leave Blank
- Interfaces: At least (1) but as you see fit
- Boot Timeout: 250
- pyATS: Disabled
- Property Inheritance: All enabled
- Per-node: All enabled
- Configuration Generator: Leave Blank
- Enable Provisioning: DISABLED
Step 2: Get an image
There’s a couple options here. You could download the image from Cisco’s Software Download page, however if you don’t have access, you can also pull the image from your own CML server. It may seem strange to download an image from CML only to upload it back, it doesn’t seem like you can directly reference “stock images” from CML. The easiest way I’ve found to pull an image from CML, is to use the admin cockpit page and scp the file to your local machine. CML hosts its images in the /var/lib/libvirt/images/virl-base-images directory. Below is a photo of me making the transfer to my machine’s Downloads/ios/ directory:

Step 3: Upload the Image
Once the image is transferred, we’ll have to create a “new image definition” in CML. You can reach this page by clicking “Tools” in the upper right corner and then selecting “Node and Image Definitions”.

Next, select Image Definitions and click Manage. This takes you to the page where you can upload the image you transferred earlier.

Select the image and then click on Upload Image. CML will show a progress bar and then show the image under Uploaded Images once the upload is complete.

Step 4: Create an Image Definition
Go back to the Node and Image Definition page and select Add to create a new Image Definition. Go ahead and give a general ID, Label, and Description. Then select the image you just uploaded and select the Node Definition you just created.

You can leave the remaining settings blank. Click “Create Definition” at the bottom of the page.
Step 5: Validate your new node
Go back to the CML dashboard and create a new lab. When you add a new node, you should see the node that you just created. Here is a photo of my lab showing the new node:

Add that node to the lab (along with the original CSR if you’d like to compare) and turn the node on. You should now see the ZTP Node Definition not find a startup-config and attempt autoinstall options. I’ve highlighted the “stock CSR image” in red and our new image image in green for a comparison.

Conclusion
We now have new Node Definition that will attempt to pull an install file. In upcoming posts, I’ll go over configuration of the ZTP Server, required DHCP settings, and show ZTP in action. Thanks for reading.