Azure

Bicep Diagram Generator — Visualize Azure Bicep & ARM Templates Instantly

By Raghvendra Pandey · May 2026 · 7 min read

Bicep is Azure's answer to readable infrastructure code — a domain-specific language that compiles to ARM JSON. It's far cleaner than the ARM templates it replaces, but it still describes resources as a flat list of declarations linked by symbolic references and dependsOn chains. The Azure portal shows you deployed resources grouped by resource group, not how they connect. Neither view gives you the topology at a glance. This article covers how Bicep and ARM templates map to an architecture diagram, how implicit and explicit dependencies are detected, and how Bicep modules appear.

What the Azure portal doesn't show you

Bicep is Microsoft's domain-specific language for Azure infrastructure. It compiles to ARM JSON and deploys via Azure Resource Manager. A production Bicep template can define dozens of resources — virtual networks, subnets, AKS clusters, API Management gateways, SQL servers, Key Vaults, Service Bus namespaces, and more. Reading that code to understand the topology is slow and error-prone.

ARM JSON is even harder. A 1,000-line azuredeploy.json with nested dependsOn arrays and resourceId() references takes real effort to parse mentally. The Azure portal shows deployed resources but not their relationships. Visio and draw.io require manual box-drawing. There's no free tool that takes your Bicep or ARM code and generates a diagram automatically — until now.

InfraSketch parses Bicep and ARM JSON directly in the browser. No Azure subscription required. No CLI. No compile step. Paste and generate.

How to use it

Open infrasketch.cloud, click the Bicep / ARM tab, paste your template, and click Generate Diagram. InfraSketch auto-detects whether the input is Bicep syntax or ARM JSON — you don't need to switch modes.

// Bicep example — paste this into the Bicep / ARM tab
param location string = 'eastus'

resource vnet 'Microsoft.Network/virtualNetworks@2023-04-01' = {
  name: 'prod-vnet'
  location: location
  properties: {
    addressSpace: { addressPrefixes: ['10.0.0.0/16'] }
  }
}

resource appSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-04-01' = {
  parent: vnet
  name: 'app'
  properties: { addressPrefix: '10.0.1.0/24' }
}

resource aks 'Microsoft.ContainerService/managedClusters@2024-01-01' = {
  name: 'prod-aks'
  location: location
  properties: {
    agentPoolProfiles: [{ name: 'nodepool1', vnetSubnetID: appSubnet.id }]
  }
}

Tip: InfraSketch handles both Bicep and ARM JSON automatically. Paste either format — the tool detects it from the syntax.

What gets visualized

VNet containment

Resources referencing a VNet via virtualNetworkId or parent: vnet are drawn inside the VNet boundary.

Subnet placement

Resources with vnetSubnetID or subnetId references are placed inside the correct subnet lane.

Connection arrows

ARM dependsOn and Bicep .id references between resources become directed arrows on the diagram.

Inline subnets

Subnets defined inside a VNet's properties.subnets array are automatically extracted and rendered.

Supported Azure resource types

InfraSketch maps 40+ Azure resource types from Bicep and ARM templates into diagram nodes with official Microsoft icons:

Resource types not yet in the mapping still parse — they're just omitted from the diagram rather than causing an error. Supported types grow with each release.

Bicep vs ARM JSON — both work

Bicep is the recommended authoring format for new Azure projects. ARM JSON is what Bicep compiles to, and what older templates use. InfraSketch supports both:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks",
      "name": "prod-vnet",
      "apiVersion": "2023-04-01",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": { "addressPrefixes": ["10.0.0.0/16"] },
        "subnets": [{ "name": "app", "properties": { "addressPrefix": "10.0.1.0/24" } }]
      }
    },
    {
      "type": "Microsoft.ContainerService/managedClusters",
      "name": "prod-aks",
      "apiVersion": "2024-01-01",
      "location": "[resourceGroup().location]",
      "dependsOn": ["[resourceId('Microsoft.Network/virtualNetworks', 'prod-vnet')]"],
      "properties": {}
    }
  ]
}

Use cases

Bicep modules and how they diagram

Production Bicep code is rarely a single file. Most teams split resources into reusable modules — a networking.bicep module for VNet and subnets, an aks.bicep module for cluster and node pools, a databases.bicep module for SQL and Redis. The main template calls them with module blocks:

// main.bicep
module network './modules/networking.bicep' = {
  name: 'networkDeployment'
  params: {
    vnetName: 'prod-vnet'
    location: location
  }
}

module cluster './modules/aks.bicep' = {
  name: 'aksDeployment'
  params: {
    clusterName: 'prod-aks'
    subnetId: network.outputs.appSubnetId
    location: location
  }
  dependsOn: [network]
}

module data './modules/databases.bicep' = {
  name: 'dataDeployment'
  params: {
    sqlServerName: 'prod-sql'
    location: location
  }
}

When you paste a modular Bicep setup into InfraSketch, the tool reads what's directly in the pasted code. For best results with modular Bicep, paste the content of each module file concatenated together — the combined resource set gives InfraSketch the full topology to diagram. Alternatively, compile to ARM JSON first (az bicep build --file main.bicep) and paste the resulting ARM template, which contains all resources fully expanded.

Understanding dependsOn vs implicit dependencies

One of the more subtle aspects of Bicep architecture is the difference between implicit and explicit dependencies. Bicep resolves dependencies automatically when you reference a symbolic name:

