A look at Arista's configuration session

When making changes it's generally advisable to have a few things:

  • A rollback plan
  • Atomic changes
  • Control around releases

This is a given in the land of Juniper, but sadly has been lacking on Cisco, Arista, HP and other network kit based on the familiar syntax.

Thankfully Arista added in a feature last year, which brings initial support for this and some nice use cases with it!

We'll take a look at what Arista offers and how we can use it.

The basics

configure session as added in EOS 14.4 (mid-2015), enables changes to be staged, reviewed, rollback and committed as required.

The most basic usage is to use configure session rather than configure terminal and commit before exiting the configuration mode.

Lets take a basic example; changing the IP on the Management interface:

localhost#configure terminal
localhost(config)#interface management 1
localhost(config-if-Ma1)#ip address 1.2.3.4/24
localhost(config-if-Ma1)#ip address 4.3.2.1/24
localhost(config-if-Ma1)#ip address 1.2.3.4/24
localhost(config-if-Ma1)#

Completing the same using a configuration session is nearly identical:

localhost#configure session example1
localhost(config-s-exampl)#interface management 1
localhost(config-s-exampl-if-Ma1)#ip address 1.2.3.4/24
localhost(config-s-exampl-if-Ma1)#ip address 4.3.2.1/24
localhost(config-s-exampl-if-Ma1)#ip address 1.2.3.4/24
localhost(config-s-exampl-if-Ma1)#commit

However, there is 1 key difference. In the first example, the IP is changed to 4.3.2.1, in the second the IP is never set to this.

This can be seen as below:

localhost(config-s-exampl-if-Ma1)#ip address 4.3.2.1/24
localhost(config-s-exampl-if-Ma1)#show ip int ma1 brief
Interface              IP Address         Status     Protocol         MTU
Management1            1.2.3.4/24         up         up              1500

This is due to the config not actually being applied until the 'commit' command has completed.

Naturally, you also have the usual commands, including aborting, computing the diff etc:

localhost(config-s-sess1)#show session-config diffs
--- system:/running-config
+++ session:/sess1-session-config
@@ -35,7 +35,6 @@
 interface Ethernet7
 !
 interface Management1
-   vrf forwarding management
    ip address 1.2.3.4/24
 !
 no ip routing

localhost(config-s-sess2)#abort
localhost#

These also work when not in configure mode, by passing the session name (see below);

localhost#show session-config named sess2 diffs
--- system:/running-config
+++ session:/sess2-session-config
@@ -35,7 +35,6 @@
 interface Ethernet7
 !
 interface Management1
-   vrf forwarding management
    ip address 1.2.3.4/24
 !
 no ip routing

The difference

At a basic level, this is familiar to the Juniper world of 'configure & commit', but we get much more.

You can have multiple pending configuration sessions, disconnecting from the device and re-entering the same session by name later, or passing it to another engineer for review.

To view all sessions you can issue the show configuration sessions command:

localhost#show configuration sessions detail
Maximum number of completed sessions: 1
Maximum number of pending sessions: 5

  Name        State           User       Terminal    PID
  -------- --------------- ---------- -------------- ---
  example1    completed                                  
  example2    pending                                    
  sess1       pending                                                         

A simple use case for this feature may be continuing earlier work, a more complex example could be enforcing 2 users are involved in a config change; this has a very nice appear for environments with high compliance requirements.

Limitations

Currently, there is no rollback command, once the change is committed trying to display the diff or inverse diff is not possible.

It's also not super easy to hook into config events to backup the config just before a config commit happens. You're still going to be relying on access logs or scheduled config backups to figure out what changed if you don't have the session-config diff to hand.

This would be a really nice feature, that I hope they implement soon.

For any configs on the flash, these can either be restored (config replace flash:startup-config.xxxx), or the differences displayed (diff running-config flash:startup-config.xxxx) pretty easily, so most the functionality is already there.

An example 'four-eye' change

Let's establish some ground rules:

  • Operations staff can 'request' config changes
  • Operations staff have no access to the advanced shells (i.e. APIs directly)
  • Engineering staff can 'approve' (commit) requested config changes
  • Engineering staff can do anything they want

To enforce this, we can create 2 groups with relevant permissions;

localhost(config)#role operations
localhost(config-role-operations)#10 permit mode exec command configure session
localhost(config-role-operations)#20 deny mode exec command configure|bash|python-shell
localhost(config-role-operations)#30 deny mode config command commit
localhost(config-role-operations)#40 permit mode exec command .*

localhost(config)#role engineering
localhost(config-role-engineering)#10 permit command .*

Next, let's define some test users;

localhost(config)#username ops1 role operations nopassword
localhost(config)#username eng1 role engineering nopassword

Trying a standard configure command as ops1, results in an error;

