Deploy Router Using Classic ZTP

Manually deploying network devices in a large-scale environment requires skilled workers and is time consuming.

With Zero Touch Provisioning (ZTP), you can seamlessly provision thousands of network devices accurately within minutes and without any manual intervention. This can be easily defined using a configuration file or script using shell or phyton. Currently, ZTP only supports single name-server. When the DHCP server has more than one server address configured, ZTP fails to apply the server configuration.

ZTP provides multiple options, such as:

  • Automatically apply specific configuration in a large-scale environment.

  • Download and install specific IOS XR image.

  • Install specific application package or third party applications automatically.

  • Deploy containers without manual intervention.

  • Upgrade or downgrade software versions effortlessly on thousands of network devices at a time

Benefits of Using ZTP

ZTP helps you manage large-scale service providers infrastructures effortlessly. Following are the added benefits of using ZTP:

  • ZTP helps you to remotely provision a router anywhere in the network. Thus eliminates the need to send an expert to deploy network devices and reduces IT cost.

  • Automated provisioning using ZTP can remove delay and increase accuracy and thus is cost-effective and provides better customer experience.

    By automating repeated tasks, ZTP allows network administrators to concentrate on more important stuff.

  • ZTP process helps you to quickly restore service. Rather than troubleshooting an issue by hand, you can reset a system to well-known working status.

Use Cases

The following are some of the useful use cases for ZTP:

  • Using ZTP to install Chef

  • Using ZTP to integrate IOS-XR with NSO

  • Using ZTP to install Puppet

You can initiate ZTP in one of the following ways:

  • Fresh Boot: Use this method for devices that has no pre-loaded configuration. See Getting Started with ZTP on a Fresh Boot of a Router.

  • Manual Invocation: Use this method when you want to forcefully initiate ZTP on a fully configured device. To know the detailed steps of manual invocation of ZTP, see Manual Invocation of ZTP.

  • ZTP Bootscript: Use this method when you want to hard code a script to be executed on every boot.

Follow the workflow to understand the tasks involved in provisioning the router using classic ZTP.

Figure 1. Classic ZTP Workflow
Workflow to provision router using classic ZTP

This section contains the following topics:

Deploy Router Using Classic ZTP

Manually deploying network devices in a large-scale environment requires skilled workers and is time consuming.

With Zero Touch Provisioning (ZTP), you can seamlessly provision thousands of network devices accurately within minutes and without any manual intervention. This can be easily defined using a configuration file or script using shell or phyton. Currently, ZTP only supports single name-server. When the DHCP server has more than one server address configured, ZTP fails to apply the server configuration.

ZTP provides multiple options, such as:

  • Automatically apply specific configuration in a large-scale environment.

  • Download and install specific IOS XR image.

  • Install specific application package or third party applications automatically.

  • Deploy containers without manual intervention.

  • Upgrade or downgrade software versions effortlessly on thousands of network devices at a time

Benefits of Using ZTP

ZTP helps you manage large-scale service providers infrastructures effortlessly. Following are the added benefits of using ZTP:

  • ZTP helps you to remotely provision a router anywhere in the network. Thus eliminates the need to send an expert to deploy network devices and reduces IT cost.

  • Automated provisioning using ZTP can remove delay and increase accuracy and thus is cost-effective and provides better customer experience.

    By automating repeated tasks, ZTP allows network administrators to concentrate on more important stuff.

  • ZTP process helps you to quickly restore service. Rather than troubleshooting an issue by hand, you can reset a system to well-known working status.

Use Cases

The following are some of the useful use cases for ZTP:

  • Using ZTP to install Chef

  • Using ZTP to integrate IOS-XR with NSO

  • Using ZTP to install Puppet

You can initiate ZTP in one of the following ways:

  • Fresh Boot: Use this method for devices that has no pre-loaded configuration. See Getting Started with ZTP on a Fresh Boot of a Router.

  • Manual Invocation: Use this method when you want to forcefully initiate ZTP on a fully configured device. To know the detailed steps of manual invocation of ZTP, see Manual Invocation of ZTP.

  • ZTP Bootscript: Use this method when you want to hard code a script to be executed on every boot.

Follow the workflow to understand the tasks involved in provisioning the router using classic ZTP.

Figure 2. Classic ZTP Workflow
Workflow to provision router using classic ZTP

This section contains the following topics:

Build Configuration File

Based on the business need, you can use a configuration or script file to initiate the ZTP process.


Attention


When you use a USB flash drive as a source for ZTP, you cannot use the script file for provisioning. The script file is not supported in the USB fetcher. Fetcher defines which port the ZTP process should use to get the provisioning details as defined in the ztp.ini file.


The configuration file content starts with !! IOS XR and the script file content starts with #! /bin/bash, #! /bin/sh or #!/usr/bin/python.

Once you create the configuration file, apply it to the device using the ztp_helper function xrapply.


Note


We recommend that you don’t execute the APIs on a router that is already provisioned. ZTP Utility APIs are designed to be executed from the ZTP script when you boot the router for the first time. The APIs perform additional operations to run the requested actions during the boot process and bring changes in the existing configuration before executing any action.

ZTP utility APIs have prerequisites which are executed in the ZTP workflow before running the ZTP utility APIs. These prerequisites help with running specific actions during the boot process and in making necessary configuration changes.

We recommend that you don’t use ZTP utilities outside the scope of ZTP script. The APIs in this script use username as ztp or ztp-user in every action. The ZTP utility executed outside the scope of the ZTP script may fail as it’s not executed from the ZTP workflow. This may modify the configurations on the device and affect other related operations. If the ZTP utility is executed outside the scope ZTP script, the logs display that the script is executed using username ztp or ztp-user, misleading that the script is executed from the workflow.


The following is the sample configuration file:

!! IOS XR
username root
group root-lr
password 0 lablab
!
 
hostname ios
alias exec al show alarms brief system active
 
interface HundredGigE 0/0/0/24
ipv4 address 10.10.10.55 255.255.255.0
no shutdown
!

You can also use a script file to initiate the ZTP process. This script or binary is executed in the IOS XR bash shell and can be used to interact with IOS XR CLI to configure, verify the configured state and even run EXEC commands based on the workflow that you choose. Build your ZTP script with either shell and python. ZTP includes a set of CLI commands and a set of shell utilities that can be used within the user script. ZTP includes a set of shell utilities that can be sourced within the user script. The ztp_helper.sh is a shell script that can be sourced by the user script. This script provides simple utilities to access XR functionalities. For information on helper APIs, see the Github repository.

The following shows the sample script in python.

[apple2:~]$ python sample_ztp_script.py
###### Debugs enabled ######

###### Change context to user specified VRF ######

###### Using Child class method, setting the root user ######
2016-12-17 04:23:24,091 - DebugZTPLogger - DEBUG - Config File content to be applied !
                username netops
                group root-lr
                group cisco-support
                secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1
                !
                end
2016-12-17 04:23:28,546 - DebugZTPLogger - DEBUG - Received exec command request: "show
configuration commit changes last 1"
2016-12-17 04:23:28,546 - DebugZTPLogger - DEBUG - Response to any expected prompt ""
Building configuration...
2016-12-17 04:23:29,329 - DebugZTPLogger - DEBUG - Exec command output is ['!! IOS XR
Configuration version = 6.2.1.21I', 'username netops', 'group root-lr', 'group cisco-support',
   'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1', '!', 'end']
