Create a template which creates loopback99 with the ip-address of the loopback as a variable. Configure this only for IOS-XE. Apply this template to R1 with IP address 1.0.0.1/32.
If you are starting this lab without doing the previous one, you can add all devices to NSO with this config:
devices template loopback99
ned-id cisco-ios-cli-6.92
config
interface Loopback 99
ip address primary address {$ip-address}
ip address primary mask 255.255.255.255
!
commit
devices device r1 apply-template template-name loopback99 variable { name ip-address value '1.0.0.1' }
commit
You can use variables in a normal template by wrapping the variable name in curly braces. You then apply a value to the variable when applying the template to a device.
The issue with templates is that it is not stateful. It is merely a shorthand to applying boiler plate config. NCS does not “remember” the application for the template. You cannot then simply “remove” the template from the device.
Instead, to revert the config at a much later time, without affecting any other config changes since then, you would need to manually remove the config:
devices device r1 config
no interface Loopback 99
Also, you cannot easily change the value of the template later. For example, let’s look at a template that sets the SNMPv2 community string:
devices template snmpv2-string
ned-id cisco-ios-cli-6.92
config
snmp-server community {$community-string}
devices device r1 apply-template template-name snmpv2-string variable { name community-string value 'MY_STRING' }
commit
Let’s say we want to change the community string later:
devices device r1 apply-template template-name snmpv2-string variable { name community-string value 'MY_STRING_NEW' }
commit
We are left with both strings on the device:
Task 2. Create the same functionality as a service template with a service
Create an SNMP service that sets the SNMP community string.
Apply it once, then change it.
Task 2 Answer
# Stop NCS
ncs --stop
# Create the skeleton package
cd ~/nso-instance/packages
ncs-make-package --service-skeleton template snmpv2
# Edit the template
nano snmpv2/templates/snmpv2-template.xml
# Edit the YANG module to change the dummy type to a string
nano snmpv2/src/yang/snmpv2.yang
# Make the service
cd snmpv2/src/
make
# Start NCS and reload packages
cd ~/nso-instance
ncs
ncs_cli -Cu admin
packages reload
# Apply the service to r1
snmpv2 TEST device r1 dummy TEST_COMM
commit
Change the service
snmpv2 TEST device r1 dummy TEST_COMM_NEW
commit
The community is changed instead of being added in addition to the existing one:
We can also easily “un-deploy” the service:
snmpv2 TEST un-deploy
Summary
The reason is that a basic template simply just applys config in a stateless manner. If you have a complex template, you cannot later remove that template. You must figure out how to do it manually using a series of “no” commands. Instead, you should use services, because these are stateful. You can easily change the values of the variables of the service, or remove the service altogether. You can also easily re-deploy the service to ensure the devices are in-sync with the expected configuration.
The way that NSO models services is called “FASTMAP.”
When a template is used as part of a service implementation, thanks to NSO FASTMAP, NSO remembers the configuration changes made towards the devices and the template changes can for example be reverted.
This blog post makes the case for always using services instead of templates: