๐Ÿงช Testing, CI/CD & Infrastructure as Code

Network Testing, Automation Pipelines & IaC Principles

๐Ÿงช 5.3 Network Simulation & Test Tools

Overview

Network simulation and testing tools allow you to validate network configurations, test automation scripts, and perform regression testing without impacting production networks.

graph TD A["Network Testing Tools"] --> B["Cisco Modeling Labs"] A --> C["pyATS/Genie"] B --> B1["Virtual Topologies"] B --> B2["Device Simulation"] B --> B3["API Access"] C --> C1["Test Framework"] C --> C2["Network Validation"] C --> C3["CLI Parsing"] style A fill:#667eea,stroke:#764ba2,stroke-width:3px,color:#fff style B fill:#66bb6a,stroke:#2e7d32,stroke-width:2px,color:#fff style C fill:#42a5f5,stroke:#1976d2,stroke-width:2px,color:#fff

Cisco Modeling Labs (CML)

๐Ÿ–ฅ๏ธ Virtual Network Simulation Platform

Cisco Modeling Labs (formerly VIRL) provides a virtualized network environment for testing and development.

Key Features

  • Virtual Devices: Routers, switches, firewalls, servers
  • Realistic Topologies: Build complex network scenarios
  • API Access: Automate lab creation and management
  • Breakout Tool: Connect virtual to physical networks

Use Cases

  • Test network configurations before deployment
  • Develop and validate automation scripts
  • Training and certification preparation
  • Proof of concept demonstrations
# CML API Example (Python)
from virl2_client import ClientLibrary

# Connect to CML server
client = ClientLibrary("https://cml-server", "admin", "password", ssl_verify=False)

# Create a lab
lab = client.create_lab("Test Lab")

# Add devices
router1 = lab.create_node("R1", "iosv", 100, 100)
router2 = lab.create_node("R2", "iosv", 300, 100)

# Connect devices
lab.create_link(router1.get_interface_by_label("GigabitEthernet0/1"),
                router2.get_interface_by_label("GigabitEthernet0/1"))

# Start the lab
lab.start()
print(f"Lab started: {lab.title}")

pyATS & Genie

๐Ÿ Python Automated Test System

pyATS is Cisco's Python-based test automation framework, and Genie is its library for network testing and validation.

pyATS Components

Component Purpose
Testbed Define devices and connections
Test Scripts Define test cases
Genie Models Device state parsing
Genie Diff Compare configurations
# pyATS Testbed File (testbed.yaml)
devices:
  router1:
    type: router
    os: iosxe
    credentials:
      default:
        username: admin
        password: cisco123
    connections:
      cli:
        protocol: ssh
        ip: 192.168.1.1
# pyATS Test Script
from genie.testbed import load
from genie.utils.diff import Diff

# Load testbed
testbed = load('testbed.yaml')
device = testbed.devices['router1']
device.connect()

# Learn current state
before = device.learn('interface')

# Make changes (via automation)
# ...

# Learn new state
after = device.learn('interface')

# Compare states
diff = Diff(before, after)
diff.findDiff()
print(diff)

Genie Features

  • Device Models: Parse CLI output into structured data
  • Config Comparison: Detect configuration drift
  • State Validation: Verify expected device states
  • Reusable Libraries: Pre-built parsers for common commands
# Genie Parser Example
from genie.testbed import load

testbed = load('testbed.yaml')
device = testbed.devices['router1']
device.connect()

# Parse 'show interfaces' output
output = device.parse('show interfaces')

# Access structured data
for intf, data in output.items():
    print(f"{intf}: {data['oper_status']}")
graph LR A["Test Script"] --> B["pyATS Framework"] B --> C["Genie Library"] C --> D["Device"] D --> E["Collect State"] E --> F["Parse Output"] F --> G["Validate/Compare"] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style B fill:#fff3e0,stroke:#e65100,stroke-width:2px style C fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px style G fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px

๐Ÿ”„ 5.4 CI/CD Pipeline in Infrastructure Automation

Overview

CI/CD (Continuous Integration/Continuous Deployment) in infrastructure automation enables automated testing, validation, and deployment of network configurations and infrastructure changes.

graph LR A["Code Commit"] --> B["Source Control"] B --> C["CI Build"] C --> D["Automated Tests"] D --> E["Validation"] E --> F["Deploy to Test"] F --> G["Deploy to Prod"] D --> H["Failed"] H --> I["Notify Team"] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style C fill:#fff3e0,stroke:#e65100,stroke-width:2px style D fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px style G fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px style H fill:#ffebee,stroke:#c62828,stroke-width:2px

