Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Kamil Marut
Kamil Marut

Posted on • Originally published atkamilmarut.com on

     

Diagrams as Code (DaC) - crafting beautiful diagrams with D2

Cover

We all love diagrams. A quick peek allows us to quickly create a mental map, no matter whether it's cloud architecture, a database schema, or a sequence diagram.
But creating diagrams is hard. It's hard to keep them up to date, it's hard to collaborate on them, and it's hard to make them look good.

There are a lot of tools for creating diagrams, but probably the most popular one isdraw.io. It's a great tool, but it's not without its flaws.
It gives you a lot of freedom, but also bothers you with the little details.

Since we often use diagrams to describe our infrastructure, why don't we learn from the DevOps world and treat them as code?
What if next to our Infrastructure as Code (IaC) we could also have Diagrams as Code (DaC)?

What is D2?

In the words of the creators,D2 is a domain-specific language (DSL) that stands for Declarative Diagramming. Declarative, as in, you describe what you want diagrammed, it generates the image.

In other words, D2 gives you the ability to write diagrams as code, and then use a CLI tool to compile and render them into SVG or PNG images.
The CLI tool supports live reload, so the workflow is nearly as smooth as working with other diagram tools.

Get started with D2

You can install the D2 CLI tools by following the instructions on theD2 website.

After installing the CLI, you should now be good to go. The most important command is:

$ d2 -w input.d2 output.svg
Enter fullscreen modeExit fullscreen mode

This will run a live reload server that will watch for changes in theinput.d2 file and render the output tooutput.svg.
It will also open a browser window with the rendered diagram. For most cases this is all you need, however it is also worth noting
that you can change the theme of the diagram by passing the--theme/-t parameter. This parameter is the ID of the target theme, which is not
showcased in the D2 docs, but you can find a list of all available themes in theD2 repo.

# Renders with the "Shirley temple" theme$ d2 -w input.d2 -t 102 output.svg
Enter fullscreen modeExit fullscreen mode

Creating a diagram with D2

Using D2 to create a diagram is very simple. To present this, we will try to recreate the example AWS architecture diagram fromdraw.io examples.

Example AWS architecture diagram

We start by defining the containers.

aws_1: AWS Cloud {}aws_2: AWS Cloud {}
Enter fullscreen modeExit fullscreen mode

Here,aws_1 andaws_2 are the IDs of the containers. We can then later use those IDs to reference the objects inside (or the containers themselves).

Diagram with defined containers

Next, we define the objects inside the containers (and the nested containers).

aws_1: AWS Cloud {  obj: Object  bucket_1: Bucket  bucket_2: Bucket  subsystem: "" {    cloudwatch: Amazon CloudWatch    cloudtrail: Amazon CloudTrail    sns: Amazon Simple Notification Service    sqs: Amazon Simple Queue Service    lambda: AWS Lambda    kinesis: Amazon Kinesis Data Firehose    dynamo: Amazon DynamoDB  }}aws_2: AWS Cloud {  bucket: Bucket  subsystem: "" {    cloudwatch: Amazon CloudWatch    cloudtrail: Amazon CloudTrail  }}
Enter fullscreen modeExit fullscreen mode

Diagram with defined objects

We have defined all the objects inside the containers. Now we can make the connections between them.
This is by far the part that is most troublesome when using traditional diagram tools, since with each update of the diagram you have to make sure
that the connections are still clear and correct. In D2, this is a breeze.

aws_1.bucket_1 -> aws_2.bucketaws_2.subsystem.cloudwatch -> aws_1.subsystem.cloudwatch: Monitor templateaws_1: AWS Cloud {  obj: Object  bucket_1: Bucket  bucket_2: Bucket  obj -> bucket_1  bucket_1 -> subsystem.cloudtrail  subsystem.kinesis -> bucket_2  subsystem: "" {    cloudwatch: Amazon CloudWatch    cloudtrail: Amazon CloudTrail    sns: Amazon Simple Notification Service    sqs: Amazon Simple Queue Service    lambda: AWS Lambda    kinesis: Amazon Kinesis Data Firehose    dynamo: Amazon DynamoDB    cloudtrail -> cloudwatch -> sns -> sqs -> lambda    lambda -> dynamo    lambda -> kinesis  }}aws_2: AWS Cloud {  bucket: Bucket  bucket -> subsystem.cloudtrail  subsystem: "" {    cloudwatch: Amazon CloudWatch    cloudtrail: Amazon CloudTrail    cloudtrail -> cloudwatch  }}
Enter fullscreen modeExit fullscreen mode

Diagram with defined connections

And that's it! The specified objects are connected automatically. But the diagram still looks a little raw - let's add some icons to make it look better.

aws_1.bucket_1 -> aws_2.bucketaws_2.subsystem.cloudwatch -> aws_1.subsystem.cloudwatch: Monitor templateaws_1: AWS Cloud {    obj: Object    obj.shape: circle    obj.style.stroke: "#62a638"    bucket_1: Bucket    bucket_1.shape: image    bucket_1.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/s3/s3.svg    bucket_2: Bucket    bucket_2.shape: image    bucket_2.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/s3/s3.svg    obj -> bucket_1    bucket_1 -> subsystem.cloudtrail    subsystem.kinesis -> bucket_2    subsystem: "" {        cloudwatch: Amazon CloudWatch        cloudwatch.shape: image        cloudwatch.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/cloudwatch/cloudwatch.svg        cloudtrail: Amazon CloudTrail        cloudtrail.shape: image        cloudtrail.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/cloudtrail/cloudtrail.svg        sns: Amazon Simple Notification Service        sns.shape: image        sns.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/simple_notification_service/sns.svg        sqs: Amazon Simple Queue Service        sqs.shape: image        sqs.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/simple_queue_service/sqs.svg        lambda: AWS Lambda        lambda.shape: image        lambda.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/lambda/lambda.svg        kinesis: Amazon Kinesis Data Firehose        kinesis.shape: image        kinesis.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/kinesis_data_firehose/firehose.svg        dynamo: Amazon DynamoDB        dynamo.shape: image        dynamo.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/dynamodb/dynamodb.svg        cloudtrail -> cloudwatch -> sns -> sqs -> lambda        lambda -> dynamo        lambda -> kinesis    }}aws_2: AWS Cloud {    bucket: Bucket    bucket.shape: image    bucket.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/s3/s3.svg    bucket -> subsystem.cloudtrail    subsystem: "" {        cloudwatch: Amazon CloudWatch        cloudwatch.shape: image        cloudwatch.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/cloudwatch/cloudwatch.svg        cloudtrail: Amazon CloudTrail        cloudtrail.shape: image        cloudtrail.icon: https://raw.githubusercontent.com/exler/diagrams/main/icons/aws/cloudtrail/cloudtrail.svg        cloudtrail -> cloudwatch    }}
Enter fullscreen modeExit fullscreen mode

With the icons added, the diagram is much more intuitive and easier to understand. Sadly, D2 does not support filesystem paths for icons, so you have to use remote URLs.
Nevertheless, the diagram is finished and looks great.

Final diagram

For now, D2 has limited capability of styling, so we are not able to fully reproduce the original diagram. However, we just wrote an easily reproducible and maintainable diagram in less than 70 LOC!

Summary

I hope that this post has convinced you that Diagrams as Code fit the modern's software architect's tech stack perfectly.
They are easy to write, easy to maintain, and easy to share. Give them a go when you have the chance!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Professionalism hardcoded.
  • Location
    Wrocław, Poland
  • Education
    Wrocław University of Science and Technology
  • Work
    Solutions Architect & Engineering Team Lead
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp