Wednesday, 23 September 2020

Juniper Configuration Groups

 Although the use of network automation / Infrastructure as Code is likely to greatly reduce their usefulness, configuration groups can be pretty handy things to include in your Juniper configuration. 

You can use them for two major things:

  1. portable generic configuration you are likely to set everywhere on all your routers (something like DNS servers or NTP servers, or a management network gateway etc.), and
  2. specific configuration that differs from Juniper's defaults, but is the common "base" configuration for that type of object in your network. 
The second tends to be the more useful.

People that are not familiar with Junos may find this group inheritance behaviour surprising, and surprising is not a thing you really need in an operational network - so it's worth understanding configuration types in Junos that are commonly used, but not immediately obvious. 

So, let's have a look at these handy magical blocks of group configuration!


Some use cases...

A major use at my last site on our distribution routers was ensuring that VLANs that went over (almost) all interfaces were consistently applied, ensuring they didn't get forgotten - and couldn't be inadvertently removed by issuing the wrong command; where we didn't want those for some specific reason, we could exclude specific interfaces from inheriting that configuration. Essentially, these VLANs were used for wireless access, and had to go to pretty much every building in that network sector - chances are, we wanted those VLANs on an interface, so there they were! Similarly, we used another one to ensure OSPF interfaces were passive - and over-rode that where we actually wanted neighbo(u)r relationships to form. 

With some thinking, you can even use groups to define and apply a third type of group configuration, like different customer-facing services (wildcard groups are very useful here) - and when those services change, simply update the configuration in one place (in the relevant group), and it propagates through all the occurrences of that type of customer service (for instance a bandwidth allocation on a customer MPLS path for each level of service you sell).
You could achieve changing a load of identical values throughout a configuration with a replace pattern  throughout a configuration - but manually (re)configuring things is more prone to human error that programmatic inheritance - and replace patterns have some gotchas - make extensive use of show | compare if you use them!


How do I know if groups are changing my configuration? 

One thing you may not realise is that configuration groups can be quite stealthy - they won't be output in an obvious way in show configuration, except as a list of groups at the top, and some possibly not immediately obvious apply-groups configuration elements - unless you pipe display inheritance.

In other words:

show configuration | display inheritance
<snip>
unit 3 {
encapsulation vlan;
vlan-id 20;
peer-unit 2;
family inet {
address 10.20.0.2/30;
}
##
## 'mpls' was inherited from group 'mpls_lt'
##
family mpls;
}
</snip>
gives you a much better "situational awareness" of your router's configuration - without it, you might not realise the interface has the mpls address family configured on it. In unfamiliar Juniper environments, bear inheritance in mind!

If you find the comments tedious, add | except ##

show configuration | display inheritance | except ##

Note this then won't tell you where the config came from - but you will see the configuration that is applied to your system, including any inherited config.

You can also try show configuration | display inheritance | display set, although it's not the easiest to read - but you can still see which groups are being applied where.

You can also carefully examine the configuration itself to determine the groups that exist

show configuration groups

and then check for apply-groups to see where they are applied: 

show configuration | match apply-groups | display set

which will give you the immediate stanzas including apply-groups (and apply-groups-except), which should give you enough context to see where they are applied - if you need greater context, you at least then know where in the configuration to look! 

The third, really hard way of noticing this is that you note the output of operational commands implies the presence of configuration you never recall applying. In this example, that confusion might be that interfaces have family mpls on them, but it doesn't seem to be configured at first glance, yet show interfaces terse shows mpls!

Finally, in that vein, you should be aware that Junos applies a whole load of defaults silently - mostly these do not cause you issues, but you should know that:

show configuration | show inheritance defaults

can display what these are and where they are applied.


How do you create and use these groups? 

Simple, just name them and apply the config you want, using wildcards where appropriate. 

A good example is setting something on an interface: 

set groups mpls_lt interface <lt-*> unit<*> family mpls

the base syntax is:

set groups <name> <config you want to apply> 

Next, you need to apply-groups to your configuration. 

The least effort is to apply them to the entire configuration (set apply-groups <groups name(s)>), but that is not efficient. Instead, add apply-groups closer to where they will be applied - people are more likely to notice groups are in use that way, too. 

set interfaces apply-groups [list_of your_groups about_interfaces]

 From the example group we configured a moment ago, this would be

set interface apply-groups mpls_lt

What about if we want to NOT use a group on a particular bit of configuration? Easy! Set the apply-groups-except setting to the relevant bit of your configuration. 

set interfaces lt-0/0/0.1 apply-groups-except mpls_lt

or more generically

set <some config item> apply-groups-except <one or more groups you want to exclude> 

If you want to get really fancy, you can also apply configuration conditionally, such as when the platform is a particular model:

set groups mx240_config when model mx240

would apply whatever was in the group mx240_config to any device that was an MX240 - but it would be ignored on any other Juniper platform. 


Help! My commit time is horrid now!

If you set apply-groups, it may take your router some time to now process all of the stanzas within your configuration, decide if it needs a change, and applying the change from the apply-group(s) you defined. 

Remember, you can add set apply-groups [list of groups] at the top of your configuration, but that would evaluate every single configuration stanza against every single group! Rather add the apply-groups to sub-sections of your configuration, such as listing only the apply-groups for interfaces under the [edit interfaces] section.
Fewer wildcard matches will also improve speed.

On some Juniper platforms, 

set system commit persist-groups-inheritance

allows the system to store the results of some of the applied groups with wildcards between commits (almost "precompiled" if you will), speeding the evaluation of the groups and therefore improving commit times. You may also like to be more specific about where you apply-groups, and which groups you apply, if you haven't already done that! 

When we upgraded from MX10 edge routers to MX204, one thing we noticed was a massive improvement in not only BGP convergence, but near-instantaneous commits - slow commits can be really annoying, so it's worth spending a little time to make sure you're not doing your configuration in a way that's likely to drag them out unnecessarily. The improved commit time was mainly down to much more CPU power (1.33GHz PowerPC CPU vs. 1.6-GHz Intel 8 Core X86 CPU), but a side-order of solid state storage probably didn't hurt either. I offer this tale to illustrate that slow commits are annoying - particularly once you've experienced near instantaneous ones...!


Further reading


No comments:

Post a Comment