Zero Touch Provisioning

Zero Touch Provisioning (ZTP) is a feature that

  • streamlines the onboarding of routers by automatically applying configuration artifacts during the boot-up process, and
  • eliminates the need for manual intervention.

The artifacts involved include

  • Software Images: Predefined software versions or updates necessary for router operation.
  • Configuration Files: Specific settings and parameters that tailor the router's functionality.
  • Custom Scripts: Automated scripts to execute additional configuration tasks or customizations.

These artifacts enable the SONiC router to have the appropriate software configuration options, allowing for a seamless and efficient deployment.

ZTP operation

Zero Touch Provisioning on SONiC uses the Dynamic Host Configuration Protocol (DHCP) to discover onboarding configuration. This list describes different stages of ZTP on SONiC:

  1. SONiC router boots up
  2. The router checks if a ztp.json is present on the router (packaged during the SONiC image build process). If it exists, the router proceeds to step 10.
  3. The SONiC router broadcasts a DHCP Discover packet with option 77 (User Class Information) set to SONiC-ZTP.
  4. A DHCP server receives the packet. The server is configured to check if option 77 (User Class Information) is set.
  5. If option 77 is set to SONiC-ZTP, the server responds with a DHCP Offer. In the response, Option 67 (Bootfilename) is set to a URL for a ztp.json file. This file is hosted provisioning server and contains onboarding configuration information for the router.
  6. The router receives the DHCP Offer. It sends a DHCP Request to the DHCP server to indicate that it is using the parameters set in the DHCP Offer.
  7. The DHCP Server acknowledges this request by sending a DHCP ACK.
  8. The router now sends a request to the provisioning server to get the ztp.json file by accessing the URL specified in the Option 67 of the DHCP Offer.
  9. The provisioning server responds with the ztp.json file.
  10. The router processes the ztp.json file and learns the sources for configuration artifacts.
  11. The router sends requests to the artifact server(s) to get the configuration artifacts.
  12. Upon receiving configuration artifacts, the router processes them and applies them (For e.g., configuration reload, script execution, image upgrade)

The following sections cover router and server configuration options for Zero Touch Provisioning.

DHCP Server Configuration

The DHCP server needs to be configured to respond to the router's DHCP Discover packet. It needs to check if the Discover packet has Option 77 (User Class Information) set to SONiC ZTP and respond with the location of the ztp.json file.