localhost#configure terminal % Authorization denied for command 'configure'

However, using configure session is allowed;

localhost#configure session
localhost(config-s-sess4)#hostname super-cool-001
localhost(config-s-sess4)#show session-config diff
--- system:/running-config
+++ session:/sess4-session-config
@@ -7,6 +7,8 @@
    action bash sudo /mnt/flash/initialize_ma1.sh
 !
 transceiver qsfp default-mode 4x10G
+!
+hostname super-cool-001
 !
 spanning-tree mode mstp
 !

We've successfully staged the config change but cannot commit it.

localhost(config-s-sess4)#commit
% Authorization denied for command 'commit'

Let's ask our eng1 user to proceed;

First, lets review the change:

localhost#configure session sess4
localhost(config-s-sess4)#show session-config diffs
--- system:/running-config
+++ session:/sess4-session-config
@@ -7,6 +7,8 @@
    action bash sudo /mnt/flash/initialize_ma1.sh
 !
 transceiver qsfp default-mode 4x10G
+!
+hostname super-cool-001
 !
 spanning-tree mode mstp
 !

As you can see, this is identical to what the ops1 user sees. We can then commit the change as normal, changing the status to completed:

localhost(config-s-sess4)#commit

super-cool-001#show configuration sessions detail | inc sess4
  sess4    completed

Now the change has been completed, no further changes can be made.

Real life examples

When is this a life saver? Simply whenever you need atomic changes.

Migrating management interfaces into a different VRF

Using a separate routing domain for management traffic is attractive in certain environments.

Let's look at the simplest change:

localhost>show ip int management 1 brief
Interface              IP Address         Status     Protocol         MTU
Management1            1.2.3.4/24         up         up              1500

localhost(config)#vrf definition management
localhost(config-vrf-management)#rd 0:0

localhost(config)#interface management 1
localhost(config-if-Ma1)#vrf forwarding management
! Interface Management1 IP address 1.2.3.4 removed due to enabling VRF management

! We've now lost access to the device!
Interface              IP Address         Status     Protocol         MTU
Management1            unassigned         up         up              1500

This makes the migration tricky, without another form of access (console, loopbacks etc).

Using a config session we can make the change and re-apply the IP, resulting in only a short interruption:

localhost(config-s-sess0)#interface management 1
localhost(config-s-sess0-if-Ma1)#vrf forwarding management
localhost(config-s-sess0-if-Ma1)#ip address 1.2.3.4/24
localhost(config-s-sess0-if-Ma1)#commit
localhost#show ip int management 1 brief
Interface              IP Address         Status     Protocol         MTU
Management1            1.2.3.4/24         up         up              1500

localhost#show vrf management
   Vrf              RD        Protocols       State             Interfaces  
---------------- --------- --------------- -------------------- -----------
   management       0:0       ipv4,ipv6       v4:no routing,    Management1
                                              v6:no routing                

This can be extended as required; RADIUS, DNS, NTP, SNMP config sections are a few places that come to mind as requiring changes under these circumstances.

Changing ACLs

When building access control lists, it's common practice to space the entries, allowing for future entries to fit into the list, preventing access issues due to ordering.

Sometimes it's useful to change these on mass:

  • ACLs come from an external system, computing the diff is required
  • Re-ordering of the entries needs to take place to allow for growth
  • Standardisation of ACLs across multiple devices

Typically, this is a painful process as you cannot remove an ACL, without directly impacting traffic.

Once again, due to the staging aspect of commit sessions, we can make all of our changes and have a single change resulting in our desired config.

A similar approach can be taken for more complex objects, such as route maps.

Staging config

Simply, the ability to stage config is very useful.

Let's imagine you have a maintenance window that requires 3 steps:

  • Placing BGP peers into maintenance mode
  • Re-configuring said peers for BFD
  • Reverting step 1

Rather than having this in text files and copying it in sequence, we can stage the configs and simply apply them as required.

The rollback config can also be staged, allowing a very fast rollback with little confusion.

This could play out along the lines of;

localhost#show configuration sessions | inc maint-10001
  maint-10001-step-1           pending                        
  maint-10001-step-1-revert    pending     

localhost#configure session maint-10001-step-1
localhost(config-s-maint-)#commit

!! Breakage, rollback

localhost#configure session maint-10001-step-1-revert
localhost(config-s-maint-)#commit

API support

The configuration session command is also supported via the eAPI, which has a nice side effect, ensuring any config errors submitted remotely do not result in partially applied configs.

Summary

While not perfect, this certainly gives you some nice features. I hope further features are built, extending the functionality.

Ideally, the changes are being versioned and pushed via an external service, but we all know in reality that sometimes it's easier/quicker to check a single device in question. Old habits die hard!

Comments