Automating Network Configuration with Python and Ansible

Automating Network Configuration with Python and Ansible
Network automation has evolved from a nice-to-have to an essential skill for modern network engineers. In this guide, I'll share practical approaches to automating network configuration using Python and Ansible.
Why Automate?
Manual network configuration is:
- Time-consuming and error-prone
- Difficult to scale across hundreds of devices
- Hard to maintain consistency
- Challenging to audit and rollback
Python for Network Automation
Python's extensive library ecosystem makes it ideal for network automation:
Using Netmiko for Device Configuration
pythonfrom netmiko import ConnectHandler device = { 'device_type': 'cisco_ios', 'host': '192.168.1.1', 'username': 'admin', 'password': 'secure_password', } with ConnectHandler(**device) as net_connect: output = net_connect.send_config_set([ 'interface GigabitEthernet0/1', 'description Automated Configuration', 'ip address 10.0.0.1 255.255.255.0', 'no shutdown' ]) print(output)
Parsing Configuration with TextFSM
TextFSM helps extract structured data from CLI output:
pythonimport textfsm template = open('cisco_ios_show_interfaces.textfsm') output = net_connect.send_command('show interfaces') fsm = textfsm.TextFSM(template) parsed_output = fsm.ParseText(output)
Ansible for Configuration Management
Ansible provides a declarative approach to network automation:
Basic Playbook Structure
yaml--- - name: Configure Cisco Switches hosts: switches gather_facts: no tasks: - name: Configure VLANs cisco.ios.ios_vlans: config: - vlan_id: 10 name: DATA - vlan_id: 20 name: VOICE state: merged - name: Configure Interfaces cisco.ios.ios_interfaces: config: - name: GigabitEthernet0/1 description: Uplink to Core enabled: true state: merged
Best Practices
1. Use Version Control
Store all automation scripts and playbooks in Git:
- Track changes over time
- Enable collaboration
- Facilitate rollback if needed
2. Implement Testing
Test configurations in a lab environment before production:
pythondef test_vlan_configuration(): output = device.send_command('show vlan brief') assert 'VLAN10' in output assert 'VLAN20' in output
3. Handle Errors Gracefully
pythontry: net_connect.send_config_set(config_commands) except NetmikoTimeoutException: logger.error(f"Timeout connecting to {device['host']}") except NetmikoAuthenticationException: logger.error(f"Authentication failed for {device['host']}")
4. Use Jinja2 Templates
Create reusable configuration templates:
jinja2interface {{ interface_name }} description {{ description }} switchport mode {{ mode }} {% if mode == 'access' %} switchport access vlan {{ vlan_id }} {% endif %}
Real-World Example: Bulk VLAN Deployment
Here's a complete example that deploys VLANs across multiple switches:
pythonimport yaml from netmiko import ConnectHandler from concurrent.futures import ThreadPoolExecutor def configure_device(device_info): try: with ConnectHandler(**device_info) as net_connect: config = [ 'vlan 100', 'name AUTOMATION_TEST', 'exit' ] output = net_connect.send_config_set(config) return f"Success: {device_info['host']}" except Exception as e: return f"Failed: {device_info['host']} - {str(e)}" # Load device inventory with open('devices.yaml') as f: devices = yaml.safe_load(f) # Parallel execution with ThreadPoolExecutor(max_workers=10) as executor: results = executor.map(configure_device, devices) for result in results: print(result)
Conclusion
Network automation with Python and Ansible transforms how we manage infrastructure. Start small with simple tasks like backup automation, then gradually expand to more complex workflows. The investment in learning these tools pays dividends in reduced errors, faster deployments, and better documentation.