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

  1. Reads switch list: The function read_switches() parses the text file, line by line, extracting IPs, credentials, and hostnames.
  2. Establishes SSH connection: For each entry, the script connects to the switch using Paramiko with provided credentials.
  3. Runs backup command: Executes the copy command with a dynamically generated filename: copy running-config tftp://<tftp_server>/<hostname>_<timestamp>.cfg cli.
  4. Logs output and errors: Displays progress, including connection status, command output, and any errors encountered in the console.
  5. 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.