Visualizing Azure Networking using D3js

2024-04-29

A picture worth a thousand words. When you work with a complex networking infrastructure, it would be great to have a bird’s-eye view of it. In this article, I want to discuss how this can be achieved using PowerShell, Jupyter notebooks, and d3js

We are already familiar with the .NET Interactive kernel and Jupyter notebooks. Now, we want to introduce a new tool - d3js. In a few words, it is a powerful visualization framework for JS. Among other features, it can help visualize graph and network structures using a force-aware algorithm. Basically, what we need to do is to build our own graph of dependencies between various networking elements, and then transform this data in such a way that it can be consumed by d3js.

First thing we are going to do is to use the preview version of the PSQuickGraph module, which lets us generate graph structures dynamically.

Install-Module -Name PSQuickGraph -AllowPrerelease -RequiredVersion "2.0.2-alpha"
Import-Module PSQuickGraph -RequiredVersion "2.0.2"

Now we can initialize the graph and collect our networking elements from Azure

$g = New-Graph

# pull necessary data
$vnets = Get-AzVirtualNetwork
$nics = Get-AzNetworkInterface

Next, we need to process our data and build a graph out of it. We basically scan our $vnets and $nics arrays, add their elements as vertices and connect them with directed edges, when they are related: VNETs include Subnets, and NICs are attached to Subnets.

# add vnets and peerings to the graph
$vnets | ForEach-Object {
    $currentVnet = $_
    $vnetVertex = [PSGraph.Model.PSVertex]::new($currentVnet.Id, $currentVnet)
    Add-Vertex -Graph $g -Vertex $vnetVertex
    $currentVnet.Subnets | % {
        $currentSubnet = $_
        $subnetVertex = [PSGraph.Model.PSVertex]::new($currentSubnet.Id, $currentSubnet)
        Add-Edge -Graph $g -From $vnetVertex -To $subnetVertex
    }
}

foreach ($v in $g.Vertices){
    foreach($p in $v.OriginalObject.VirtualNetworkPeerings) {
        foreach ($rvn in $p.RemoteVirtualNetwork) {
            $targetVertex = $g.Vertices.Where({$_.Label -eq $rvn.id})[0]
            Add-Edge -From $v -To $targetVertex -Graph $g
        }
    }
}

# add NICs to the graph
$nics | ForEach-Object {
    $vnetID = $_.IpConfigurations[0].Subnet.Id
    $targetVertex = $g.Vertices.Where({$_.Label -eq $vnetID})[0]
    Add-Edge -Graph $g -From ([PSGraph.Model.PSVertex]::new($_.name, $_)) -To $targetVertex
}

At this point we want to use a bit of JS and D3 magic, to visualize the graph. The JS piece adds a few nice UI features, like a list of elements, so we can search for a specific node in a graph, or highlight a node and other directly connected nodes when clicked.

This is how it looks like:

    You can see the whole thing in a ready-to use jupyter notebook.

    The YouTube player can not be loaded with disabled JavaScript.
    The following video is embedded here:
    https://youtube.com/watch?v=qnWar8mPbfg