Backing up IOS Configs Automatically
In this blog article I’m going to teach you about the archive command in Cisco’s IOS. Using the archive command you can create a backup of your IOS config every time you save the configuration and/or periodically. Let’s jump in!
Saving configurations is essential. If you make a change to the config you need to save it, otherwise the next time the device reloads it’ll revert back to it’s last saved configuration. Depending on how many changes you made during that session this could be catastrophic!
Saving the config is easy. You can issue either copy running-config startup-config (or copy run start for short), write memory, write, or even just wr to save a config. When you do this you’re taking the current running configuration which is what you just modified and are saving it as the startup configuration, or the configuration that is loaded from flash at boot-up.
Now you could use the copy running-config command to save the configuration as a different file name, like copy running-config backup.cfg, confirm the file name of backup.cfg, and then we can see the backup config in flash, like so:
Then, like any other files we could use the copy command to copy the file over to a tftp server.
This process might be fine if you have a small network, but what if you had a larger one? You’d want a way to do this automatically. Enter the Archive command.
Configuring the Archive Command
For this demonstration I’m using a Cisco ISR 2921 running IOS 15. Please consult the configuration guide for the specific version of IOS you’re using, as configuration syntax, options, and availability may be different.
The IOS archive command has a few parameters we can configure so let’s go over those. The really import ones we want are path, maximum, and write memory.
The path is the specified location where you want to save your archived configs. This could be local to the device, but if the device crashes and is otherwise not recoverable those locally saved configs won’t do much for you, so stick with a remote destination.
Next is maximum. This is the maximum number of copies you wish to keep on hand in the directory where you’re storing your archived configs. Some remote destinations may not support this, as there may be permissions required to delete or overwrite files.
And lastly, write memory. This tells IOS to run the archive command any time the configurations are saved. Otherwise you can issue the archive config command to save a copy of the config to the stored path.
When setting the path you’re also specifying the file name to be used. You could type out the “hostname”-backup here, but then this isn’t very easily repeatable and clean. So, what you can do is make use of some variables. The variables will just be replaced at the time the config is saved. There are two supported variables. The first is $h for the hostname, and the other is $t for the time. Make sure you have your device configured for accurate time by using an NTP server, and configuring the clock on the device. You can checkout my previous article on configuring NTP here.
For this example I’m using my home Synology NAS configured as a TFTP server.
First, we’ll move into global configuration mode and type archive. Next we’ll set the path for the TFTP server. You’ll notice I’m using variables here in a couple of places.
R2(config)#archive R2(config-archive)#path tftp://10.76.1.146/CONFIG-ARCH/$h/$h-$t R2(config-archive)#write-memory
In my TFTP root I have a folder called CONFIG-ARCH, for Configuration Archive. Within that folder I have a folder that I created for each lab router. I named the folder the hostname for each router, so I could just use the variable in the path. Then, the archive filename is hostname-time, and the time will include whatever you have configured for your log timestamps. In my case I have the local time, and I included the timezone, use the service timestamps log command to customize this.
Then we issue the command write-memory to tell the archive to create an archive whenever a config is written.
So now we can see the write command being issued and then a new archive config is pushed via TFTP!
Scheduling an Archive
So, what if we wanted to grab an archive config on a regular basis and not just when config is written? There are two solutions for this.
The first is within the archive config itself and it’s called time-period. This is the time, in minutes, IOS will save an archive config on a cycle. Do you want to save the config every hour? time-period 60. How about every day? time-period 1440. You could do weekly – 10080.
Now, the problem with time-period is that it’s not an exact recurring, scheduled event. Its just a count down. If the count down gets disrupted due to loss of power or reboot or something else, then the count down restarts. A recurring countdown should be just fine. But, if you’d rather have a more dependably scheduled event then we’ll have use an IOS Kron Job. (Yes, it’s Kron with a K)
IOS Kron Jobs
A Kron job in IOS, just like a Cron job in other operating systems, allows you to schedule things like scripts and other automation. There are two parts to the Kron job – a kron policy list – “what are we doing?” and a kron occurrence – “when are we doing it?”
First we’ll configure the policy. We start by giving the policy a name. Personally when I name things in my IOS code I use all capital letters, this way when I’m scanning configs I know that all-caps means it was created by a human and not just code. We’ll call the policy CONFIG_ARCHIVE and then use the cli keyword to tell the Kron policy we’re entering commands, then type out the command you wish to execute as part of the policy. If you want to issue multiple commands as part of your policy you can enter them here line by line.
R2(config)#kron policy-list CONFIG_ARCHIVE R2(config-kron-policy)#cli wr
Next, we’ll configure the Kron occurrence. The occurrence tells IOS when to run the Kron job. we’ll enter the command kron occurrence then a name, I used ARCHIVE, then we can use the at keyword to tell it a specific time. There’s also the in keyword which allows us to specific a delay in minutes, hours and minutes, or days, hours, and minutes. But, for now we’ll use at and then specify the time of day using the 24 hour clock, and then we can do a couple of different things from here. We can specific a day of the month, like 10, and the Kron job will run at the specificed time on the 10th of every month. Or we can specify a day of the week and the job will run at that time on that day of every week. I’m going to configure mine to run at 9AM on the 10th of every month. We use the recurring keyword to have the kron job run over and over again. We can also use “oneshot” if we wanted the job to run one, and only once.
kron occurrence ARCHIVE at 9:00 10 recurring
Next we have to specify the policy we created earlier so we’ll enter in the policy name from earlier.
R2(config)#kron occurrence ARCHIVE at 9:00 10 recurring R2(config-kron-occurrence)#policy-list CONFIG_ARCHIVE
And there, now our Kron job to run the CLI command wr on the 10th of every month at 9am is complete! And, because we configured archive to write the config to our TFTP server the configurations will be backed up in a central location.
Here’s the full config used in this article so you can use and modify it for your needs!
! Archive command using TFTP archive path tftp://10.76.1.146/CONFIG-ARCH/$h/$h-$t write-memory ! Kron Policy kron policy-list CONFIG_ARCHIVE cli wr ! Kron Occurrence kron occurrence ARCHIVE at 9:00 10 recurring policy-list CONFIG_ARCHIVE
I hope you’ve enjoyed this article. If you found it useful please share it with others!
As always, thanks for stopping by!
Awesome, do you know if this procedure works in earlier iOS versions ?
if you do configuration changes often the problem is that over the time in your tftp server will be a lot of backup files taking up space, and what if you have 10-20 or more devices
Great question and consideration and I’ve actually dealt with this before. On Windows servers, you can write a PowerShell script to delete files that are so many days old. I’m sure the same can be done with a Bash script on Linux.