Document vSphere as Code with D2!

D2 Logo

In a previous post we tested methods to illustrate documentation as-code with Terrastruct's D2 language.

Documentation is good for infrastructure engineers in a variety of scenarios practically speaking, but we often forget the value of building consumer confidence. This may vary based on culture! My experiences are almost exclusively in the United States! We should advance and protect the profession by providing a visible internal infrastructure, documented in a way that is visually appealing and easy to understand. If we provide this to stakeholders it will help them understand the value of what they're paying for.

Different infrastructure "silos" participate at different levels of documentation with this cause, with networkers focusing primarily on diagrams and avoiding the "why" questions, where systems designers tend to carefully document the use cases and user perspective over detail on functionality. These guiding values indicate where a design priority is made; automating documentation is a powerful tool to shift some of that cognitive load away from an author's strong points to their weak spots. The object of tools like D2 is to eliminate time spent on aligning and formatting diagrams, and allowing an engineer to document more.

The scope of this post will be to produce a code-driven diagram describing my vSphere Lab Infrastructure. In the future, we'll even be able to collect the required information via vSphere's RESTful API; we must lay down a solid foundation first.

vSphere Stencils

Note: VMware is no longer maintaining the design stencils for VVD. The stencils provided are good, but will no longer be maintained by VMware to assist VI Engineers in design and planning their infrastructure deployments.

The Visio Library provided by VMware for infrastructure design is located on TenThirtyAM's GitHub Page, but the version that includes the SVG-formatted icons is located here. D2 natively supports SVG icons, so that's what we want to use.

D2's icon: directive requires a URL to access stencils from - it can be either local or a remote server (HTTP/S) this example will leverage VMware's provided stencil library with some level of workspace setup. Let's extract the stencils provided in into a new folder, e.g.:


Placing the stencils into a separate folder will help keep the clutter under control. There are quite a few icons, and the author was kind enough to label all of them properly for us.

Adding a VVD icon becomes easy, for example:

