Showing results for 
Search instead for 
Did you mean: 

APIC-EM 1.3 Update – Part 1 - PnP Templates

Cisco Employee


This blog series covers some of the new API released as part of the APIC-EM 1.3 release of code.


This particular blog covers a new feature in the Plug and Play (PnP) application, configuration templates.  Prior to version 1.3, the configuration file was a text file and did not support variables. If you wanted to use a template you needed to use Prime Infrastructure.  In APIC-EM 1.3, template support has been added.

This blog looks at both the UI and API required for templates.

For all of these examples I am using a 3650 switch running 3.6.5 code, but you could use versions of 16.3.1 and 3.7.4 (For other platforms such 2960x please see release notes for details).


I am going to assume you have seen my earlier blogs Network Automation with Plug and Play (PnP) – Part 1 on the mechanics of PnP and how to configure discover (DHCP, DNS) etc.



A template is identical to a standard configuration file, except it has variables embedded in it. Templates use the "velocity" template language, the same as Prime Infrastructure.  Variables start with the "$" character.  For example there is a "hostname" variable in this example.

hostname $hostname

enable password xxx


username sdn password 0 xxx


ip http server

ip http secure-server

snmp-server community xxxx RO


line con 0

line vty 0 15 

login local 

transport input ssh telnet


When you view the template in APIC-EM, there are three views:

  1. Text view: the file above.  Variables have a "$" at the start
  2. Form View: just shows the variables.
  3. Preview: Shows the complete configuration with variables filled in.

template view.png

Templates can be uploaded the same as any other configuration file, through the user interface or the API.

Using the Template – User Interface

Templates are used in PnP rules in exactly the same way as normal configuration files.  One extra step is to fill in the variables. In this example I am going to use a pre-defined rule, but templates work with unclaimed devices as well.

NOTE: You do not need a specific suffix on a template file.  The controller searches the configuration file for variables, and if they are present, the file is treated as a template.


I then need to select the "Form View" to fill in the variables.  This example has only one variable "hostname"


I then need to select "Device Configuration" and scroll down to the bottom of the page to "Add" the Device. 

NOTE: I have also configured some stack parameters.  These are only required as I am also using a stack of switches.


Now the rule has been added successfully.


Once the switch has been provisioned you will notice the configuration file has changed.  This will be the rendered template with all of the variables filled in.


Using the Template – User Interface

In this section I will cover the API that are required to use the template API.  I am going to assume you have seen my earlier blogs for a detailed description of using the PnP API.

  I have already created a project and uploaded the configuration file.  This was covered in an earlier blog Network Automation with Plug and Play (PnP) – Part 2

Templates require two new API "/template" and "/template-config" as shown below:


Here is the API call to get the "id" for the template file "3650-dhcp-template.txt".

https://adam-iwan/api/v1/pnp-file/config?name=3650-dhcp-template.txt GET


      "nameSpace": "config",

      "name": "3650-dhcp-template.txt",

      "downloadPath": "/file/e8682c6f-e9f7-425b-a8a7-08f37ee2bb2d",

      "fileSize": "281",

      "fileFormat": "text/plain",

      "md5Checksum": "4a733185281e17e15228d5636c921308",

      "sha1Checksum": "0bccd2be238ed74e283c198af1ed7b4291717ce3",

      "id": "e8682c6f-e9f7-425b-a8a7-08f37ee2bb2d"


Configuration files that are templates will have an entry in template table.  I  need to find the template UUID from the fileId (e8682c6f-e9f7-425b-a8a7-08f37ee2bb2d).

https://adam-iwan/api/v1/template?fileId=e8682c6f-e9f7-425b-a8a7-08f37ee2bb2d   GET


