NetStacksNetStacks

Example Templates

Enterprise

Three complete Cisco IOS-XE config templates (access port VLAN, NTP and logging, SNMPv2c with an ACL) with their variables, sample values, and rendered output.

Overview

These three templates make up the Campus access baseline stack in the NetStacks demo organization. All three use these settings:

  • Config Format: CLI (plain IOS-XE commands)
  • Operation: merge
  • A different Target Path label on each template (vlan/access-port, global/ntp-logging, global/snmp). For CLI templates the label is only descriptive, but it must be unique within a stack. See Template fields.

Copy any of them into Template Source in a new template (Config Automation → Templates → Create Template) and change the values to suit your network.

Templates list showing Access port VLAN provisioning, NTP and logging baseline, and SNMPv2c read-only community + ACL

The Templates list shows how many stacks use each template (Linked), how many variables it has, and its current version.

Access Port VLAN Provisioning

Creates (or renames) an access VLAN and puts one edge port into it with portfast. It uses only plain substitution, so it is a good first template.

Access port VLAN provisioningjinja
vlan {{ vlan_id }}
 name {{ vlan_name }}
exit
interface {{ interface }}
 description {{ port_description }}
 switchport mode access
 switchport access vlan {{ vlan_id }}
 spanning-tree portfast
 no shutdown
exit
VariableExample valueScope in the stack
vlan_id120Shared
vlan_nameGUEST-WIFIShared
interfaceGigabitEthernet1/0/36Per Device
port_descriptionGuest AP — floor 1, jack 101-36Per Device
Test Variables card with values entered for interface, port_description, vlan_id and vlan_name

In the template editor, Test Variables has one field per detected variable. With these values, the template renders to:

vlan 120
 name GUEST-WIFI
exit
interface GigabitEthernet1/0/36
 description Guest AP — floor 1, jack 101-36
 switchport mode access
 switchport access vlan 120
 spanning-tree portfast
 no shutdown
exit

NTP and Logging Baseline

Sets timestamps, time zone, NTP servers, and syslog for every IOS-XE device. It loops over a list of NTP servers and marks the first one prefer using loop.first.

NTP and logging baselinejinja
! NTP / logging baseline — {{ site }}
service timestamps log datetime msec localtime show-timezone
clock timezone CST -6 0
clock summer-time CDT recurring
{% for server in ntp_servers %}
ntp server vrf Mgmt-intf {{ server }}{% if loop.first %} prefer{% endif %}
{% endfor %}
logging buffered {{ logging_buffer }}
logging host {{ syslog_server }} vrf Mgmt-intf
logging trap {{ logging_level }}
logging source-interface Loopback0
Template Source editor with the NTP template and the detected variables chips below it, ntp_servers marked as list

NetStacks detects five variables. ntp_servers is tagged list because it is used in a for loop. Enter a list value as a JSON array, for example ["10.90.0.5", "10.90.0.4"].

VariableExample value
siteAustin HQ
ntp_servers["10.90.0.5", "10.90.0.4"]
logging_buffer64000
syslog_server10.90.0.6
logging_levelinformational

Rendered output:

! NTP / logging baseline — Austin HQ
service timestamps log datetime msec localtime show-timezone
clock timezone CST -6 0
clock summer-time CDT recurring

ntp server vrf Mgmt-intf 10.90.0.5 prefer

ntp server vrf Mgmt-intf 10.90.0.4

logging buffered 64000
logging host 10.90.0.6 vrf Mgmt-intf
logging trap informational
logging source-interface Loopback0
Removing the blank lines

The blank lines come from the line breaks after the {% for %} and {% endfor %} tags. IOS-XE ignores them. If you want tidy output, add whitespace control:

{% for server in ntp_servers -%}
ntp server vrf Mgmt-intf {{ server }}{% if loop.first %} prefer{% endif %}
{% endfor -%}

SNMPv2c Read-Only Community + ACL

Builds a numbered ACL from a list of poller addresses, then ties a read-only SNMPv2c community to it and sets location and contact.

SNMPv2c read-only community + ACLjinja
! SNMP read-only access — {{ snmp_location }}
access-list 60 remark SNMP-RO pollers
{% for poller in allowed_pollers %}
access-list 60 permit host {{ poller }}
{% endfor %}
access-list 60 deny any log
snmp-server community {{ community }} RO 60
snmp-server location {{ snmp_location }}
snmp-server contact {{ snmp_contact }}
snmp-server ifindex persist
Edit Template page for SNMPv2c read-only community + ACL with Test Variables for allowed_pollers, community, snmp_contact and snmp_location

With allowed_pollers set to ["10.90.0.6", "10.90.0.7"], the loop produces one permit host line per poller:

! SNMP read-only access — Austin HQ MDF 3.14
access-list 60 remark SNMP-RO pollers

access-list 60 permit host 10.90.0.6

access-list 60 permit host 10.90.0.7

access-list 60 deny any log
snmp-server community demo-ro RO 60
snmp-server location Austin HQ MDF 3.14
snmp-server contact [email protected]
snmp-server ifindex persist
Community strings are template values

The community is entered as an ordinary variable value. It is stored with the instance or deployment and shows up in the rendered config in deployment logs. Anyone who can open the deployment can see it.

Useful Variations

Optional voice VLAN. Leave voice_vlan empty and the line is skipped:

interface {{ interface }}
 switchport access vlan {{ vlan_id }}
{% if voice_vlan %}
 switchport voice vlan {{ voice_vlan }}
{% endif %}

A range of ports. Use range() to configure a block of interfaces from two numbers:

{% for n in range(first_port, last_port + 1) %}
interface GigabitEthernet1/0/{{ n }}
 switchport access vlan {{ vlan_id }}
{% endfor %}

Several ports with their own settings. Pass a JSON list of objects, for example [{"name": "Gi1/0/1", "vlan": 10}, {"name": "Gi1/0/2", "vlan": 20}]:

{% for port in ports %}
interface {{ port.name }}
 switchport mode access
 switchport access vlan {{ port.vlan }}
{% endfor %}