မာတိကာ သို့ သွားရန်

🧪 Lab 01 · Data-Driven Config Generation (Jinja2 & YAML)

Validated on Arista cEOS 4.32.0F & Python 3.11.

Time: ~40 minutes · Tools: Python 3, PyYAML, Jinja2

Quick Start — Step-by-Step Execution Guide (Location: labs/netdevops-lab/)

Step 1 · Deploy the Lab Fabric (if not already running)

cd labs/netdevops-lab
sudo containerlab deploy -t topology.clab.yml --max-workers 1

Step 2 · Launch the Fully Guided Interactive Walkthrough

./run.sh --guided

Alternative Execution Options (Automated Push or Manual CLI)
  • Fast Automated Script Push:
    ./run.sh 01          # apply + verify step 01 automatically
    ./run.sh --all       # run all steps in order
    
  • Manual Line-by-Line CLI Execution: Interactive CLI shell on any container node:
    docker exec -it clab-netdevops-lab-node1 Cli
    

🧠 Technology Deep Dive: Separating Data from Logic

In traditional network engineering, device hostname, IP addresses, and routing parameters are hardcoded directly into vendor CLI strings. If you need to change an OSPF area ID across 100 leaf switches, you have to edit 100 individual configuration files!

In NetDevOps, we separate Data from Templates:

+-------------------+      +-------------------+      +-------------------+
|  DATA MODEL       |      |  JINJA2 TEMPLATE  |      |  RENDERED OUTPUT  |
|  (data/hosts.yaml)| +===>|  (templates/*.j2) | +===>|  (rendered/*.cfg) |
|  Raw IP parameters|      |  CLI Structure    |      |  Valid Vendor CLI |
+-------------------+      +-------------------+      +-------------------+

1. YAML Data Model Breakdown (data/hosts.yaml)

YAML (YAML Ain't Markup Language) stores structured network data using simple key-value pairs (key: value), lists (- item), and nested dictionaries:

fabric:
  name: NetForge-DC1
  asn: 65000
  ospf_area: 0.0.0.0

spines:
  - name: spine1
    mgmt_ip: 172.20.20.31
    router_id: 10.255.0.1
    interfaces:
      - name: Ethernet1
        ip: 10.0.1.1/30
        neighbor: leaf1
  • fabric: Global network variables (ASN 65000, OSPF Area 0.0.0.0).
  • spines: A list (-) of spine router dictionaries containing interface arrays.

2. Jinja2 Template Breakdown (templates/spine.j2)

Jinja2 is a templating engine for Python that dynamically generates text files: - {{ variable }}: Inserts a data value (e.g. {{ node.name }}spine1). - {% for item in list %}: Loops through an array of interfaces.

configure
hostname {{ node.name }}
!
interface Loopback0
   ip address {{ node.router_id }}/32
   ip ospf area {{ fabric.ospf_area }}
!
{% for intf in node.interfaces %}
interface {{ intf.name }}
   no switchport
   ip address {{ intf.ip }}
   ip ospf area {{ fabric.ospf_area }}
!
{% endfor %}

3. Python Rendering Script (scripts/generate_configs.py)

Python reads the YAML file, passes data to Jinja2, and saves the generated .cfg files:

import os, yaml
from jinja2 import Environment, FileSystemLoader

with open("data/hosts.yaml", "r") as f:
    data = yaml.safe_load(f)

env = Environment(loader=FileSystemLoader("templates"))
template = env.get_template("spine.j2")

for spine in data["spines"]:
    rendered = template.render(node=spine, fabric=data["fabric"])
    with open(f"rendered/{spine['name']}.cfg", "w") as f:
        f.write(rendered)

Step 1 · Generate Configurations

Run the Jinja2 generator script to produce device configurations:

cd labs/netdevops-lab
python3 scripts/generate_configs.py
Rendered: labs/netdevops-lab/rendered/spine1.cfg
Rendered: labs/netdevops-lab/rendered/spine2.cfg
Rendered: labs/netdevops-lab/rendered/leaf1.cfg
Rendered: labs/netdevops-lab/rendered/leaf2.cfg
✅ Configuration rendering complete!

Step 2 · Inspect Rendered Output (rendered/spine1.cfg)

Verify that Jinja2 generated a 100% valid EOS configuration:

configure
hostname spine1
!
interface Loopback0
   ip address 10.255.0.1/32
   ip ospf area 0.0.0.0
!
interface Ethernet1
   no switchport
   ip address 10.0.1.1/30
   ip ospf area 0.0.0.0
!
interface Ethernet2
   no switchport
   ip address 10.0.1.5/30
   ip ospf area 0.0.0.0
!
router ospf 100
   router-id 10.255.0.1
   passive-interface Loopback0

DONE when rendered/spine1.cfg contains valid EOS commands generated from hosts.yaml.