"response": [


      "fileId": "e8682c6f-e9f7-425b-a8a7-08f37ee2bb2d",

      "id": "d1fd02d0-c9cf-4fad-b706-1332a891ca18"



The next step is to create a configuration file from the template. I use the UUID of the template (d1fd02d0-c9cf-4fad-b706-1332a891ca18) obtained above.

https://adam-iwan/api/v1/template-config  POST

[{"templateId":"d1fd02d0-c9cf-4fad-b706-1332a891ca18", "configProperty":{"hostname":"stack-template"}}]

Because this is an asynchronous operation, a task will be returned.


"response": {

"taskId": "8a82c03f-b746-41e6-b7b1-23be1c552ebe",

"url": "/api/v1/task/8a82c03f-b746-41e6-b7b1-23be1c552ebe"


"version": "1.0"


I need to poll the status of the task (8a82c03f-b746-41e6-b7b1-23be1c552ebe") and get the UUID of the rendered template (13c6b9cf-f91c-429d-8489-46d81263d1a2)

https://adam-iwan/api/v1/task/8a82c03f-b746-41e6-b7b1-23be1c552ebe   GET


"response": {

"startTime": 1477824534405,

"endTime": 1477824534424,

"version": 1477824534405,

"progress": "{\"message\":\"Successfully added the Ztd Template Config\",\"id\":\"13c6b9cf-f91c-429d-8489-46d81263d1a2\"}",

"serviceType": "Ztd Service",

"isError": false,

"rootId": "8a82c03f-b746-41e6-b7b1-23be1c552ebe",

"id": "8a82c03f-b746-41e6-b7b1-23be1c552ebe"


"version": "1.0"


I have successfully created a new template with the variable hostname":"stack-template"

In order to create a rule in the project (named "template), I also need the UUID of the project.

https://adam-iwan/api/v1/pnp-project?siteName=template  GET


      "state": "PRE_PROVISIONED",

      "siteName": "template",

      "tftpServer": "",

      "tftpPath": "",

      "deviceCount": 0,

      "pendingDeviceCount": 0,

      "provisionedBy": "admin",

      "provisionedOn": "2016-10-29 02:35:26",

      "id": "d168aa1a-bf61-46c9-b5d6-7ae4e27c48c8"


I can now create a rule in my project using the configuration template i created earlier.  The items in red, are specifically for a stack deployment.

https://adam-iwan/api/v1/pnp-project/d168aa1a-bf61-46c9-b5d6-7ae4e27c48c8/device POST












Again, get the task body to see the task was successful.  This also returns the UUID of the newly created rule.

https://adam-iwan/api/v1/task/9ba76c24-4db1-44f4-a9bd-e3f8b6507e33 GET


"response": {

"startTime": 1477824968481,

"endTime": 1477824968527,

"version": 1477824968481,

"progress": "{\"message\":\"Success creating new site device(rule)\",\"ruleId\":\"234f2700-62b2-4721-8780-a6ccb79900e0\"}",

"serviceType": "Ztd Service",

"isError": false,

"rootId": "9ba76c24-4db1-44f4-a9bd-e3f8b6507e33",

"id": "9ba76c24-4db1-44f4-a9bd-e3f8b6507e33"


"version": "1.0"


The User Interface shows the rule has been defined successfully.


This can be also be verified through an API call:  NOTE: the "templateConfigId": and the ruleID which matches that returned by the task above (234f2700-62b2-4721-8780-a6ccb79900e0)

https://adam-iwan/api/v1/pnp-project/d168aa1a-bf61-46c9-b5d6-7ae4e27c48c8/device   GET


"response": [


      "hostName": "switch",

      "platformId": "WS-C3650-48FQ",

      "serialNumber": "FDO1735Q0G5",

      "site": "template",

      "templateConfigId": "13c6b9cf-f91c-429d-8489-46d81263d1a2",

      "pkiEnabled": false,

      "sudiRequired": false,

      "apCount": "0",

      "isMobilityController": "false",

      "memberCount": 2,

      "licenseLevel": "ipservices",

      "eulaAccepted": true,

      "state": "PENDING",

      "stateDisplay": "Pending",

      "authStatus": {

        "type": "Unknown",

        "status": "None",

        "errorMessage": null,

        "timestamp": 1477824995539,

        "certInfo": null


      "aliases": [],

      "id": "234f2700-62b2-4721-8780-a6ccb79900e0"



"version": "1.0"


Here is a summary of the API calls above. NOTE the section in RED is the only difference compared to a standard configuration file.


What Next?

This blog covered configuration templates for PnP, native in APIC-EM.  My next blog will cover some of the new EasyQoS API.

In the meantime, if you would like to learn more about this, you could come hang out with us in The Cisco Devnet DNA Community. We’ll have a continuous stream of blogs like this and you can ask questions and we’ll get you answers.  In addition, we have a Github repository where you can get examples related to PnP.

Thanks for reading,



Thanks a lot. Templates is very useful and long time waited for feature!

Do we know what exactly is supported and what not (yet?) It would be nice to have some reference guide since examples in Velocity from Prime books dont work.

Tried with cnstructions with #MODE_ENABLE and #INTERACTIVE - no luck.

If there way or at least plan to use some info from deployed device in template?


Deploying two types of switches with 24 and 48 ports. Last two ports are uplink.

I'd like to be able to get list of interfaces from switch and apply specific config for my last two ports only.

Can I provide drop down menu with prepopulated values which will trigger setting certain variable(s)?


Global deployment and multimode monitoring system. Traps are being sent to node specific to region.

I'd like to present selection: region1, region2, region3 and configure trap destination for region1, for region2 and for region3

Cisco Employee

Hi Misha,

Great to get your feedback.

the support is pretty basic at present.  The release notes give some examples of the constructs. #set, #if, #else, and #foreach etc.

The next step is to add context and give you access to information from the device etc.

Are there other things you would like to see, in addition to what you have described above?



Hi Adam,

Would it be possible to get more examples of templates. Just to see what could be done and what power it reveals.

There are many different cases and fixing list of things isnt going to work for everyone.

What about providing capability of sending command to the PNP device and parse output?

Alternatively it could set of things which are defined by user per device profile (different infos might be required if this is switch, router or AP).

Makes sense?




Another quesion this time related to visualisation of what is presented in Form view from APIC-EM.

Are there any possibilities? Now it just gets $Value and asks for. Possibility to add free text?


Cisco Employee

1.3.3 is now out.  This contains a way to escape '$' in encrypted passwords in a template

Release Notes for Cisco Network Plug and Play, Release 1.3x - Cisco


Is there a way to export the API variables into the template? For example I give the device a device name when I claim it into a project. Can I get hold of that device name (hostName) and have it resolve in the template so I don't have to retype the hostname?.

Cisco Employee

Hi Tom,

do you mean access to "system variables" which includes information about the device itself from within the template?

If so, we are looking at this.

Are you looking for a way to populate a template via API with some of those variables?  You are creating the rule at the same time as adding the template (via the API), so it is quite easy to do.  Happy to provide an example.



Thanks. Yes to the former – If I put the hostname/devicename in the project via the GUI I would like to be able to retrieve that value via a template variable.


However I would like to see your example of populating a template with items from the API. I always learn something when I look at your code.


Thanks for all your contributions to the community!



Hi again,

Do the templates support #include and #parse?


This widget could not be displayed.