2016-12-17 04:23:29,330 - DebugZTPLogger - DEBUG - Config apply through file successful,
last change = ['!! IOS XR Configuration version = 6.2.1.21I', 'username netops', 'group
root-lr', 'group cisco-support', 'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1', '!', 'end']

###### Debugs Disabled ######

###### Executing a show command ######
Building configuration...
{'output': ['!! IOS XR Configuration version = 6.2.1.21I',
        '!! Last configuration change at Sat Dec 17 04:23:25 2016 by UNKNOWN',
        '!',
        'hostname customer2',
        'username root',
        'group root-lr',
        'group cisco-support',
        'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1',
        '!',
        'username noc',
        'group root-lr',
        'group cisco-support',
        'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1',
        '!',
        'username netops',
        'group root-lr',
        'group cisco-support',
        'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1',
        '!',
        'username netops2',
        'group root-lr',
        'group cisco-support',
        'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1',
        '!',
        'username netops3',
        'group root-lr',
        'group cisco-support',
        'secret 5 $1$7kTu$zjrgqbgW08vEXsYzUycXw1',
        '!',
        'cdp',
        'service cli interactive disable',
        'interface MgmtEth0/RP0/CPU0/0',
        'ipv4 address 11.11.11.59 255.255.255.0',
        '!',
        'interface TenGigE0/0/0/0/24',
        'shutdown',
        '!',
        'interface TenGigE0/0/0/0/25',
        'shutdown',
        '!',
        'router static',
        'address-family ipv4 unicast',
        '0.0.0.0/0 11.11.11.2',
        '!',
        '!',
        'end'],
        'status': 'success'}

###### Apply valid configuration using a file ######
Building configuration...
{'status': 'success', 'output': ['!! IOS XR Configuration version = 6.2.1.21I', 'hostname
customer', 'cdp', 'end']}

###### Apply valid configuration using a string ######
Building configuration...
{'output': ['!! IOS XR Configuration version = 6.2.1.21I',
        'hostname customer2',
        'end'],
'status': 'success'}

###### Apply invalid configuration using a string ######
{'output': ['!! SYNTAX/AUTHORIZATION ERRORS: This configuration failed due to',
        '!! one or more of the following reasons:',
        '!! - the entered commands do not exist,',
        '!! - the entered commands have errors in their syntax,',
        '!! - the software packages containing the commands are not active,',

The XML-encoded YANG configuration that follows shows various network settings including:

  • Basic setup, including line configuration (TTY, VTY)

  • User setup such as System Utilities

  • Network configurations such as, domain service, Management IP address assignment, NETCONF, IP routing

  • Protocol configurations such as, SSH, LLDP, gRPC

  • Security (AAA)

  • Interface settings (Interface (IF) manager)

Router# python ztp_XML_test.py
# netconf_client_ztp_lib - version 1.2 #
2021-02-22 13:53:11,587 - DebugZTPLogger - DEBUG - netconf init attempt: 1
Building configuration...
2021-02-22 13:53:18,117 - DebugZTPLogger - DEBUG - Netconf yang agent is up
###################### Netconf response: Current running configuration #######################
<?xml version="1.0"?>
<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <data>
  <netconf xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-man-xml-ttyagent-cfg>
   /* Enables NETCONF agent over TTY*/
   <agent>
    <tty>
     <enable></enable>
    </tty>
   </agent>
  </netconf>
<lldp xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-ethernet-lldp-cfg>
 /*Enables and configures global LLDP subcommands*/
  <enable>true</enable>
</lldp>  
 <ip-domain xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-ip-domain-cfg>
  /*Configures domain service related commands*/
  <vrfs>
   <vrf>
    <vrf-name>default</vrf-name>
    <name>cisco.lab</name>
    <servers>
     <server>
      <order>0</order>
      <server-address>5.38.4.246</server-address>
     </server>
    </servers>
   </vrf>
  </vrfs>
</ip-domain>
<interface-configurations xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg>
 /*Configures Interfaces and controls their activation and deactivation*/
  <interface-configuration>
   <active>act</active>
   <interface-name>HundredGigE0/0/0/14</interface-name>
   <shutdown></shutdown>
  </interface-configuration>
  <interface-configuration>
   <active>act</active>
   <interface-name>MgmtEth0/RP0/CPU0/0</interface-name>
   <ipv4-network xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-ipv4-io-cfg>
    /*Configures IPv4 Interface input and output settings on the device*/
    <addresses>
     <primary>
      <address>5.38.9.29</address>
      <netmask>255.255.0.0</netmask>
     </primary>
    </addresses>
   </ipv4-network>
  </interface-configuration>
  <interface-configuration>
   <active>act</active>
   <interface-name>FourHundredGigE0/0/0/0</interface-name>
   <shutdown></shutdown>
  </interface-configuration>
</interface-configurations>
<netconf-yang xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-man-netconf-cfg>
 /*Configures Network Configuration Protocol (NETCONF) commands*/
  <agent>
   <ssh>
    <enable></enable>
   </ssh>
  </agent>
</netconf-yang>
<tty xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-tty-server-cfg>
  <tty-lines>
   <tty-line>
    <name>default</name>
    <exec>
     <timeout>
      <minutes>0</minutes>
      <seconds>0</seconds>
     </timeout>
    </exec>
    <general>
     <absolute-timeout>0</absolute-timeout>
    </general>
   </tty-line>
  </tty-lines>
</tty>
<host-names xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg>
 /*Configures various system utilities related to the shell environment 
of the system such as Hostname, Time zone, Prompt, Environmental variable configurations.*/
  <host-name>SF-1</host-name>
</host-names>
<grpc xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-man-ems-cfg>
  <port>57400</port>
  <no-tls></no-tls>
  <enable></enable>
</grpc>
<aaa xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-aaa-lib-cfg>
 /*Configures AAA (Authentication, Authorization, and Accounting) settings on the device*/
  <usernames xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-aaa-locald-cfg>
   <username>
    <ordering-index>0</ordering-index>
    <name>cafyauto</name>
    <usergroup-under-usernames>
     <usergroup-under-username>
      <name>root-lr</name>
     </usergroup-under-username>
     <usergroup-under-username>
      <name>cisco-support</name>
     </usergroup-under-username>
    </usergroup-under-usernames>
    <secret>
     <type>type10</type>
     <secret10>$6$iY.Zo/7E7RIG5o/.$PH1YegMZiHsiRDTxKOjKQ0i8rd4n
s2vHMHEmQrsMQrrtNTlj/gcBEQRXj3WDR8bAv0rWzz3aGdElteshHYXXR1</secret10>
    </secret>
   </username>
  </usernames>
  <accountings>
   <accounting>
    <type>commands</type>
    <listname>default</listname>
    <type-xr>start-stop</type-xr>
    <method1>local</method1>
   </accounting>
  </accountings>
</aaa>
<ssh xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-crypto-ssh-cfg>
 /*Configures the Secure Shell (SSH) settings on a device such as Encryption, Authentication, Session Management*/  
  <server>
   <timeout>120</timeout>
   <rate-limit>600</rate-limit>
   <session-limit>110</session-limit>
   <v2></v2>
   <vrf-table>
    <vrf>
     <vrf-name>default</vrf-name>
     <enable></enable>
    </vrf>
   </vrf-table>
   <netconf>830</netconf>
   <netconf-vrf-table>
    <vrf>
     <vrf-name>default</vrf-name>
     <enable></enable>
    </vrf>
   </netconf-vrf-table>
  </server>
</ssh>
<router-static xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-ip-static-cfg>
/*Configures static IP routing on network devices*/ 
  <default-vrf>
   <address-family>
    <vrfipv4>
     <vrf-unicast>
      <vrf-prefixes>
       <vrf-prefix>
        <prefix>0.0.0.0</prefix>
        <prefix-length>0</prefix-length>
        <vrf-route>
         <vrf-next-hop-table>
          <vrf-next-hop-next-hop-address>
           <next-hop-address>5.38.0.1</next-hop-address>
          </vrf-next-hop-next-hop-address>
         </vrf-next-hop-table>
        </vrf-route>
       </vrf-prefix>
      </vrf-prefixes>
     </vrf-unicast>
    </vrfipv4>
   </address-family>
  </default-vrf>
</router-static>
<vty xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-tty-vty-cfg>
/*Configures virtual terminal lines (VTY lines) to access a device through SSH or TTY protocols remotely.*/ 
  <vty-pools>
   <vty-pool>
    <pool-name>cafyauto</pool-name>
    <first-vty>5</first-vty>
    <last-vty>99</last-vty>
    <line-template>cafyauto</line-template>
   </vty-pool>
  </vty-pools>
</vty>
<netconf-yang xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-netconf-yang-cfg>
/*Configures the Network Configuration Protocol (NETCONF) settings and Yet Another Next Generation (YANG) data modelling.*/ 
  <agent>
   <ssh/>
  </agent>
</netconf-yang>
<vty-pool xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-vty-pool-cfg>
 /*Configures virtual terminal (VTY) lines on large number of network devices*/
  <pools>
   <pool>
    <pool-name>cafyauto</pool-name>
    <first-vty-number>5</first-vty-number>
    <last-vty-number>99</last-vty-number>
    <line-template>cafyauto</line-template>
   </pool>
  </pools>
</vty-pool>
<interfaces xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-interface-cfg>
 /*Configures Interface settings such as interface, security, and performance on a device*/ 
  <interface>
   <interface-name>HundredGigE0/0/0/14</interface-name>
   <shutdown/>
  </interface>
  <interface>
   <interface-name>MgmtEth0/RP0/CPU0/0</interface-name>
   <ipv4>
    <addresses xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-if-ip-address-cfg>
     /*Configures IP address settings on network interfaces of a device.*/
     <address>
      <address>5.38.9.29</address>
      <netmask>255.255.0.0</netmask>
     </address>
    </addresses>
   </ipv4>
  </interface>
</interfaces>
<lldp xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-lldp-cfg/>
/*Configures the Link Layer Discovery Protocol (LLDP) settings on a network device.*/
<domain xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-domain-cfg>
 /*Configures domain settings on the device*/
  <name>cisco.lab</name>
  <name-servers>
   <name-server>
    <order>0</order>
    <address>5.38.4.246</address>
   </name-server>
  </name-servers>
</domain>
<xr-xml xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-xml-agent-cfg>
/*Configures XML agent settings such as Data formatting, Network Management, and Secure transport layers on the router.*/
  <agent>
   <ssl/> 
   <tty/>
   <enable/>
  </agent>
</xr-xml>
<netconf xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-xml-agent-cfg>
  <agent>
   <tty/>
  </agent>
</netconf>
<router xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-router-static-cfg>
 /*Configures the static routing settings on network devices*/
  <static>
   <address-family>
    <ipv4>
     <unicast>
      <prefixes>
       <prefix>
        <prefix-address>0.0.0.0</prefix-address>
        <prefix-length>0</prefix-length>
        <nexthop-addresses>
         <nexthop-address>
          <address>5.38.0.1</address>
         </nexthop-address>
        </nexthop-addresses>
       </prefix>
      </prefixes>
     </unicast>
    </ipv4>
   </address-family>
  </static>
</router>
<ssh xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-ssh-cfg>
 /*Configures the Secure Shell (SSH) settings such as secure remote access, 
Encryption, and security on a network device.*/
  <timeout>120</timeout>
  <server>
   <rate-limit>600</rate-limit>
   <session-limit>110</session-limit>
   <v2/>
   <vrfs>
    <vrf>
     <vrf-name>default</vrf-name>
    </vrf>
   </vrfs>
   <netconf>
    <port>830</port>
    <vrfs>
     <vrf>
      <vrf-name>default</vrf-name>
     </vrf>
    </vrfs>
   </netconf>
  </server>
</ssh>
<grpc xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-grpc-cfg>
  /*Configures the gRPC (Google Remote Procedure Call) on a network device*/
  <port>57400</port>
  <no-tls></no-tls>
</grpc>
<hostname xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-hostname-cfg>
 /*Configures the hostname on a network device*/
  <system-network-name>SF-1</system-network-name>
</hostname>
<aaa xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-aaa-cfg>
  <usernames xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-aaa-task-user-cfg>
   /*Configures the AAA (Authentication, Authorization, and Accounting) parameters on a network device*/
   <username>
    <ordering-index>0</ordering-index>
    <name>cafyauto</name>
    <group>
     <root-lr/>
     <cisco-support/>
    </group>
    <secret>
     <ten>$6$iY.Zo/7E7RIG5o/.$PH1YegMZiHsiRDTxKOjKQ0i8rd4ns2vHMHEmQrsMQrrtNTlj
/gcBEQRXj3WDR8bAv0rWzz3aGdElteshHYXXR1</ten>
    </secret>
   </username>
  </usernames>
  <accounting>
   <commands>
    <accounting-list>
     <list-name>default</list-name>
     <start-stop/>
     <local/>
    </accounting-list>
   </commands>
  </accounting>
 </aaa>
 <line xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-line-cfg>
   <default>
    <exec-timeout xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-line-exec-timeout-cfg>
     /*Configures the exec timeout settings on network devices for the amount of time that the software waits for user to input after the last key has been pressed */
     <timeout-in-minutes>0</timeout-in-minutes>
     <timeout-in-seconds>0</timeout-in-seconds>
    </exec-timeout>
    <absolute-timeout xmlns=http://cisco.com/ns/yang/Cisco-IOS-XR-um-line-general-cfg>0</absolute-timeout>
    /*Configures line settings on network devices*/   
   </default>
 </line>
 </data>
</rpc-reply>

Authenticate Data Ports

On fresh boot, ZTP process is initiated from management ports and may switch to data ports. To validate the connection with DHCP server, authentication is performed on data ports through DHCP option 43 for IPv4 and option 17 for IPv6. These DHCP options are defined in option space and are included within dhcpd.conf and dhcpd6.conf configuration files. You must provide following parameters for authentication while defining option space:

  • Authentication code—The authentication code is either 0 or 1; where 0 indicates that authentication is not required, and 1 indicates that MD5 checksum is required.


    Note


    If the option 43 for IPv4, and option 17 for IPv6 is disabled, the authentication fails.


  • Client identifier—The client identifier must be 'exr-config' .

  • MD5 checksum—This is chassis serial number. It can be obtained using echo -n $SERIALNUMBER | md5sum | awk '{print $1}' .

Here is the sample dhcpd.conf configuration. In the example below, the option space called VendorInfo is defined with three parameters for authentication:
class "vendor-classes" {
   match option vendor-class-identifier;
}

option space VendorInfo;
option VendorInfo.clientId code 1 = string;
option VendorInfo.authCode code 2 = unsigned integer 8;
option VendorInfo.md5sum code 3 = string
option vendor-specific code 43 = encapsulate VendorInfo;
subnet 10.65.2.0 netmask 255.255.255.0 {
  option subnet-mask 255.255.255.0;
  option routers 10.65.2.1;
  range 10.65.2.1 10.65.2.200;
}
host cisco-mgmt {
   hardware ethernet 00:50:60:45:67:01;
   fixed-address 10.65.2.39;
   vendor-option-space VendorInfo;
   option VendorInfo.clientId "exr-config" ;
   option VendorInfo.authCode 1;
   option VendorInfo.md5sum "aedf5c457c36390c664f5942ac1ae3829";
   option bootfile-name "http://10.65.2.1:8800/admin-cmd.sh";
}

Here is the sample dhcpd6.conf configuration file. In the example below, the option space called VendorInfo is defined that has code width 2 and length width 2 (as per dhcp standard for IPv6) with three parameters for authentication:


log-facility local7;
option dhcp6.name-servers 2001:1451:c632:1::1;
option dhcp6.domain-search "cisco.com";
dhcpv6-lease-file-name "/var/lib/dhcpd/dhcpd6.leases";
option dhcp6.info-refresh-time 21600;
option dhcp6.bootfile-url code 59 = string;
option dhcp6.user-class code 15 = string;
option space CISCO-EXR-CONFIG code width 2 length width 2;
option CISCO-EXR-CONFIG.client-identifier code 1 = string;
option CISCO-EXR-CONFIG.authCode code 2 = integer 8;
option CISCO-EXR-CONFIG.md5sum code 3 = string;
option vsio.CISCO-EXR-CONFIG code 9 = encapsulate CISCO-EXR-CONFIG;
subnet6 2001:1451:c632:1::/64{
 range6 2001:1451:c632:1::2 2001:1451:c632:1::9;        
 option CISCO-EXR-CONFIG.client-identifier "exr-config";
 option CISCO-EXR-CONFIG.authCode 1;
 #valid md5
 option CISCO-EXR-CONFIG.md5sum "90fd845ac82c77f834d57a034658d0f0";
 if option dhcp6.user-class = 00:04:69:50:58:45 {
  option dhcp6.bootfile-url "http://[2001:1851:c632:1::1]/cisco-2/image.iso";
 }
 else {
   #option dhcp6.bootfile-url "http://[2001:1851:c632:1::1]/cisco-2/cisco-mini-x.iso.sh";
   option dhcp6.bootfile-url "http://[2001:1851:c632:1::1]/cisco-2/ztp.cfg";
  }
}

Setup DHCP Server

For ZTP to operate a valid IPv4 or IPv6 address is required and the DHCP server must send a pointer to the configuration script.

The DHCP request from the router has the following DHCP options to identify itself:

  • Option 60: “vendor-class-identifier” : Used to Identify the following four elements:

    • The type of client: For example, PXEClient

    • The architecture of The system (Arch): For example: 00009 Identify an EFI system using a x86-64 CPU

    • The Universal Network Driver Interface (UNDI):

      For example 003010 (first 3 octets identify the major version and last 3 octets identify the minor version)

    • The Product Identifier (PID):

  • Option 61: “dhcp-client-identifier” : Used to identify the Serial Number of the device.

  • Option 66 : Used to request the TFTP server name.

  • Option 67: Used request the TFTP filename.

  • Option 97: “uuid” : Used to identify the Universally Unique Identifier a 128-bit value (not usable at this time)

Example

The following DHCP request sample provides a fixed IP address and a configuration file with the mac address of the management interface.

host cisco-rp0 {
   hardware ethernet e4:c7:22:be:10:ba;
   fixed-address 172.30.12.54;
   filename "http://172.30.0.22/configs/cisco-1.config";
}

The following DHCP request sample provides a fixed IP address and a configuration file with the mac address of the management interface along with capability to re-image the system using iPXE (exr-config option):

host cisco-rp0 {
   hardware ethernet e4:c7:22:be:10:ba;
   fixed-address 172.30.12.54;
   if exists user-class and option user-class = "iPXE" {
      filename = "http://172.30.0.22/boot.ipxe";
   } elsif exists user-class and option user-class = "exr-config"  {
      filename = "http://172.30.0.22/scripts/cisco-rp0_ztp.sh";
   }
}

DHCP server identifies the device and responds with either an IOS-XR configuration file or a ZTP script as the filename option.

The DHCP server responds with the following DHCP options:

  • DHCPv4 using BOOTP filename to supply script/config location.

  • DHCPv4 using Option 67 (bootfile-name) to supply script/config location.

  • DHCPv6 using Option 59 (OPT_BOOTFILE_URL) to supply script/config location

The following sample shows the DHCP response with bootfile-name (option 67):

option space cisco-vendor-id-vendor-class code width 1 length width 1;
option vendor-class.cisco-vendor-id-vendor-class code 9 = {string};

######### Network 11.11.11.0/24 ################
shared-network 11-11-11-0 {

####### Pools ##############
  subnet 11.11.11.0 netmask 255.255.255.0 {
    option subnet-mask 255.255.255.0;
	option broadcast-address 11.11.11.255;
	option routers 11.11.11.2;
	option domain-name-servers 11.11.11.2;
	option domain-name "cisco.local";
	# DDNS statements
  	ddns-domainname "cisco.local.";
	# use this domain name to update A RR (forward map)
  	ddns-rev-domainname "in-addr.arpa.";
  	# use this domain name to update PTR RR (reverse map)

    }

######## Matching Classes ##########

  class "cisco" {
       match if (substring(option dhcp-client-identifier,0,11) = "FGE194714QS");
  }


  pool {
      allow members of "cisco";
      range 11.11.11.47 11.11.11.50;
      next-server 11.11.11.2;

      if exists user-class and option user-class = "iPXE" {
         filename="http://11.11.11.2:9090/cisco-mini-x-6.2.25.10I.iso";
      }

  
      if exists user-class and option user-class = "exr-config"  
       {
          if (substring(option vendor-class.cisco-vendor-id-vendor-class,19,99)="cisco")
          {           
            option bootfile-name "http://11.11.11.2:9090/scripts/exhaustive_ztp_script.py";
          }
        }
      

      ddns-hostname "cisco-local";
      option routers 11.11.11.2;
  }
}

Customize ZTP Initialization File

You can customize the following ZTP configurable options in the ztp.ini file:

  • ZTP: You can enable or disable ZTP at boot using CLI or by editing the ztp.ini file.

  • Retry: Set the ZTP DHCP retry mechanism: The available values are infinite and once.

  • Fetcher Priority: Fetcher defines which port ZTP should use to get the provisioning details. By default, each port has a fetcher priority defined in the ztp.ini file. You can modify the default priority of the fetcher. Allowed range is from 0 to 9.


    Note


    Lower the number higher the priority. The value 0 has the highest priority and 9 has the lowest priority.


    In the following example, the Mgmt4 port has the highest priority:

    
    [Fetcher Priority]
    Mgmt4: 0
    Mgmt6: 1
    DPort4: 2
    DPort6: 3
    
  • progress_bar: Enable progress bar on the console. By default, the progress bar is disabled. To enable the progress bar, add the following entry in the ztp.ini file.

    [Options]
    progress_bar: True

By default, the ztp.ini file is located in the /pkg/etc/ location. To modify the ZTP configurable options, make a copy of the file in the /disk0:/ztp/ directory and then edit the ztp.ini file.

To reset to the default options, delete the ztp.ini file in the /disk0:/ztp/ directory.


Note


Do not edit or delete the ztp.ini file in the /pkg/etc/ location to avoid issues during installation.


The following example shows the sample of the ztp.ini file:

[Startup]
start: True
retry_forever: True

[Fetcher Priority]
Mgmt4:  1 
Mgmt6:  2 
DPort4: 3 
DPort6: 4 

Enable ZTP Using CLI

If you want to enable ZTP using CLI, use the ztp enable command.

Configuration example

Router#ztp enable
Fri Jul 12 16:09:02.154 UTC
Enable ZTP? [confirm] [y/n] :y
ZTP Enabled.

Disable ZTP Using CLI

If you want to disable ZTP using CLI, use the ztp disable command.

Configuration example

Router#ztp disable
Fri Jul 12 16:07:18.491 UTC
Disable ZTP? [confirm] [y/n] :y
ZTP Disabled.
Run ZTP enable to run ZTP again.

Provision ZTP

When you boot the device, the ZTP process initiates automatically if the device does not have a prior configuration. During the process, the router receives the details of the configuration file from the DHCP server. The ZTP process initiates when you boot the network-device with an IOS-XR image. The process starts only on the device that doesn't have a prior configuration. Here is the high-level work flow of the ZTP process for the Fresh boot:

  1. ZTP sends DHCP request to fetch the ZTP configuration file or user script. To help the Bootstrap server uniquely identify the device, ZTP sends below DHCP option

    • DHCP(v4/v6) client-id=Serial Number

    • DHCPv4 option 124: Vendor, Platform, Serial-Number

    • DHCPv6 option 16: Vendor, Platform, Serial-Number

    The following is the default sequential flow of the ZTP process:
    • ZTP sends IPv4 DHCP request first on all the management port. In case there is a failure, then ZTP sends IPv6 DHCP request on all the management port.

    • ZTP sends IPv4 DHCP request first on all the data port. In case there is a failure, then ZTP sends IPv6 DHCP request on all the data port.

      The default sequential flow is defined in configuration file and you can modify the sequence using the configuration file.
  2. DHCP server identifies the device and responds with DHCP response using one of the following options: DHCP server should be configured to respond with the DHCP options.

    • DHCPv4 using BOOTP filename to supply script/config location

    • DHCPv4 using Option 67 (bootfile-name) to supply script/config location

    • DHCPv6 using Option 59 (OPT_BOOTFILE_URL) to supply script/config location

  3. The network device downloads the file from the web server using the URI location that is provided in the DHCP response.

  4. The device receives a configuration file or script file from the HTTP server.


    Note


    • If the downloaded file content starts with !! IOS XR it is considered as a configuration file.

    • If the downloaded file content starts with #! /bin/bash, #! /bin/sh or #!/usr/bin/python it is considered as a script file.


  5. The device applies the configuration file or executes the script or binary in the default bash shell.

  6. The Network device is now up and running.

Manual Invocation of ZTP

Procedure


Step 1

Use the ztp clean command to remove previous state information from ZTP.

Example:

Router#ztp clean 
         This would remove all ZTP temporary files.
         Would you like to proceed? [no]: yes 
         All ZTP operation files have been removed.
         ZTP logs are present in /var/log/ztp*.log for logrotate.
         Please remove manually if needed.
         If you now wish ZTP to run again from boot, do 'configure terminal/commit replace' followed by reload

Step 2

Use the commit replace command to replace the entire running configuration.

Example:

Router#configure terinal
Router(configure)#commit replace
execute "commit replace from configuration mode"

Note

 
  • ZTP triggers only if there’s no configuration/username.

  • The execution of ZTP can be affected by an existing configuration on interface such as DHCP or ACL.

  • If the ZTP work flow involves image upgrade, the presence of configuration makes ZTP to exit after reload.

  • Existing configuration can cause issue to image upgrade.

  • If the existing configuration isn’t compatible with the new image upgraded you’ll see failures after reimage.

Step 3

Do one of the following steps.

  • Use the reload command to initiate the ZTP process automatically during system boot on active RP.

    Router#reload
  • Use the ztp initiate command to initiate ZTP manually.

    Router#ztp initiate 
    Initiating ZTP may change your configuration.
    Interfaces might be brought up if they are in shutdown state
    Would you like to proceed? [no]: yes
    ZTP will now run in the background.

    If all conditions are met ZTP continues with fetch, otherwise exits. The ztp initiate command manually initiates ZTP for testing, bypassing all ZTP checks that is followed in the reload method. You shouldn’t execute ztp initiate on up and running testbed, this command modifies the existing configuration on the router. If the execution of ztp initiate fails, make sure of provisioning the device manually.

    If you initiate ZTP, using the ztp initate command, the ZTP workflow bypasses the exit checks. ZTP will continue running in the background indefinitely. ZTP will exit only if the workflow has completed with a SUCCESS or if it is stopped manually. Ensure to stop ZTP using the ztp terminate command after initiating it, if ZTP is active/running on the device.