5.9 Configuration Groups & Profiles¶
Document Information¶
- Version: 1.0
- Last Updated: December 2025
- Author: Network Architecture Team
- Status: Production Ready
Overview¶
Configuration Groups and Feature Profiles represent the modern configuration management approach introduced in SD-WAN Manager 20.12+. This section covers the implementation of this hierarchical configuration model for Abhavtech.com's SD-WAN deployment, providing enhanced flexibility and operational efficiency compared to traditional device templates.
Configuration Groups Architecture¶
Hierarchical Structure¶
+------------------------------------------------------------------+
| Configuration Groups Hierarchy |
+------------------------------------------------------------------+
| |
| +----------------------------------------------------------+ |
| | Configuration Groups | |
| | (Top-level container for device types) | |
| +----------------------------------------------------------+ |
| | | | |
| v v v |
| +----------------+ +----------------+ +----------------+ |
| | DC-Hubs-Group | | Branch-Group | | Remote-Group | |
| +----------------+ +----------------+ +----------------+ |
| | | | |
| v v v |
| +----------------------------------------------------------+ |
| | Feature Profiles | |
| | (Reusable configuration building blocks) | |
| +----------------------------------------------------------+ |
| | | |
| | +-------------+ +-------------+ +-------------+ | |
| | | System | | Transport | | Service | | |
| | | Profile | | Profile | | Profile | | |
| | +-------------+ +-------------+ +-------------+ | |
| | | |
| | +-------------+ +-------------+ +-------------+ | |
| | | Policy | | Security | | CLI | | |
| | | Profile | | Profile | | Profile | | |
| | +-------------+ +-------------+ +-------------+ | |
| | | |
| +----------------------------------------------------------+ |
| | |
| v |
| +----------------------------------------------------------+ |
| | Parcels | |
| | (Atomic configuration units within profiles) | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Configuration Groups vs Device Templates¶
| Aspect | Device Templates | Configuration Groups |
|---|---|---|
| Introduction | Original (17.2+) | Modern (20.12+) |
| Structure | Flat, monolithic | Hierarchical, modular |
| Flexibility | Limited inheritance | Full profile sharing |
| Variable Scope | Per-device only | Group, profile, device levels |
| Partial Updates | Full push required | Incremental changes |
| Multi-tenancy | Complex | Native support |
| Recommended For | Legacy, simple deployments | New deployments, scale |
Configuration Groups Design¶
Abhavtech.com Configuration Groups¶
+------------------------------------------------------------------+
| Abhavtech Configuration Groups Layout |
+------------------------------------------------------------------+
ABVT-DC-Hubs-CG
├── Description: DC and Regional Hub Routers
├── Device Models: C8500-12X4QC, C8300-2N2S-6T
├── Sites: Mumbai DC, Chennai DC, London, Frankfurt, NJ, Dallas
├── Feature Profiles:
│ ├── System: ABVT-System-Hub-Profile
│ ├── Transport: ABVT-Transport-MultiWAN-Profile
│ ├── Service: ABVT-Service-Full-Profile
│ ├── Policy: ABVT-Policy-Hub-Profile
│ ├── Security: ABVT-Security-Hub-Profile
│ └── CLI: ABVT-CLI-Hub-Profile
└── Associated Devices: 12 (2 per hub site)
ABVT-India-Branches-CG
├── Description: India Branch Office Routers
├── Device Models: C8300-1N1S-6T
├── Sites: Bangalore, Delhi, Noida
├── Feature Profiles:
│ ├── System: ABVT-System-Branch-Profile
│ ├── Transport: ABVT-Transport-DIA-LTE-Profile
│ ├── Service: ABVT-Service-Branch-Profile
│ ├── Policy: ABVT-Policy-Branch-Profile
│ └── Security: ABVT-Security-Branch-Profile
└── Associated Devices: 3 (1 per branch)
ABVT-EMEA-Hubs-CG
├── Description: EMEA Regional Hub Routers
├── Device Models: C8300-2N2S-6T
├── Sites: London, Frankfurt
├── Feature Profiles:
│ ├── System: ABVT-System-Hub-Profile
│ ├── Transport: ABVT-Transport-MultiWAN-Profile
│ ├── Service: ABVT-Service-Full-Profile
│ └── Security: ABVT-Security-Hub-Profile
└── Associated Devices: 4 (2 per hub)
ABVT-Americas-Hubs-CG
├── Description: Americas Regional Hub Routers
├── Device Models: C8300-2N2S-6T
├── Sites: New Jersey, Dallas
├── Feature Profiles:
│ ├── System: ABVT-System-Hub-Profile
│ ├── Transport: ABVT-Transport-MultiWAN-Profile
│ ├── Service: ABVT-Service-Full-Profile
│ └── Security: ABVT-Security-Hub-Profile
└── Associated Devices: 4 (2 per hub)
+------------------------------------------------------------------+
Creating Configuration Groups¶
Via SD-WAN Manager GUI¶
SD-WAN Manager → Configuration → Configuration Groups
Step 1: Create Configuration Group
- Name: ABVT-DC-Hubs-CG
- Description: DC and Regional Hub Routers for Abhavtech
- Solution Type: SD-WAN
- Device Models:
- C8500-12X4QC
- C8300-2N2S-6T
Step 2: Associate Feature Profiles
- System Profile: ABVT-System-Hub-Profile
- Transport Profile: ABVT-Transport-MultiWAN-Profile
- Service Profile: ABVT-Service-Full-Profile
- Policy Profile: ABVT-Policy-Hub-Profile
- Security Profile: ABVT-Security-Hub-Profile
- CLI Profile: ABVT-CLI-Hub-Profile (optional)
Step 3: Define Group Variables
- Organization: Abhavtech
- vBond: sdwan-validator.abhavtech.com
- DNS Primary: 10.10.100.10
- NTP Server: 10.10.100.10
- Syslog Server: 10.10.60.50
Step 4: Associate Devices
- Add devices from inventory
- Map device-specific variables
Via API¶
#!/usr/bin/env python3
"""
Create Configuration Groups via API
File: create_config_groups.py
"""
from vmanage_session import VManageSession
import json
VMANAGE_HOST = "10.255.0.10"
def create_configuration_group(vm, group_config):
"""Create a new configuration group"""
url = f"https://{vm.host}/dataservice/v1/config-group"
response = vm.session.post(url, json=group_config)
if response.status_code in [200, 201]:
result = response.json()
print(f"Created config group: {group_config['name']} (ID: {result.get('id')})")
return result
else:
print(f"Failed to create config group: {response.status_code} - {response.text}")
return None
# DC Hubs Configuration Group
DC_HUBS_GROUP = {
"name": "ABVT-DC-Hubs-CG",
"description": "DC and Regional Hub Routers for Abhavtech",
"solution": "sdwan",
"profiles": [
{
"type": "system",
"id": "{{system_profile_id}}"
},
{
"type": "transport",
"id": "{{transport_profile_id}}"
},
{
"type": "service",
"id": "{{service_profile_id}}"
},
{
"type": "policy",
"id": "{{policy_profile_id}}"
},
{
"type": "security",
"id": "{{security_profile_id}}"
}
],
"devices": [
{
"deviceId": "{{device_uuid_1}}",
"variables": {
"system_host_name": "MUM-DC-CORE-01",
"system_system_ip": "10.255.255.103",
"system_site_id": "101"
}
},
{
"deviceId": "{{device_uuid_2}}",
"variables": {
"system_host_name": "MUM-DC-CORE-02",
"system_system_ip": "10.255.255.104",
"system_site_id": "101"
}
}
]
}
# Branch Configuration Group
BRANCH_GROUP = {
"name": "ABVT-India-Branches-CG",
"description": "India Branch Office Routers",
"solution": "sdwan",
"profiles": [
{
"type": "system",
"id": "{{system_branch_profile_id}}"
},
{
"type": "transport",
"id": "{{transport_branch_profile_id}}"
},
{
"type": "service",
"id": "{{service_branch_profile_id}}"
},
{
"type": "security",
"id": "{{security_branch_profile_id}}"
}
]
}
if __name__ == "__main__":
vm = VManageSession(VMANAGE_HOST, "admin", "Admin123!")
# Create configuration groups
create_configuration_group(vm, DC_HUBS_GROUP)
create_configuration_group(vm, BRANCH_GROUP)
Feature Profiles¶
Profile Types¶
| Profile Type | Purpose | Contents |
|---|---|---|
| System | Device identity, management | Hostname, system IP, AAA, logging, SNMP |
| Transport | WAN connectivity | VPN 0 interfaces, tunnels, colors |
| Service | Business services | Service VPNs (1-65534), LAN interfaces |
| Policy | Traffic engineering | AAR, QoS, data/control policies |
| Security | Protection features | ZBFW, IPS, URL filtering |
| CLI | Custom configuration | Free-form CLI additions |
System Profile¶
Profile Name: ABVT-System-Hub-Profile
Profile Type: System
Description: System configuration for hub routers
+------------------------------------------------------------------+
| System Profile Parcels |
+------------------------------------------------------------------+
Basic Parcel:
├── Organization Name: Abhavtech
├── vBond: sdwan-validator.abhavtech.com
├── Hostname: {{system_host_name}}
├── System IP: {{system_system_ip}}
├── Site ID: {{system_site_id}}
├── Timezone: Asia/Kolkata
├── Console Baud Rate: 115200
└── Idle Timeout: 30 minutes
AAA Parcel:
├── Authentication Order: RADIUS, Local
├── RADIUS Server Group: ISE-SERVERS
│ ├── Server 1: 10.10.50.21 (Priority 1)
│ └── Server 2: 10.10.50.22 (Priority 2)
├── Timeout: 5 seconds
├── Retransmit: 3
├── Source Interface: Loopback0
└── Local Users:
├── admin (privilege 15)
└── readonly (privilege 1)
Logging Parcel:
├── Syslog Server 1: 10.10.60.50
├── Syslog Server 2: 10.10.60.51
├── VPN: 512
├── Source Interface: Loopback0
├── Priority: informational
└── Disk Enable: Yes (100MB, 10 rotations)
NTP Parcel:
├── Server 1: 10.10.100.10 (prefer)
├── Server 2: 10.10.100.11
├── VPN: 512
├── Source Interface: Loopback0
└── Authentication: MD5 (Key ID 1)
SNMP Parcel:
├── Contact: noc@abhavtech.com
├── Location: {{site_location}}
├── SNMP v3 User: sdwan-monitor
├── Auth: SHA / {{snmp_auth_pass}}
├── Priv: AES-256 / {{snmp_priv_pass}}
└── Trap Target: 10.10.60.55 (VPN 512)
Banner Parcel:
├── Login: [Authorized Access Warning]
└── MOTD: [Device Info Display]
+------------------------------------------------------------------+
Transport Profile (Multi-WAN)¶
Profile Name: ABVT-Transport-MultiWAN-Profile
Profile Type: Transport
Description: Multi-WAN transport for hub routers (MPLS + Internet + LTE)
+------------------------------------------------------------------+
| Transport Profile Parcels |
+------------------------------------------------------------------+
VPN 0 Basic Parcel:
├── VPN ID: 0
├── VPN Name: Transport
├── DNS Primary: 10.10.100.10
├── DNS Secondary: 10.10.100.11
└── Enhanced App Routing: Enabled
MPLS Interface Parcel:
├── Interface: {{transport_mpls_interface}}
├── Description: MPLS-WAN-Transport
├── IP Address: {{transport_mpls_ip}}/{{transport_mpls_mask}}
├── Gateway: {{transport_mpls_gateway}}
├── Bandwidth: {{transport_mpls_bandwidth_kbps}}
├── MTU: 1500
├── Tunnel Interface:
│ ├── Color: mpls
│ ├── Restrict: No
│ ├── Encapsulation: IPsec (prefer), GRE
│ ├── Hello Interval: 1000ms
│ ├── Hello Tolerance: 12
│ ├── TLOC Preference: 200
│ └── Weight: 1
└── Allow Services: DHCP, DNS, ICMP, SSH, HTTPS, SNMP, BFD, NTP, STUN
Internet Interface Parcel:
├── Interface: {{transport_inet_interface}}
├── Description: Internet-DIA-Transport
├── IP Address: DHCP (or {{transport_inet_ip}})
├── NAT: Enabled
├── Bandwidth: {{transport_inet_bandwidth_kbps}}
├── Tunnel Interface:
│ ├── Color: biz-internet
│ ├── Encapsulation: IPsec
│ ├── TLOC Preference: 100
│ └── Weight: 1
└── Allow Services: DHCP, DNS, ICMP, BFD, STUN
LTE Interface Parcel:
├── Interface: Cellular0/1/0
├── Description: LTE-Backup-Transport
├── Profile ID: 1
├── APN: {{transport_lte_apn}}
├── IP Negotiated: Yes
├── Tunnel Interface:
│ ├── Color: lte
│ ├── Last Resort Circuit: Yes
│ ├── Low Bandwidth Link: Yes
│ ├── TLOC Preference: 50
│ ├── Max Control Connections: 2
│ └── Weight: 1
└── Allow Services: DHCP, DNS, ICMP, BFD, STUN
Static Route Parcel:
├── Default Route via MPLS: 0.0.0.0/0 → {{transport_mpls_gateway}}
├── Default Route via Internet: 0.0.0.0/0 → {{transport_inet_gateway}}
└── Management Routes: 10.255.0.0/24 → VPN 512
+------------------------------------------------------------------+
Service Profile (Full Services)¶
Profile Name: ABVT-Service-Full-Profile
Profile Type: Service
Description: Full service VPN configuration for hub sites
+------------------------------------------------------------------+
| Service Profile Parcels |
+------------------------------------------------------------------+
VPN 10 - Corporate Data:
├── VPN ID: 10
├── VPN Name: Corporate-Data
├── OMP Admin Distance: 251
├── ECMP: Enabled
├── DNS: 10.10.100.10, 10.10.100.11
├── Interface Parcel:
│ ├── Subinterface: {{service_vpn10_interface}}.10
│ ├── VLAN: 10
│ ├── Description: SD-Access-Handoff-Corporate
│ ├── IP: {{service_vpn10_ip}}/30
│ └── CTS Role-Based Enforcement: Enabled
├── BGP Parcel:
│ ├── Local AS: 65100
│ ├── Router ID: {{system_system_ip}}
│ ├── Neighbor 1: {{service_vpn10_bgp_neighbor1}} (AS 65200)
│ └── Neighbor 2: {{service_vpn10_bgp_neighbor2}} (AS 65200)
└── Static Routes: 10.10.0.0/16 → Aggregate
VPN 20 - Guest Network:
├── VPN ID: 20
├── VPN Name: Guest-Network
├── OMP Admin Distance: 251
├── DIA: Enabled (NAT to VPN 0 Internet)
├── DNS: 8.8.8.8, 8.8.4.4 (Public)
├── Interface Parcel:
│ ├── Subinterface: {{service_vpn20_interface}}.20
│ ├── VLAN: 20
│ └── IP: {{service_vpn20_ip}}/24
└── Note: Isolated - No route leaking
VPN 30 - Voice/UC:
├── VPN ID: 30
├── VPN Name: Voice-UC
├── OMP Admin Distance: 251
├── ECMP: Enabled
├── Interface Parcel:
│ ├── Subinterface: {{service_vpn30_interface}}.30
│ ├── VLAN: 30
│ ├── IP: {{service_vpn30_ip}}/30
│ └── CTS Role-Based Enforcement: Enabled
├── BGP Parcel:
│ └── Neighbors: Same as VPN 10
└── QoS: Voice priority queue
VPN 40 - IoT/OT:
├── VPN ID: 40
├── VPN Name: IoT-OT
├── OMP Admin Distance: 251
├── Interface Parcel:
│ ├── Subinterface: {{service_vpn40_interface}}.40
│ ├── VLAN: 40
│ └── IP: {{service_vpn40_ip}}/24
├── Route Leaking: To VPN 50 only
└── Security: Enhanced ZBFW inspection
VPN 50 - Shared Services:
├── VPN ID: 50
├── VPN Name: Shared-Services
├── OMP Admin Distance: 251
├── Interface Parcel:
│ ├── Subinterface: {{service_vpn50_interface}}.50
│ ├── VLAN: 50
│ └── IP: {{service_vpn50_ip}}/24
├── Route Import: VPN 10, 30, 40
└── Route Export: To VPN 10, 30, 40
VPN 512 - Management:
├── VPN ID: 512
├── VPN Name: Management
├── Interface Parcel:
│ ├── Interface: GigabitEthernet0
│ ├── IP: {{mgmt_ip}}/24
│ └── Gateway: {{mgmt_gateway}}
└── DNS: 10.10.100.10, 10.10.100.11
+------------------------------------------------------------------+
Security Profile¶
Profile Name: ABVT-Security-Hub-Profile
Profile Type: Security
Description: Security configuration for hub routers
+------------------------------------------------------------------+
| Security Profile Parcels |
+------------------------------------------------------------------+
Zone-Based Firewall Parcel:
├── Zones:
│ ├── TRUST (VPN 10, 30, 50)
│ ├── UNTRUST (VPN 0)
│ ├── GUEST (VPN 20)
│ ├── IOT (VPN 40)
│ └── SELF (Router)
├── Zone Pairs:
│ ├── TRUST → UNTRUST: Inspect
│ ├── TRUST → GUEST: Deny
│ ├── TRUST → IOT: Limited
│ ├── IOT → TRUST: Deny
│ ├── GUEST → UNTRUST: Allow (DIA)
│ └── * → SELF: Control Traffic Only
└── Default Action: Drop
Application Firewall Parcel:
├── Policy: Hub-AppFW-Policy
├── Rules:
│ ├── Allow: ms-office-365, webex, salesforce
│ ├── Block: bittorrent, tor, anonymous-proxy
│ └── Log: All blocked applications
└── Default: Allow (with logging)
IPS/IDS Parcel:
├── Mode: IPS (inline blocking)
├── Signature Set: Cisco Talos
├── Update Frequency: Daily
├── Actions:
│ ├── Critical: Block + Alert
│ ├── High: Block + Alert
│ ├── Medium: Alert Only
│ └── Low: Log Only
└── Exclusions: Known false positives
URL Filtering Parcel:
├── Mode: Block
├── Categories Blocked:
│ ├── Malware
│ ├── Phishing
│ ├── Gambling
│ ├── Adult Content
│ └── Cryptomining
├── Allow Override: No
└── Logging: All blocked URLs
Umbrella Integration Parcel:
├── DNS Security: Enabled
├── Umbrella Token: {{umbrella_token}}
├── Registration: Automatic
├── VPNs: 10, 20, 30, 40, 50
└── Block Page: Redirect to Umbrella
TLS Decryption Parcel (Optional):
├── Mode: Enabled for inspection
├── CA Certificate: Internal CA
├── Bypass Categories:
│ ├── Banking/Financial
│ └── Healthcare
└── Log Decrypted Sessions: Yes
+------------------------------------------------------------------+
CLI Profile¶
Profile Name: ABVT-CLI-Hub-Profile
Profile Type: CLI
Description: Additional CLI configuration for hub routers
+------------------------------------------------------------------+
| CLI Profile Parcels |
+------------------------------------------------------------------+
BGP Advanced Parcel:
Parcels¶
Parcel Concepts¶
Parcels are the atomic configuration units within feature profiles:
+------------------------------------------------------------------+
| Parcel Architecture |
+------------------------------------------------------------------+
Feature Profile (e.g., Transport)
│
├── Parcel 1: VPN 0 Basic
│ ├── VPN ID
│ ├── VPN Name
│ └── DNS Settings
│
├── Parcel 2: MPLS Interface
│ ├── Interface Name
│ ├── IP Configuration
│ ├── Tunnel Settings
│ └── Allow Services
│
├── Parcel 3: Internet Interface
│ ├── Interface Name
│ ├── IP Configuration
│ ├── NAT Settings
│ └── Tunnel Settings
│
├── Parcel 4: LTE Interface
│ ├── Cellular Profile
│ ├── APN Settings
│ └── Tunnel Settings
│
└── Parcel 5: Static Routes
├── Default Routes
└── Management Routes
+------------------------------------------------------------------+
Creating Parcels via API¶
#!/usr/bin/env python3
"""
Create Feature Profile Parcels via API
File: create_parcels.py
"""
from vmanage_session import VManageSession
import json
VMANAGE_HOST = "10.255.0.10"
# System Basic Parcel
SYSTEM_BASIC_PARCEL = {
"name": "ABVT-System-Basic",
"description": "Basic system settings for Abhavtech",
"data": {
"timezone": {
"optionType": "global",
"value": "Asia/Kolkata"
},
"hostname": {
"optionType": "variable",
"value": "{{system_host_name}}"
},
"systemIp": {
"optionType": "variable",
"value": "{{system_system_ip}}"
},
"siteId": {
"optionType": "variable",
"value": "{{system_site_id}}"
},
"organizationName": {
"optionType": "global",
"value": "Abhavtech"
},
"vBond": {
"optionType": "global",
"value": "sdwan-validator.abhavtech.com"
},
"idleTimeout": {
"optionType": "global",
"value": 30
},
"consoleBaudRate": {
"optionType": "global",
"value": "115200"
}
}
}
# AAA Parcel
AAA_PARCEL = {
"name": "ABVT-AAA-ISE",
"description": "AAA configuration with ISE RADIUS",
"data": {
"authenticationOrder": {
"optionType": "global",
"value": ["server", "local"]
},
"radiusServers": [
{
"address": {
"optionType": "global",
"value": "10.10.50.21"
},
"key": {
"optionType": "variable",
"value": "{{radius_secret}}"
},
"priority": {
"optionType": "global",
"value": 1
}
},
{
"address": {
"optionType": "global",
"value": "10.10.50.22"
},
"key": {
"optionType": "variable",
"value": "{{radius_secret}}"
},
"priority": {
"optionType": "global",
"value": 2
}
}
],
"timeout": {
"optionType": "global",
"value": 5
},
"retransmit": {
"optionType": "global",
"value": 3
}
}
}
# Transport MPLS Interface Parcel
TRANSPORT_MPLS_PARCEL = {
"name": "ABVT-Transport-MPLS",
"description": "MPLS WAN transport interface",
"data": {
"interfaceName": {
"optionType": "variable",
"value": "{{transport_mpls_interface}}"
},
"description": {
"optionType": "global",
"value": "MPLS-WAN-Transport"
},
"ipAddress": {
"optionType": "variable",
"value": "{{transport_mpls_ip}}"
},
"subnetMask": {
"optionType": "variable",
"value": "{{transport_mpls_mask}}"
},
"tunnelInterface": {
"color": {
"optionType": "global",
"value": "mpls"
},
"encapsulation": [
{
"type": "ipsec",
"preference": 100
},
{
"type": "gre",
"preference": 50
}
],
"helloInterval": {
"optionType": "global",
"value": 1000
},
"helloTolerance": {
"optionType": "global",
"value": 12
},
"tlocPreference": {
"optionType": "global",
"value": 200
}
},
"allowService": {
"dhcp": True,
"dns": True,
"icmp": True,
"ssh": True,
"https": True,
"snmp": True,
"bfd": True,
"ntp": True,
"stun": True
}
}
}
def create_parcel(vm, profile_id, parcel_type, parcel_def):
"""Create a parcel within a feature profile"""
url = f"https://{vm.host}/dataservice/v1/feature-profile/{profile_id}/parcel/{parcel_type}"
response = vm.session.post(url, json=parcel_def)
if response.status_code in [200, 201]:
result = response.json()
print(f"Created parcel: {parcel_def['name']} (ID: {result.get('parcelId')})")
return result
else:
print(f"Failed to create parcel: {response.status_code} - {response.text}")
return None
if __name__ == "__main__":
vm = VManageSession(VMANAGE_HOST, "admin", "Admin123!")
# Assume system profile ID is known
system_profile_id = "profile-id-here"
# Create parcels
create_parcel(vm, system_profile_id, "system/basic", SYSTEM_BASIC_PARCEL)
create_parcel(vm, system_profile_id, "system/aaa", AAA_PARCEL)
Variables Management¶
Variable Hierarchy¶
+------------------------------------------------------------------+
| Variable Hierarchy Levels |
+------------------------------------------------------------------+
Level 1: Global Variables (Organization-wide)
├── organization_name: Abhavtech
├── vbond_address: sdwan-validator.abhavtech.com
├── dns_primary: 10.10.100.10
├── ntp_server: 10.10.100.10
└── syslog_server: 10.10.60.50
Level 2: Configuration Group Variables (Device Type)
├── DC-Hubs-CG:
│ ├── role: hub
│ ├── omp_advertise: aggregate
│ └── security_level: high
├── Branch-CG:
│ ├── role: spoke
│ ├── omp_advertise: connected
│ └── security_level: standard
└── EMEA-Hubs-CG:
├── role: regional_hub
└── timezone: Europe/London
Level 3: Profile Variables (Feature-specific)
├── Transport Profile:
│ ├── mpls_color: mpls
│ ├── inet_color: biz-internet
│ └── lte_color: lte
├── Service Profile:
│ ├── vpn10_name: Corporate-Data
│ ├── vpn20_name: Guest-Network
│ └── vpn30_name: Voice-UC
└── Security Profile:
├── zbfw_default_action: drop
└── ips_mode: inline
Level 4: Device Variables (Device-specific)
├── MUM-DC-CORE-01:
│ ├── system_host_name: MUM-DC-CORE-01
│ ├── system_system_ip: 10.255.255.103
│ ├── system_site_id: 101
│ ├── transport_mpls_ip: 172.16.101.2
│ └── service_vpn10_ip: 10.101.10.1
└── BLR-BR-WAN-01:
├── system_host_name: BLR-BR-WAN-01
├── system_system_ip: 10.255.255.121
├── system_site_id: 201
└── service_vpn10_ip: 10.201.10.1
+------------------------------------------------------------------+
Variable Definitions Export/Import¶
#!/usr/bin/env python3
"""
Export/Import variable definitions for Configuration Groups
File: manage_variables.py
"""
from vmanage_session import VManageSession
import json
import csv
VMANAGE_HOST = "10.255.0.10"
def export_variables(vm, config_group_id, output_file):
"""Export variables from configuration group to CSV"""
url = f"https://{vm.host}/dataservice/v1/config-group/{config_group_id}/device/variables"
response = vm.session.get(url)
if response.status_code == 200:
variables = response.json()
# Get all variable names
all_vars = set()
for device in variables.get('data', []):
all_vars.update(device.get('variables', {}).keys())
# Write to CSV
with open(output_file, 'w', newline='') as f:
writer = csv.writer(f)
header = ['device_id', 'hostname'] + sorted(list(all_vars))
writer.writerow(header)
for device in variables.get('data', []):
row = [device['deviceId'], device.get('hostname', 'Unknown')]
for var in sorted(list(all_vars)):
row.append(device.get('variables', {}).get(var, ''))
writer.writerow(row)
print(f"Exported {len(variables.get('data', []))} devices to {output_file}")
return True
return False
def import_variables(vm, config_group_id, input_file):
"""Import variables from CSV to configuration group"""
devices = []
with open(input_file, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
device_id = row.pop('device_id')
row.pop('hostname', None)
devices.append({
"deviceId": device_id,
"variables": {k: v for k, v in row.items() if v}
})
url = f"https://{vm.host}/dataservice/v1/config-group/{config_group_id}/device/variables"
response = vm.session.put(url, json={"devices": devices})
if response.status_code == 200:
print(f"Imported variables for {len(devices)} devices")
return True
else:
print(f"Import failed: {response.text}")
return False
if __name__ == "__main__":
vm = VManageSession(VMANAGE_HOST, "admin", "Admin123!")
config_group_id = "config-group-id-here"
# Export current variables
export_variables(vm, config_group_id, "dc_hubs_variables.csv")
# Import updated variables
# import_variables(vm, config_group_id, "dc_hubs_variables_updated.csv")
Deployment Operations¶
Deploy Configuration Group¶
#!/usr/bin/env python3
"""
Deploy Configuration Group to devices
File: deploy_config_group.py
"""
from vmanage_session import VManageSession
import time
VMANAGE_HOST = "10.255.0.10"
def deploy_config_group(vm, config_group_id, device_ids=None):
"""Deploy configuration group to devices"""
url = f"https://{vm.host}/dataservice/v1/config-group/{config_group_id}/device/deploy"
payload = {}
if device_ids:
payload["devices"] = device_ids
response = vm.session.post(url, json=payload)
if response.status_code == 200:
result = response.json()
action_id = result.get('id')
print(f"Deployment initiated: {action_id}")
return wait_for_deployment(vm, action_id)
else:
print(f"Deployment failed: {response.text}")
return False
def wait_for_deployment(vm, action_id, timeout=600):
"""Wait for deployment to complete"""
start = time.time()
while time.time() - start < timeout:
url = f"https://{vm.host}/dataservice/device/action/status/{action_id}"
response = vm.session.get(url)
if response.status_code == 200:
status = response.json()
summary = status.get('summary', {})
print(f"Status: {summary.get('status')} - "
f"Success: {summary.get('count', {}).get('success', 0)} - "
f"Failed: {summary.get('count', {}).get('failure', 0)}")
if summary.get('status') == 'done':
return True
elif summary.get('status') == 'failed':
print("Deployment failed - check device logs")
return False
time.sleep(15)
print("Deployment timed out")
return False
def preview_deployment(vm, config_group_id, device_id):
"""Preview configuration changes before deployment"""
url = f"https://{vm.host}/dataservice/v1/config-group/{config_group_id}/device/{device_id}/config/preview"
response = vm.session.get(url)
if response.status_code == 200:
preview = response.json()
print("Configuration Preview:")
print(preview.get('config', 'No config available'))
return preview
return None
if __name__ == "__main__":
vm = VManageSession(VMANAGE_HOST, "admin", "Admin123!")
config_group_id = "config-group-id-here"
# Preview first
preview_deployment(vm, config_group_id, "device-uuid-here")
# Deploy to all devices in group
deploy_config_group(vm, config_group_id)
# Or deploy to specific devices
# deploy_config_group(vm, config_group_id, ["device-uuid-1", "device-uuid-2"])
Configuration Group Status Monitoring¶
#!/usr/bin/env python3
"""
Monitor Configuration Group deployment status
File: monitor_config_groups.py
"""
from vmanage_session import VManageSession
from datetime import datetime
VMANAGE_HOST = "10.255.0.10"
def get_config_group_status(vm):
"""Get status of all configuration groups"""
url = f"https://{vm.host}/dataservice/v1/config-group"
response = vm.session.get(url)
if response.status_code != 200:
return None
groups = response.json().get('data', [])
report = {
"timestamp": datetime.now().isoformat(),
"groups": []
}
for group in groups:
group_info = {
"name": group.get('name'),
"id": group.get('id'),
"device_count": group.get('deviceCount', 0),
"profiles": [p.get('type') for p in group.get('profiles', [])]
}
# Get device status for this group
devices_url = f"https://{vm.host}/dataservice/v1/config-group/{group['id']}/device"
devices_response = vm.session.get(devices_url)
if devices_response.status_code == 200:
devices = devices_response.json().get('data', [])
group_info['devices'] = []
in_sync = 0
out_of_sync = 0
for device in devices:
status = device.get('configStatus', 'unknown')
if status == 'In Sync':
in_sync += 1
else:
out_of_sync += 1
group_info['devices'].append({
"hostname": device.get('hostname'),
"system_ip": device.get('systemIp'),
"status": status
})
group_info['in_sync'] = in_sync
group_info['out_of_sync'] = out_of_sync
report['groups'].append(group_info)
return report
def print_status_report(report):
"""Print formatted status report"""
print("\n" + "="*70)
print(f"Configuration Groups Status - {report['timestamp']}")
print("="*70)
for group in report['groups']:
sync_status = f"✓ {group.get('in_sync', 0)}" if group.get('out_of_sync', 0) == 0 else f"⚠ {group.get('out_of_sync', 0)} out of sync"
print(f"\n{group['name']}")
print(f" Devices: {group['device_count']} | Status: {sync_status}")
print(f" Profiles: {', '.join(group['profiles'])}")
if group.get('out_of_sync', 0) > 0:
print(" Out-of-sync devices:")
for device in group.get('devices', []):
if device['status'] != 'In Sync':
print(f" - {device['hostname']} ({device['status']})")
if __name__ == "__main__":
vm = VManageSession(VMANAGE_HOST, "admin", "Admin123!")
report = get_config_group_status(vm)
if report:
print_status_report(report)
# Save report
with open('config_group_status.json', 'w') as f:
import json
json.dump(report, f, indent=2)
Migration from Device Templates¶
Migration Strategy¶
+------------------------------------------------------------------+
| Device Template to Configuration Group Migration |
+------------------------------------------------------------------+
Phase 1: Inventory Assessment
├── Document existing device templates
├── List all feature templates in use
├── Identify template variables
├── Map devices to templates
└── Timeline: 1 week
Phase 2: Profile Design
├── Create equivalent feature profiles
├── Design parcel structure
├── Define variable hierarchy
├── Create CLI profiles for custom configs
└── Timeline: 2 weeks
Phase 3: Lab Validation
├── Deploy to lab devices
├── Compare generated configs
├── Test all features
├── Validate failover scenarios
└── Timeline: 1 week
Phase 4: Pilot Migration
├── Select 2-3 production devices
├── Schedule maintenance window
├── Migrate one device at a time
├── Validate post-migration
└── Timeline: 1 week
Phase 5: Full Migration
├── Migrate remaining devices by site type
├── Start with branches (lower risk)
├── Then regional hubs
├── Finally DC hubs
└── Timeline: 2-3 weeks
+------------------------------------------------------------------+
Migration Script¶
#!/usr/bin/env python3
"""
Migrate devices from Device Templates to Configuration Groups
File: migrate_to_config_groups.py
"""
from vmanage_session import VManageSession
import json
import time
VMANAGE_HOST = "10.255.0.10"
def get_device_template_config(vm, device_id):
"""Get current device template configuration"""
url = f"https://{vm.host}/dataservice/template/config/attached/{device_id}"
response = vm.session.get(url)
return response.json() if response.status_code == 200 else None
def detach_device_template(vm, device_id):
"""Detach current device template"""
url = f"https://{vm.host}/dataservice/template/config/device/mode/cli"
payload = {
"deviceType": "vedge",
"devices": [{"deviceId": device_id}]
}
response = vm.session.post(url, json=payload)
if response.status_code == 200:
action_id = response.json().get('id')
return wait_for_action(vm, action_id)
return False
def attach_config_group(vm, config_group_id, device_id, variables):
"""Attach device to configuration group"""
# Add device to config group
url = f"https://{vm.host}/dataservice/v1/config-group/{config_group_id}/device"
payload = {
"devices": [{
"deviceId": device_id,
"variables": variables
}]
}
response = vm.session.post(url, json=payload)
if response.status_code == 200:
# Deploy configuration
deploy_url = f"https://{vm.host}/dataservice/v1/config-group/{config_group_id}/device/deploy"
deploy_response = vm.session.post(deploy_url, json={"devices": [device_id]})
if deploy_response.status_code == 200:
action_id = deploy_response.json().get('id')
return wait_for_action(vm, action_id)
return False
def wait_for_action(vm, action_id, timeout=600):
"""Wait for action to complete"""
start = time.time()
while time.time() - start < timeout:
url = f"https://{vm.host}/dataservice/device/action/status/{action_id}"
response = vm.session.get(url)
status = response.json().get('summary', {}).get('status')
if status == 'done':
return True
elif status == 'failed':
return False
time.sleep(15)
return False
def migrate_device(vm, device_id, target_config_group_id, variables):
"""Migrate a single device from template to config group"""
print(f"Migrating device {device_id}...")
# Step 1: Get current config for reference
current_config = get_device_template_config(vm, device_id)
if current_config:
with open(f"backup_{device_id}.json", 'w') as f:
json.dump(current_config, f, indent=2)
print(" ✓ Configuration backed up")
# Step 2: Detach from device template
if detach_device_template(vm, device_id):
print(" ✓ Detached from device template")
else:
print(" ✗ Failed to detach - aborting")
return False
# Step 3: Attach to configuration group
if attach_config_group(vm, target_config_group_id, device_id, variables):
print(" ✓ Attached to configuration group")
return True
else:
print(" ✗ Failed to attach to config group")
return False
if __name__ == "__main__":
vm = VManageSession(VMANAGE_HOST, "admin", "Admin123!")
# Example migration
migrate_device(
vm,
device_id="device-uuid-here",
target_config_group_id="config-group-id-here",
variables={
"system_host_name": "BLR-BR-WAN-01",
"system_system_ip": "10.255.255.121",
"system_site_id": "201"
}
)
Summary¶
Configuration Groups and Feature Profiles provide modern, scalable configuration management for Abhavtech.com:
| Component | Purpose | Abhavtech Implementation |
|---|---|---|
| Configuration Groups | Device type containers | 4 groups (DC Hubs, Branches, EMEA, Americas) |
| System Profile | Device identity | 2 profiles (Hub, Branch) |
| Transport Profile | WAN connectivity | 2 profiles (MultiWAN, DIA-LTE) |
| Service Profile | Business services | 2 profiles (Full, Branch) |
| Security Profile | Protection | 2 profiles (Hub, Branch) |
| CLI Profile | Custom configs | 1 profile (Hub advanced) |
Key benefits over device templates: - Hierarchical variable inheritance - Incremental configuration changes - Better multi-tenancy support - Simplified profile reuse across groups - Improved operational efficiency
Document Control¶
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | December 2025 | Network Architecture Team | Initial release |
Next Section: 5.10 Hub Site Deployment