If your Bicep project has grown from a “single file” into a small ecosystem of parameters, modules, and outputs—welcome to the club. I also got tired of “parsing dependencies by eye” in the code. That’s why I wrote PSBicepGraph—a PowerShell module that builds a semantic graph from your .bicep files and provides proper tools for analysis and visualization.

What is it and why

PSBicepGraph:

Under the hood—my PSGraph module, a thin wrapper around QuickGraph/QuikGraph with utilities for export and visualization (including Vega).

Current PSBicepGraph version: v1.1.0-beta. The module is published in the PowerShell Gallery.

Installation

Install-Module -Name PSBicepGraph -Repository PSGallery -Scope CurrentUser
Install-Module -Name PSGraph      -Repository PSGallery -Scope CurrentUser

Import-Module PSBicepGraph
Import-Module PSGraph

How it works (short version)

Semantic extraction. New-BicepSemanticGraph registers Bicep services, resolves the path, collects all .bicep files, compiles, and traverses the semantic model with a custom DependencyCollectorVisitor, mapping each declaration to what it references. Graph construction. Based on the dependency map, a PsBidirectionalGraph is created—vertices (declarations) and edges (A→B, where A depends on B). Integration with PSGraph. Then—export the graph as you like: graph image, interactive HTML tree, or DSM for large projects.

Quick start

Let’s create a simple storage.bicep and build a graph:

param location string = resourceGroup().location
var storageName = 'st${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageName
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
}

output accountId string = stg.id
# 1) Build the semantic graph:
$graph = New-BicepSemanticGraph -Path ./storage.bicep

# 2) Export to HTML (MSAGL):
Export-Graph -Graph $graph -Format MSAGL_MDS -Path $Env:TEMP/storage.html
Start-Process $Env:TEMP/storage.html

For a multi-module project:

$graph = New-BicepSemanticGraph -Path ./main.bicep
$dsm   = New-DSM -Graph $graph
$ret   = Start-DSMClustering -Dsm $dsm        # Classic or Graph

Export-DSM -Result $ret -Format VEGA_HTML -Path $Env:TEMP/dsm.html
Start-Process $Env:TEMP/dsm.html

A couple of examples

Let’s look at the avm module as an example.

You can get its Force Directed visualization like this. It does look a bit messy, though.

$graph = New-BicepSemanticGraph -Path "./bicep-registry-modules/avm/res/key-vault/vault/main.bicep"
Export-Graph -Graph $graph -Format Vega_ForceDirected  -Path $outFile

You can look at it from another angle—build a tree with a virtual root. The -UseVirtualTreeRoot parameter adds a virtual root if the graph happens to have more than one root, for visualization.

$graph = New-BicepSemanticGraph -Path "./bicep-registry-modules/avm/res/key-vault/vault/main.bicep"
$visual = Export-Graph -Graph $graph -Format Vega_TreeLayout -UseVirtualTreeRoot 

What is DSM and why is it useful

Design Structure Matrix is a square dependency matrix: rows and columns are the same set of entities; a mark at (i, j) means “row i depends on column j”. In PSBicepGraph/PSGraph, the convention is: row = consumer, column = provider; edge A→B becomes a filled cell (A, B). This compactly shows cycles, layers, and module “coupling”. Clustering groups mutually dependent nodes and hints where to draw boundaries. (DSM algorithms are still in progress—but you can already try them.)

For key vault, unfortunately, it doesn’t fit the layout. So as an example, let’s look at another one, from avm/res/web/serverfarm

$graph = New-BicepSemanticGraph -Path "./bicep-registry-modules/avm/res/web/serverfarm/main.bicep"

$dsm1 = New-DSM -graph $graph
$ret1 = Start-DSMClustering -Dsm $dsm1 -ClusteringAlgorithm Classic
$visual = Export-DSM -Result $ret1 -Format VEGA_JSON 

Horizontally, you see “depends on” dependencies, for example, appServicePlan: Resource depends on a bunch of parameters. Vertically, on the contrary, “depends on me”—various outputs and other resources depend on the same appServicePlan: Resource.

Repository PSBicepGraph (dev). There you’ll find the README with installation, examples, and screenshots. Module PSGraph - export, DSM, Vega.

P.S. If you’ve ever tried to explain a complex Bicep project with “look, here’s a var, here’s a module, and here’s an output,” you know how painful it is. Now, instead of a 30-minute standup—one picture. And you can argue based on facts, not interpretations.

Would love your feedback :D