1Enterprise PKI: {
2  icon: dwg/certificate-server.svg
4Application: {
5  icon: dwg/application.svg
7Application -> Enterprise PKI: Submit Certificate Signing Request

D2 Diagram Example

Documenting a Cluster

Now, vSphere deployments are much more complex. D2 is much more effective with large diagrams, where cultivating careful connector lines has swallowed more time than I'm willing to admit. Here's a way to depict a vSphere cluster with D2 - take note of how the object hierarchy is used to control object placement:

 1vSphere Cluster: {
 2    icon: 'dwg/vmware-cloud.svg'
 3    Compute Nodes: {
 4        icon: 'dwg/site-container.svg'
 5        compute_host_1: {
 6            icon: 'dwg/vm-server.svg'
 7            Attributes: |yaml
 8            Hostnames:
 9                mgt:
10                vmo:
11                vsan:
12            Interfaces:
13                vmhba0: wwn
14                vmk0:
15                vmk1:
16                vmk10:,3
17            |
18        }
19        compute_host_2: {
20            icon: 'dwg/vm-server.svg'
21            Attributes: |yaml
22            Hostnames:
23                mgt:
24                vmo:
25                vsan:
26            Interfaces:
27                vmhba0: wwn
28                vmk0:
29                vmk1:
30                vmk10:,5
31            |
32        }
33        compute_host_3: {
34            icon: 'dwg/vm-server.svg'
35            Attributes: |yaml
36            Hostnames:
37                mgt:
38                vmo:
39                vsan:
40            Interfaces:
41                vmhba0: wwn
42                vmk0:
43                vmk1:
44                vmk10:,7
45            |
46        }
47    }

vSphere Cluster Diagram

Use the --sketch switch to set the formatting depicted here!

In this example, I used a YAML text block to draw everything because it's simpler and more visually appealing. I placed a container in a container to illustrate the text with icons, either by clustering them together or using connectors, e.g.:

 1compute_host_1: {
 2    icon: 'dwg/vm-server.svg'
 4compute_host_1 -> compute_host_1_attributes
 5compute_host_1_attributes: |yaml
 6    Hostnames:
 7        mgt:
 8        vmo:
 9        vsan:
10    Interfaces:
11        vmhba0: wwn
12        vmk0:
13        vmk1:
14        vmk10:,3
15    |

Connector diagram

Connectors are useful with this platform when you want to control the layout of your diagram. Keep in mind that the goal here is to quickly diagram a solution, not necessarily to make it the absolute best.

This solution now describes the compute cluster effectively, but it's not really sufficient to describe, say, a VCF stack. Let's do that:

 1direction: right
 2VMware Cloud Foundation: "VMware Cloud Foundation\nSDDC:\n{{ site }}-{{ stack }}-sddc.{{ domain }}" {
 3  icon: 'dwg/vmware-cloud-foundation.svg'
 4  Management: {
 5    icon: 'dwg/inftrastructure.svg'
 6    vCenters: {
 7        vCenter_1: "vCenter:\n{{ site }}-{{ stack }}-{{ wld }}-vc.{{ domain}}" {
 8            icon: 'dwg/vcenter-server.svg'
 9            Attributes: |yaml
10                version: 8.0patch-b
11                ipv4:
12                ipv6: 4000:20::2/64
13                size: super-duper-x-large
14                compute: {{ clustername }}
15                cpus: 400
16                memory: 4,000 GB
17                disk: 10 PB
18            |
19        }
20    }
21    NSX Managers: {
22        NSX_1: "NSX Mgr:\n{{ site }}-{{ stack }}-{{ wld }}-nsx00.{{ domain }}" {
23            icon: 'dwg/vmware-nsx.svg'
24            Attributes: |yaml
25                version: 4.1.1
26                ipv4:
27                ipv6: 4000:20::96/64
28                size: super-duper-x-large
29                compute: {{ clustername }}
30                cpus: 400
31                memory: 4,000 GB
32                disk: 10 PB
33            |
34        }
35    }
36  }
37  Monitoring: {
38    icon: 'dwg/alert.svg'
39    VROPS: "vROPS:\n{{ site }}-{{ stack }}-{{ wld }}-vrops.{{ domain }}" {
40        icon: 'dwg/vrops.svg'
41            Attributes: |yaml
42                version: 8.0.0
43                ipv4:
44                ipv6: 4000:20::192/64
45                size: super-duper-x-large
46                compute: {{ clustername }}
47                cpus: 400
48                memory: 4,000 GB
49                disk: 10 PB
50            |
51    }
52    VRLI: "vRLI:\n{{ site }}-{{ stack }}-{{ wld }}-vrli.{{ domain }}" {
53        icon: 'dwg/vmware-vrealize-log-insight.svg'
54            Attributes: |yaml
55                version: 8.0.0
56                ipv4:
57                ipv6: 4000:20::192/64
58                size: super-duper-x-large
59                compute: {{ clustername }}
60                cpus: 400
61                memory: 4,000 GB
62                disk: 10 PB
63            |
64    }
65    VRNI: "vRNI:\n{{ site }}-{{ stack }}-{{ wld }}-vrni.{{ domain }}" {
66        icon: 'dwg/vmware-vrealize-network-insight.svg'
67            Attributes: |yaml
68                version: 8.0.0
69                ipv4:
70                ipv6: 4000:20::192/64
71                size: super-duper-x-large
72                compute: {{ clustername }}
73                cpus: 400
74                memory: 4,000 GB
75                disk: 10 PB
76            |
77    }
78  }
79  Consumption: {
80    icon: 'dwg/consumption-plane.svg'
81    VRA: "vRA:\n{{ site }}-{{ stack }}-{{ wld }}-vra.{{ domain }}" {
82        icon: 'dwg/vmware-cloud-assembly.svg'
83            Attributes: |yaml
84                how-to-reach: it's SaaS
85            |
86    }
87  }

I formatted this drawing to be optimal for blogging and mobile use, which follows a different convention than for workstations. The directive direction: right instructs D2 to render downwards if we don't provide any connectors. This ensures that eastward expansion is possible as connectors are built. The biggest change here for most of us will be the fact that we must give up a lot of control over layout in exchange for a higher yield per effort. Think of it like Python's black module, any color you like, as long as it's black.

When compiling this diagram, we're also using iconography to help solidify understanding, which creates an issue with padding. To manipulate dagre (the drawing algorithm used here), we can add the switch --dagre-edgesep 40 to request 40 pixels of padding between objects and make it fit cleanly.

VCF SDDC Diagram

Now, let's combine the diagrams by simply putting them in the same file:

SDDC Stack Diagram


It's fascinating to see more opinionated development for automated documentation. In many cases, the primary detractor for maintaining documentation is time. D2 attempts to build something simple and visually appealing that minimizes the effort required to build documentation.

D2 is also really fast, and the generated diagrams are tiny with vector exports. Complex diagrams are drawn in under a second with minimal compute resources - something that can't be said of Visio or Inkscape.

The only major gripe I have with the platform (when I stop wrestling with the fact that I don't have much control) is that the layout engines provided (elk, dagre) don't perform as well as the costware one (tala). This is how Terrastruct is monetizing their product, which makes sense - and the company does provide a great deal of public support for their product without any cost.

My advice if you're using it, like how it looks, but become frustrated with the layout: D2 doesn't lock you into their software in any way. Open the svg in your preferred Graphic editor and tweak it to your liking. This is the big benefit of open source software!

Posts in this Series