CI/CD Components for Infrastructure

๐Ÿ”ง Pipeline Components

Component Purpose Tools
Source Control Version control for IaC Git, GitHub, GitLab
CI Server Automate pipeline execution Jenkins, GitLab CI, GitHub Actions
Testing Validate configurations pytest, pyATS, Robot Framework
Linting Check syntax and style yamllint, ansible-lint, tflint
Deployment Apply changes Ansible, Terraform, NSO
Monitoring Track changes and health Grafana, Prometheus, ELK

Infrastructure CI/CD Workflow

๐Ÿ“‹ Typical Pipeline Stages

# .gitlab-ci.yml Example
stages:
  - validate
  - test
  - deploy

validate_syntax:
  stage: validate
  script:
    - yamllint playbooks/
    - ansible-lint playbooks/
    - python -m py_compile scripts/*.py

test_network:
  stage: test
  script:
    - pytest tests/ -v
    - pyats run job test_job.py
  artifacts:
    reports:
      junit: test-results.xml

deploy_to_staging:
  stage: deploy
  script:
    - ansible-playbook -i inventory/staging playbooks/configure_network.yml
  environment:
    name: staging
  only:
    - develop

deploy_to_production:
  stage: deploy
  script:
    - ansible-playbook -i inventory/production playbooks/configure_network.yml
  environment:
    name: production
  only:
    - main
  when: manual

Benefits of CI/CD in Infrastructure

โœ… Key Advantages

  • Automated Testing: Catch errors before production
  • Consistent Deployments: Same process every time
  • Faster Iterations: Quick feedback on changes
  • Version Control: Track all infrastructure changes
  • Rollback Capability: Revert to previous versions
  • Audit Trail: Complete history of who changed what
  • Reduced Risk: Test in staging before production
  • Collaboration: Team reviews via pull requests

Example: Network Configuration Pipeline

๐ŸŒ Automated Network Deployment

# GitHub Actions Workflow (.github/workflows/network-deploy.yml)
name: Network Configuration CI/CD

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'
      
      - name: Install dependencies
        run: |
          pip install ansible ansible-lint yamllint pyats genie
      
      - name: Lint YAML files
        run: yamllint configs/
      
      - name: Lint Ansible playbooks
        run: ansible-lint playbooks/

  test:
    needs: validate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Run pyATS tests
        run: |
          pyats run job tests/network_test_job.py --testbed testbed.yaml

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v2
      
      - name: Deploy to production
        run: |
          ansible-playbook -i inventory/production playbooks/deploy.yml
graph TD A["Developer"] --> B["Commit Code"] B --> C["Git Push"] C --> D["CI Pipeline Triggered"] D --> E["Syntax Validation"] E --> F["Security Scan"] F --> G["Unit Tests"] G --> H["Integration Tests"] H --> I["Deploy to Staging"] I --> J["Smoke Tests"] J --> K["Manual Approval"] K --> L["Deploy to Production"] L --> M["Monitoring"] E --> N["Fail"] F --> N G --> N H --> N J --> N N --> O["Notify Team"] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style L fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px style N fill:#ffebee,stroke:#c62828,stroke-width:2px

๐Ÿ“œ 5.5 Principles of Infrastructure as Code

What is Infrastructure as Code (IaC)?

Infrastructure as Code is the practice of managing and provisioning infrastructure through machine-readable definition files rather than manual configuration or interactive tools.

graph TD A["Infrastructure as Code"] --> B["Declarative"] A --> C["Imperative"] B --> B1["Terraform"] B --> B2["CloudFormation"] B --> B3["Desired State"] C --> C1["Ansible"] C --> C2["Python Scripts"] C --> C3["Step-by-Step"] style A fill:#667eea,stroke:#764ba2,stroke-width:3px,color:#fff style B fill:#66bb6a,stroke:#2e7d32,stroke-width:2px,color:#fff style C fill:#42a5f5,stroke:#1976d2,stroke-width:2px,color:#fff

Core Principles of IaC

๐ŸŽฏ Fundamental Principles

Principle Description Benefit
Version Control Store all code in Git Track changes, rollback, collaboration
Idempotency Same result regardless of runs Safe to re-run, no duplicates
Immutability Replace, don't modify Consistency, predictability
Modularity Reusable components DRY principle, easier maintenance
Testing Validate before deployment Catch errors early
Documentation Code is self-documenting Understand current state

Declarative vs Imperative

๐Ÿ“‹ Two Approaches

# DECLARATIVE (Terraform)
# Define desired state
resource "cisco_interface" "gig0_1" {
  name        = "GigabitEthernet0/1"
  description = "WAN Interface"
  ip_address  = "10.1.1.1"
  subnet_mask = "255.255.255.0"
  enabled     = true
}

# Terraform figures out HOW to achieve this state
# IMPERATIVE (Ansible/Python)
# Define steps to execute
- name: Configure interface
  cisco.ios.ios_config:
    lines:
      - description WAN Interface
      - ip address 10.1.1.1 255.255.255.0
      - no shutdown
    parents: interface GigabitEthernet0/1

# You specify WHAT to do step by step

IaC Tools Comparison

๐Ÿ› ๏ธ Popular Tools

Tool Type Language Best For
Terraform Declarative HCL Multi-cloud infrastructure
Ansible Imperative YAML Configuration management
Python Imperative Python Custom automation
NSO Declarative YANG Network orchestration

IaC Best Practices

โœ… Key Practices

  • Use Version Control: All code in Git with meaningful commits
  • Modularize Code: Break into reusable modules/roles
  • Separate Environments: Dev, staging, production configs
  • Use Variables: Avoid hardcoding values
  • Document Everything: README, comments, inline docs
  • Test Before Deploy: Validate syntax, run tests
  • Implement CI/CD: Automate testing and deployment
  • Store State Securely: Remote backends, encryption
  • Use Peer Reviews: Pull requests for changes
  • Follow Standards: Naming conventions, directory structure

Example: Ansible Network IaC

๐Ÿ“ Network Configuration as Code

# Directory Structure
network-iac/
โ”œโ”€โ”€ inventory/
โ”‚   โ”œโ”€โ”€ production/
โ”‚   โ”‚   โ””โ”€โ”€ hosts.yml
โ”‚   โ””โ”€โ”€ staging/
โ”‚       โ””โ”€โ”€ hosts.yml
โ”œโ”€โ”€ group_vars/
โ”‚   โ”œโ”€โ”€ routers.yml
โ”‚   โ””โ”€โ”€ switches.yml
โ”œโ”€โ”€ roles/
โ”‚   โ”œโ”€โ”€ interfaces/
โ”‚   โ”œโ”€โ”€ routing/
โ”‚   โ””โ”€โ”€ security/
โ””โ”€โ”€ playbooks/
    โ””โ”€โ”€ deploy_network.yml
# group_vars/routers.yml
---
ntp_servers:
  - 10.1.1.1
  - 10.1.1.2

dns_servers:
  - 8.8.8.8
  - 8.8.4.4

logging_server: 10.1.1.100
# roles/interfaces/tasks/main.yml
---
- name: Configure interfaces
  cisco.ios.ios_interfaces:
    config:
      - name: "{{ item.name }}"
        description: "{{ item.description }}"
        enabled: "{{ item.enabled | default(true) }}"
  loop: "{{ interfaces }}"

- name: Configure IP addresses
  cisco.ios.ios_l3_interfaces:
    config:
      - name: "{{ item.name }}"
        ipv4:
          - address: "{{ item.ip }}"
  loop: "{{ interfaces }}"
  when: item.ip is defined
# playbooks/deploy_network.yml
---
- name: Deploy Network Configuration
  hosts: routers
  gather_facts: no
  
  roles:
    - interfaces
    - routing
    - security
  
  tasks:
    - name: Save configuration
      cisco.ios.ios_config:
        save_when: always
graph LR A["IaC Code"] --> B["Version Control"] B --> C["CI/CD Pipeline"] C --> D["Validation"] D --> E["Test Environment"] E --> F["Manual Approval"] F --> G["Production"] G --> H["State Management"] H --> I["Monitoring"] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style B fill:#fff3e0,stroke:#e65100,stroke-width:2px style G fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px

๐Ÿ Interactive Python Interpreter

๐Ÿ’ก How to use:
  • Write Python code in the editor
  • Click "โ–ถ Run Code" to execute
  • Try sample code buttons
๐Ÿ“ Python Code Editor
โšก Console Output
Ready to execute Python code...