Document Networks as Code with D2!
Published: 2023-03-27 00:52:08

---
title: Document Networks as Code with D2!
published: true
date: 2023-03-18 09:00:00 UTC
tags: 
canonical_url: https://blog.engyak.co/2023/03/d2-diagramming-networks.html
---

Let's do something a bit more stereotypical when we talk about IT diagramming - building Network Diagrams with D2.

D2's OSS layout engines (Dagre, ELK) are both centered around _hierarchical layouts_, which was a bit part of why we needed to hack D2 to get vSphere diagrams to draw. Here, it quickly becomes our best friend - Network Engineers will arrange just about anything into a tree hierarchy if permitted - and our network topologies reflect that.

First, let's load some stencils! We'll use [Crayon Visio](http://www.visguy.com/2011/08/16/crayon-visio-network-shapes-revisited/) for this exercise. The [Cisco SAFE Architecture Toolkit listed here](https://www.cisco.com/c/en/us/products/visio-stencil-listing.html) is a bit more serious and visually appealing.

If you want to see why I did it, check out this lovely firewall icon:

![Firewall Icon](https://blog.engyak.co/2023/03/dwg/firewall.png)

This is a Visio stencil, so it'll take a bit of work to convert. The `vssx` extension for Microsoft Visio is a Zip-compressed file, and the images are listed under `visio/media`, and convert with transparency using `GIMP` (this is not fun). Drop the exported `png` files (it's a raster image, not a vector) in a folder, in this case `dwg/`.

## Drawing Networks

Let's try it out!

```
 1direction: right
 2Firewall {
 3 icon: dwg/firewall.png
 4}
 5Outside Router {
 6 icon: dwg/router.png
 7}
 8Inside Router {
 9 icon: dwg/router.png
10}
11Inside Router -- Firewall -- Outside Router

```

[

![Simple Network Diagram](https://blog.engyak.co/2023/03/diagram001.png)

](diagram001.png)

Now, let's try a hierarchy (Layer 3 Clos Fabric):

```
 1direction: right
 2AS65533 {
 3 spine-1: "as65533-spine-1" {
 4 icon: "dwg/router.png"
 5 }
 6 spine-2: "as65533-spine-2" {
 7 icon: "dwg/router.png"
 8 }
 9 spine-3: "as65533-spine-3" {
10 icon: "dwg/router.png"
11 }
12 spine-4: "as65533-spine-4" {
13 icon: "dwg/router.png"
14 }
15 leaf-1: "as65533-leaf-1" {
16 icon: "dwg/switch.png"
17 }
18 leaf-2: "as65533-leaf-2" {
19 icon: "dwg/switch.png"
20 }
21 leaf-3: "as65533-leaf-3" {
22 icon: "dwg/switch.png"
23 }
24 leaf-4: "as65533-leaf-4" {
25 icon: "dwg/switch.png"
26 }
27 leaf-5: "as65533-leaf-5" {
28 icon: "dwg/switch.png"
29 }
30 leaf-6: "as65533-leaf-6" {
31 icon: "dwg/switch.png"
32 }
33 spine-1 -- leaf-1: "eth1/1<->eth1/49"
34 spine-1 -- leaf-2: "eth1/2<->eth1/49"
35 spine-1 -- leaf-3: "eth1/3<->eth1/49"
36 spine-1 -- leaf-4: "eth1/4<->eth1/49"
37 spine-1 -- leaf-5: "eth1/5<->eth1/49"
38 spine-1 -- leaf-6: "eth1/6<->eth1/49"
39 spine-2 -- leaf-1: "eth1/1<->eth1/50"
40 spine-2 -- leaf-2: "eth1/2<->eth1/50"
41 spine-2 -- leaf-3: "eth1/3<->eth1/50"
42 spine-2 -- leaf-4: "eth1/4<->eth1/50"
43 spine-2 -- leaf-5: "eth1/5<->eth1/50"
44 spine-2 -- leaf-6: "eth1/6<->eth1/50"
45 spine-3 -- leaf-1: "eth1/1<->eth1/51"
46 spine-3 -- leaf-2: "eth1/2<->eth1/51"
47 spine-3 -- leaf-3: "eth1/3<->eth1/51"
48 spine-3 -- leaf-4: "eth1/4<->eth1/51"
49 spine-3 -- leaf-5: "eth1/5<->eth1/51"
50 spine-3 -- leaf-6: "eth1/6<->eth1/51"
51 spine-4 -- leaf-1: "eth1/1<->eth1/52"
52 spine-4 -- leaf-2: "eth1/2<->eth1/52"
53 spine-4 -- leaf-3: "eth1/3<->eth1/52"
54 spine-4 -- leaf-4: "eth1/4<->eth1/52"
55 spine-4 -- leaf-5: "eth1/5<->eth1/52"
56 spine-4 -- leaf-6: "eth1/6<->eth1/52"
57}

```

[

![D2 Diagram - Clos Fabric](https://blog.engyak.co/2023/03/diagram002.svg)

](diagram002.svg)

Note that I used the `direction: right` directive to make this readable on blog and mobile. `direction: down` and some custom padding would be more appropriate when describing a solution in a Visio/Print-style media.

Let's make this fun, and add externalities:

```
 1direction: right
 2AS65534: {
 3 firewall-cluster-1: "AS65534 Firewall Cluster" {
 4 icon: "dwg/firewall.png"
 5 }
 6}
 7Storage: {
 8 nfs-array-1: "General-Use NFS" {
 9 icon: "dwg/storage.png"
10 }
11 nfs-array-2: "PCI NFS" {
12 icon: "dwg/storage.png"
13 }
14}
15Compute: {
16 vsphere-cluster-1: "General Use vSphere" {
17 icon: "dwg/server-cluster.png"
18 }
19 vsphere-cluster-2: "PCI vSphere" {
20 icon: "dwg/server-cluster.png"
21 }
22}
23AS65534.firewall-cluster-1<->AS65533.leaf-1
24AS65534.firewall-cluster-1<->AS65533.leaf-2
25Storage.nfs-array-1<->AS65533.leaf-3
26Storage.nfs-array-2<->AS65533.leaf-4
27Compute.vsphere-cluster-1<->AS65533.leaf-5
28Compute.vsphere-cluster-1<->AS65533.leaf-6
29Compute.vsphere-cluster-2<->AS65533.leaf-5
30Compute.vsphere-cluster-2<->AS65533.leaf-6

```

[

![D2 Diagram - Clos Fabric with Externalities](https://blog.engyak.co/2023/03/diagram003.svg)

](diagram003_elk.svg)

If you click on the image, it will direct you towards a `ELK` diagram format with `direction: down`.

## Conclusion

The automatic layout settings for D2 require a certain amount of tweaking to get just right, and as a topology gets "full" curating the layout becomes more difficult.

That being said, changing between formats (blog/web to a stricter canvas) only takes a few seconds, as opposed to hours. D2 (as a solution) excels in situations where a topology or solution may be fluid or repeatable, and it doesn't necessarily need to be presentation grade.

Terrastruct's layout engine (TALA) appears to have the highest quality output of the bunch - several `ELK` layouts crashed `go` while executing these examples, and `Dagre` as a layout engine is unmaintained since 2018. TALA does have the potential to routinely deliver presentation-grade solutions, and D2 ships with a variety of "freebie" resources to make it a good end-to-end solution.

D2 also performed exceptionally well with ridiculous large topologies, it's difficult to consume a full second of CPU time with a diagram, and it can run server-side with an API - [Kroki](https://kroki.io) implements one. If automatic documentation is a regular part of business, I'd recommend publishing the stencils to an object store or HTTP server and make it accessible to a system like Kroki - this effectively lets you auto-diagram with no user intervention.