// Implicit dependency — Bicep knows aks depends on appSubnet
resource aks 'Microsoft.ContainerService/managedClusters@2024-01-01' = {
  properties: {
    agentPoolProfiles: [{
      vnetSubnetID: appSubnet.id  // implicit dependency via .id reference
    }]
  }
}

// Explicit dependency — needed when there's no direct property reference
resource diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  scope: aks
  dependsOn: [logAnalyticsWorkspace]  // explicit: must exist before this
  ...
}

InfraSketch detects both. Implicit .id and .name references become connection arrows on the diagram. Explicit dependsOn also generates arrows. When reviewing a Bicep architecture diagram, arrows represent real deployment order constraints — if you see a long chain of arrows, that's a signal that changes to early resources have a large blast radius affecting everything downstream.

ARM template patterns: nested vs linked deployments

ARM JSON templates have two ways to compose multiple templates: nested deployments (inline within a single file) and linked deployments (separate files referenced by URL). Both patterns appear in enterprise Azure templates, especially in Azure landing zone frameworks.

A nested deployment embeds a child template inside the parent's resources array with "type": "Microsoft.Resources/deployments". InfraSketch parses the top-level resources but doesn't descend into nested template objects — pasting a template with nested deployments gives you a partial view. For full visibility, paste the inner template content separately or use Bicep modules instead, which are cleaner to parse.

Linked deployments reference external template URLs. Since InfraSketch runs in the browser and doesn't fetch external URLs from private storage, linked templates require manual concatenation. If you use the Azure landing zone accelerator, run az deployment sub what-if --template-file main.bicep to see the full resolved resource list, then diagram from that output.

Integrating Bicep diagrams into Azure DevOps CI/CD

Azure teams often use Azure DevOps Pipelines rather than GitHub Actions. While the InfraSketch GitHub Action targets GitHub Pull Requests, the CLI works in any CI environment — including Azure DevOps.

# azure-pipelines.yml — add diagram step to your Bicep pipeline
steps:
- task: NodeTool@0
  inputs:
    versionSpec: '20.x'
  displayName: 'Install Node.js'

- script: |
    # Install InfraSketch CLI
    npm install -g infrasketch

    # Generate diagram URL from the Bicep file
    DIAGRAM_URL=$(infrasketch main.bicep --no-open 2>&1 | grep 'https://')
    echo "##vso[task.setvariable variable=DiagramUrl]$DIAGRAM_URL"
    echo "Diagram: $DIAGRAM_URL"
  displayName: 'Generate architecture diagram'

- task: CreateWorkItem@1
  inputs:
    workItemType: 'Task'
    title: 'Review architecture diagram: $(Build.SourceBranchName)'
    description: 'Diagram URL: $(DiagramUrl)'

The --no-open flag tells the CLI to print the URL to stdout instead of opening a browser — suitable for CI environments. Capture the URL and embed it in a PR comment, a work item, or a pipeline summary artifact.

Security considerations when diagramming Azure infrastructure

Bicep and ARM templates often contain references to Key Vault secrets, subscription IDs, tenant IDs, and resource group names. Before sharing a diagram (or sharing the source code used to generate it), review what's exposed.

InfraSketch processes everything in the browser — your template is never transmitted to any server. The shareable diagram URL encodes the resource structure (not the raw template text) as a compressed URL parameter. If your template contains subscription IDs or tenant IDs in resource property values, those specific values don't appear in the diagram nodes — only the resource type and name are used for diagram rendering.

Still, treat the shareable URL as you would any link containing architectural information — internal architecture reveals attack surface. Share within your organization rather than posting publicly unless the architecture is already documented publicly.

Frequently asked questions

Does InfraSketch support Bicep parameter files?

Bicep parameter files (main.bicepparam) aren't parsed separately. For visualization, the resource structure matters more than specific parameter values. Paste the .bicep file directly — the diagram shows resource types and connections regardless of parameter values.

Can I diagram Azure Policy definitions or RBAC assignments?

Policy definitions and RBAC assignments aren't visualized as architecture nodes — they're governance constructs rather than infrastructure resources. InfraSketch focuses on infrastructure topology: networks, compute, data, messaging, and security resources.

What's the difference between the Bicep and Terraform parsers in InfraSketch?

Both parse resource definitions and extract connections, but the connection detection differs. Bicep uses symbolicName.id references and parent relationships. Terraform uses HCL attribute references like aws_subnet.main.id and module.vpc.subnet_id. The Terraform parser also reads plan JSON for fully resolved dependency graphs. The underlying diagram renderer is the same for both.

How do I diagram an Azure Verified Module (AVM)?

Azure Verified Modules are Bicep registry modules. To diagram one, use the AVM module's Bicep source code if it's public (download from the registry and paste). Or deploy a test instance and run az deployment group what-if to see what resources it creates, then use that as the basis for your diagram.

Bicep vs Terraform diagrams

If your team uses both Terraform (for AWS/GCP) and Bicep (for Azure), InfraSketch handles both in the same tool. Switch between the Terraform and Bicep / ARM tabs to diagram each side of a multi-cloud deployment. The layout zones — Internet, Ingress, Compute, Data, Messaging, Security — are consistent across providers, so diagrams from both tools are comparable at a glance.

Generate your Bicep diagram now

Paste your .bicep file or azuredeploy.json into the Bicep / ARM tab. Free, no login, nothing leaves your browser.

Open InfraSketch →

Related articles