In our example, we will use the ISC DHCP server on a server running Ubuntu Linux. (https://ubuntu.com/server/docs/how-to-install-and-configure-isc-dhcp-server) Here is a sample /etc/dhcp/dhcpd.conf file that would re-direct the router to a provisioning server serving the ztp.json file at http://192.168.0.1/ztp-sonic/ztp.json.

subnet 192.168.0.0 netmask 255.255.0.0 {
  range 192.168.44.100 192.168.44.250;
  option routers 192.168.0.1;

  host sonic-ZTP-router{
   hardware ethernet aa:aa:aa:aa:aa:aa;
   fixed-address 192.168.1.2;
   if exists user-class and option user-class = "SONiC-ZTP"{
    option bootfile-name = "http://192.168.0.1/ztp-sonic/ztp.json";
  }
 }
}

Users can also put additional filters in the /etc/dhcp/dhcpd.conf file by matching the router serial number before sending the bootfile name (URL for ztp.json). For example:

subnet 192.168.0.0 netmask 255.255.0.0 {
  range 192.168.44.100 192.168.44.250;
  option routers 192.168.0.1;

  host sonic-ZTP-router{
   hardware ethernet aa:aa:aa:aa:aa:aa;
   fixed-address 192.168.1.2;
   if exists user-class and option user-class = "SONiC-ZTP"{
    if  exists dhcp-client-identifier and dhcp-client-identifier = "SONiC##8101-32FH-O##FLM272702CD" {
     option bootfile-name = "http://192.168.0.1/ztp-sonic/ztp.json";
   }
  }
 }
}

In the example above the dhcp-client-identifier (Option 77) is used to check for the router's serial number. SONiC routers supporting ZTP will set this option to SONiC##<HwSKU>##<Serial Number> in their DHCP Discover packet. The HwSKU and Serial Number can be found using the show platform summary command on a router running SONiC. For example:

admin@sonic:~$ show platform summary
Platform: x86_64-8101_32fh_o-r0
HwSKU: Cisco-8101-32FH-O
ASIC: cisco-8000
ASIC Count: 1
Serial Number: xxxxxx
Model Number: 8101-32FH-O
Hardware Revision: 1.0

ztp.json definition

SONiC uses a ztp.json file to define sources for configuration artifacts and how to use them. The file is consists of sections where each section corresponds to a set of user-defined configuration actions. Here is an example of a ztp.json file

{
    "ztp":{
        "001-configdb-json":{
            "url":{
                "source":"http://192.168.0.1/ztp-sonic/config_db.json",
                "destination":"/etc/sonic/config_db.json",
                "secure":false
            }
        },
        "002-provisioning-script": {
            "plugin": {
                "url": "http://192.168.0.1/ztp-sonic/provisioning-script.sh",
                "shell": "true"
            },
            "reboot-on-success": false
       }

    }
}

In the example above, within the ztp json object, 001-configdb-json and 002-provisioning-script are two objects that correspond to configuration actions on SONiC (replace config_db.json and run a provisioning script).

Within a configuration action object, a user defines the steps to succesfully execute a configuration action. In our example above:

  • The 001-configdb-json object specifies the location of a new config_db.json file to be copied to the router. It uses the default plugin called configdb-json (discussed later) to apply the contents of the new config_db.json file using a config reload

  • The 002-provisioning-script object provides the location of a provisioning script to be copied to the router using a custom plugin. It executes the copied script using a default shell.

Configuration Action Objects and SONiC ZTP plugins

The configuration action objects make use of either default plugins or custom plugins. Plugins are used to define what SONiC ZTP does with configuration artifacts as well as provide paths to configuration artifacts themselves.

The default plugins supported by SONiC ZTP are (for detailled information: https://github.com/sonic-net/SONiC/blob/master/doc/ztp/ztp.md):

configdb-json: The configdb-json plugin is used to download ConfigDB JSON file and apply the configuration. A config reload is performed during which various SWSS services may restart. For example:

{
  "ztp":{
      "001-configdb-json":{
          "url":{
              "source":"http://192.168.0.1/ztp-sonic/config_db.json",
              "destination":"/etc/sonic/config_db.json",
              "secure":false
          }
      }
  }
}

connectivity-check: The connectivity-check plugin is used to ping a remote host and verify if the router is able to reach the remote host. It is possible to ping multiple hosts and the plugin result is marked as failed even if ping to one of the specified host fails.

{
  "ztp":{
     "connectivity-check" : {
      "ping-hosts" : [ "192.168.0.1", "192.1.1.1" ]
     }
  }
}

snmp: The snmp plugin is used to configure SNMP community string on SONiC router.

{
  "ztp":{
    "snmp": {
      "community-ro": "public",
      "snmp-location": "sjc-r22"
    }
  }
}

ZTP detects default plugins in the ztp.json by parsing the configuration action object names. As an example, a configuration action object named xxx-configdb-json will be considered a configdb-json object. Here xxx corresponds to a number which can be used to indicate the order of execution of this action.

In addition to these default options, SONiC supports custom plugins. In the earlier example, the 002-provisioning-script was a configuration action object using a custom plugin. The supported options for a custom plugin are (from https://github.com/sonic-net/SONiC/blob/master/doc/ztp/ztp.md):

Object Usage Supported Values Default Value
url Define the URL string from where plugin has to be downloaded in the form of url object URL Object Name of enclosing object
dynamic-url Define the URL string from where plugin has to be downloaded in the form of url object Dynamic URL Object Name of enclosing object
name Use a predefined plugin available as part of SONiC ZTP package Predefined plugins Name of enclosing object
shell Use this to specify if the plugin has to be executed through the shell. For more information refer to the shell option of python subprocess library. true
false
false
ignore-section-data Use this to specify if section data read from the configuration section of the plugin should not be passed as the first argument to plugin command true
false
false
args Defines argument string that can be passed as an argument to the plugin command. The ignore-section-data object needs to be set to true if the plugin command is expecting only the argument string as part of the command. Valid command arguments Null string

Users can force execution order of SONiC ZTP configuration actions by adding embedding numbers to each object in the xxx-<configuration-action-object-name>. If we consider the earlier ztp.json file as an example, 001-configdb-json will be executed first followed by 002-provisioning-script.

ZTP invocation on SONiC:

The ZTP workflow requires the router to be pre-loaded with an image that attempts to get configuration artifacts when it first boots up. To enable this behavior, SONiC images can be built with a "ZTP flag" enabled. This optional build feature automatically begins the ZTP process on a router loaded with this image on first boot. In contrast, a "non-ZTP" image will boot-up without attempting to get onboarding information and expect a user to login and configure features on the router.

For testing and debugging purposes, ZTP can be invoked on a running router as well (provided the SONiC image supports ZTP). The following commands describe ZTP actions available for users on a running router:

admin@sonic:~$ sudo ztp -h
usage: ztp [-h] [-C FILE] [-c] [-v] [-y] COMMAND

Zero Touch Provisioning configuration and status monitoring tool

positional arguments:
  COMMAND               disable  Administratively disable ZTP
                        enable   Administratively enable ZTP
                        erase    Erase ZTP data
                        features ZTP features available
                        run      Restart ZTP
                        status   Display current state of ZTP and last known result

options:
  -h, --help            show this help message and exit
  -C FILE, --config-json FILE
                        ZTP service configuration file
  -c, --status-code     displays ztp status as a concise coded string. Used with status command.
  -v, --verbose         displays detailed ztp status information. Used with status command.
  -y, --yes
admin@sonic:~$ show ztp status -h
Usage: show ztp [OPTIONS] [[status]]

  Show Zero Touch Provisioning status

Options:
  --verbose       Enable verbose output
  -h, -?, --help  Show this message and exit.

For example:

admin@sonic:~$ show ztp status
ZTP Admin Mode : True
ZTP Service    : Active Discovery
Runtime        : 03s
ZTP Status     : Not Started

ZTP Service is active