NEWS

Cisco MINT Partner! Learn more →

Automation
2025-01-05
8 min read

Automating the Impossible: How We Migrated 1000+ Cisco Umbrella Objects Without APIs

When Cisco Secure Access lacks APIs for critical configuration objects, do you spend days clicking buttons or get creative? Here's how we used Selenium to turn a 4-day manual nightmare into an automated dream.

Cisco Umbrella
Cisco Secure Access
Python
Selenium
Automation
Migration

Who Says Geeks Can't Have Fun? 🌝

Happy Hump Day, fellow network warriors!

You know what's fun? Solving challenges that make other engineers cry. And we have fun every single day doing exactly that. 😊

Today, I want to share how we turned what could have been a mind-numbing, error-prone, 4-day manual migration into an elegant automated solution. Because life's too short to click buttons 1,000 times.

The Challenge: When APIs Don't Exist

Picture this scenario:

  • Customer needs: Migrate from Cisco Umbrella to Cisco Secure Access
  • Objects to migrate: ~1,000 application list entries + ~1,000 do-not-decrypt list entries
  • Available APIs: None. Zip. Nada.
  • Manual effort required: 3-4 days of mind-numbing clicking
  • Error probability: Through the roof 😭

Here's the kicker: Cisco Secure Access doesn't have APIs for all configuration objects. No APIs for application lists. No APIs for do-not-decrypt lists. Just a web portal and the expectation that you'll manually enter everything.

The Crossroads: Manual Pain or Creative Gain?

We could have gone the manual route. I mean, that's what most people would do, right?

Manual Migration Math:

  • 2,000 entries total
  • ~2 minutes per entry (navigate, enter, verify, save)
  • = 4,000 minutes
  • = 67 hours
  • = 3-4 days of pure tedium

And that's assuming:

  • No typos
  • No missed entries
  • No fatigue-induced errors
  • No desire to throw your laptop out the window

But here's the thing: My team and I aren't "most people." We're here to give clients the best possible outcome. And clicking buttons for 4 days? That's not it.

The Solution: Selenium to the Rescue

Enter the magic of the selenium module with Python—the tool that lets you automate web browsers like a puppet master.

Instead of manually clicking and typing, we built a script that:

  • Reads the exported Umbrella configuration
  • Navigates the Cisco Secure Access portal
  • Clicks the right buttons
  • Fills in the right fields
  • Saves each entry
  • Verifies the upload

All while we grab coffee and watch it work. ☕

The Technical Magic: How It Works

Here's our solution blueprint:

Step 1: Export from Umbrella

# Download configuration from Cisco Umbrella
# Format: JSON with all application lists and do-not-decrypt lists

Step 2: The Selenium Automation Script

Here's a simplified version of what we built:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
import time

def migrate_to_secure_access(json_file):
    """
    Automates migration of Umbrella configs to Secure Access
    """
    # Load the exported data
    with open(json_file, 'r') as f:
        umbrella_data = json.load(f)
    
    # Initialize the browser
    driver = webdriver.Chrome()
    driver.get("https://secure-access.cisco.com")
    
    # Login process (simplified)
    login_to_portal(driver)
    
    # Navigate to application lists
    navigate_to_app_lists(driver)
    
    # Process each application entry
    for app in umbrella_data['application_lists']:
        add_application_entry(driver, app)
        time.sleep(0.5)  # Be nice to the server
    
    # Navigate to do-not-decrypt lists
    navigate_to_dnd_lists(driver)
    
    # Process each DND entry
    for dnd in umbrella_data['do_not_decrypt_lists']:
        add_dnd_entry(driver, dnd)
        time.sleep(0.5)
    
    print(f"Migration complete! Processed {len(umbrella_data)} entries")

def add_application_entry(driver, app_data):
    """
    Adds a single application entry via web automation
    """
    # Click "Add" button
    add_btn = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.ID, "add-application"))
    )
    add_btn.click()
    
    # Fill in the form
    name_field = driver.find_element(By.ID, "app-name")
    name_field.send_keys(app_data['name'])
    
    url_field = driver.find_element(By.ID, "app-url")
    url_field.send_keys(app_data['url'])
    
    # Save
    save_btn = driver.find_element(By.ID, "save-button")
    save_btn.click()

Step 3: Verification Script

Trust, but verify. Always.

def verify_migration(driver, original_data):
    """
    Verifies all entries were migrated successfully
    """
    migrated_apps = fetch_all_applications(driver)
    migrated_dnd = fetch_all_dnd_entries(driver)
    
    # Compare counts
    print(f"Original apps: {len(original_data['application_lists'])}")
    print(f"Migrated apps: {len(migrated_apps)}")
    
    # Check for missing entries
    missing = find_missing_entries(original_data, migrated_apps)
    if missing:
        print(f"Warning: {len(missing)} entries failed to migrate")
        return False
    
    print("✅ All entries migrated successfully!")
    return True

The Results: Time is Money (And Sanity)

Let's talk ROI:

Development Time:

  • Coding: ~8 hours
  • Testing: ~3 hours
  • Verification: ~1 hour
  • Total: 12 hours

Time Saved Per Migration:

  • Manual process: 67 hours
  • Automated process: 2 hours
  • Saved: 65 hours per customer

For Multiple Customers:

  • 10 customers = 650 hours saved
  • 20 customers = 1,300 hours saved
  • That's literally months of productive time returned! 💯

Lessons Learned: When Life Gives You No APIs...

1. Think Outside the API Box

Just because there's no API doesn't mean you're stuck with manual work. Web automation can be a lifesaver when official integration methods don't exist.

2. Always Factor in Testing Time

Yes, it took 12 hours to build. But those 12 hours prevent countless errors and save hundreds of hours down the line. That's not a cost—that's an investment.

3. Verify Everything

Automation without verification is just automated chaos. Always build in checks to ensure your automation actually worked.

4. Document Your Automation

Future you (or your teammates) will thank present you for clear documentation. Our script includes detailed comments and error handling for every edge case we encountered.

The Bigger Picture: Automation Mindset

This project embodies a core philosophy: Always look for the multiplier effect.

Sure, we could have done this migration manually. Once. But we're not in the business of doing things once. We're in the business of solving problems at scale.

Every hour spent on automation is an hour that pays dividends across every future migration. It's the difference between working hard and working smart.

Your Turn: What Would You Automate?

I'm curious—what manual, repetitive tasks are eating up your time? What processes make you think, "There has to be a better way"?

Maybe it's configuration management. Maybe it's report generation. Maybe it's something nobody else has even thought to automate yet.

Drop a comment below and let's brainstorm. Sometimes the best solutions come from engineers sharing their pain points.

Ready to Migrate?

If you're facing a Cisco Umbrella to Cisco Secure Access migration (or any similar challenge), we're here to help. Why spend days clicking when you could be solving more interesting problems?

Remember: Geeks can have fun. Especially when that fun involves making tedious tasks disappear. 🚀

P.S. - Interested in the full script? Reach out. We love sharing tools that make engineers' lives easier. After all, we're all in this together!

ABOUT THE AUTHOR

Tom Alexander

CTO, Ex-Cisco TAC

CCIEx2, former Cisco TAC engineer. Building automation solutions that save hundreds of hours for enterprise migrations.