Automating ArubaOS-CX Backups with Python and Paramiko
Learn how to automate ArubaOS-CX configuration backups to a TFTP server using Python and Paramiko. A practical guide for ensuring switch consistency.
Backing up switch configurations is one of those repetitive tasks that’s easy to overlook—until you need it most. Manual backups work, but they’re time-consuming and error-prone. That’s where automation comes in.
In this post, I’ll show you how I automated ArubaOS-CX switch configuration backups to a TFTP server using a simple Python script powered by Paramiko for SSH connections.
Overview
The Python script connects to each ArubaOS-CX switch listed in a file, logs in via SSH, and runs the following command:
copy running-config tftp://<tftp_server>/<filename> cli
Each backup is timestamped automatically, making it easy to track and store versions for disaster recovery or compliance auditing.
Prerequisites
Before running the script, make sure you have:
- Python 3 installed.
- Paramiko library (for SSH automation).
Install Paramiko via pip:
pip install paramiko
You’ll also need a TFTP server reachable from your switches. Ensure you update the variable tftp_server = "192.168.10.1" in the script to your own TFTP server IP address.
Switch List File
The script reads switch details from a text file (e.g., SwitchBackup.txt) located in the same directory as the script itself. Each line should contain the IP, username, password, and hostname separated by commas:
Location: Same folder as the script
<ip_address>,<username>,<password>,<hostname>
192.168.1.10,admin,password123,Switch01
192.168.1.11,admin,password456,Switch02
This approach makes it easy to scale—simply add new switches to the file without modifying the code.
How the Script Works
- Reads switch list: The function
read_switches()parses the text file, line by line, extracting IPs, credentials, and hostnames. - Establishes SSH connection: For each entry, the script connects to the switch using Paramiko with provided credentials.
- Runs backup command: Executes the copy command with a dynamically generated filename:
copy running-config tftp://<tftp_server>/<hostname>_<timestamp>.cfg cli. - Logs output and errors: Displays progress, including connection status, command output, and any errors encountered in the console.
- Handles exceptions gracefully: If a switch is unreachable or credentials are wrong, the script prints a clear error message and continues with the next device in the list.
Full Script
import paramiko
import datetime
def read_switches(file_path):
switches = []
try:
with open(file_path, 'r') as file:
for line in file:
parts = line.strip().split(',')
if len(parts) == 4:
ip, username, password, hostname = parts
switches.append({
'ip': ip,
'username': username,
'password': password,
'hostname': hostname
})
except FileNotFoundError:
print(f"Error: File '{file_path}' not found.")
return switches
def backup_config(switch):
date_str = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{switch['hostname']}_{date_str}.cfg"
tftp_server = "192.168.10.1" # Change this to your TFTP server IP
backup_command = f"copy running-config tftp://{tftp_server}/{filename} cli"
print(f"\nConnecting to {switch['ip']} ({switch['hostname']})...")
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(switch['ip'], username=switch['username'], password=switch['password'], look_for_keys=False)
print("Connected successfully.")
print(f"Running backup command: {backup_command}")
stdin, stdout, stderr = ssh.exec_command(backup_command)
output = stdout.read().decode()
error = stderr.read().decode()
if output:
print("Command Output:")
print(output)
if error:
print("Command Error:")
print(error)
print(f"Backup completed. File saved as {filename} on TFTP server {tftp_server}.")
ssh.close()
except Exception as e:
print(f"Failed to connect or execute command on {switch['ip']}: {e}")
def main():
file_path = "SwitchBackup.txt" # Update this path if needed
switches = read_switches(file_path)
if not switches:
print("No valid switch entries found.")
return
for switch in switches:
backup_config(switch)
if __name__ == "__main__":
main()
Final Thoughts
This small automation saves time, ensures configuration consistency, and makes disaster recovery far easier. Once you get it running, consider scheduling it as a cron job (Linux) or Task Scheduler (Windows) for regular, hands-off backups.