LoginSignup
14
7

More than 3 years have passed since last update.

構成図をコード管理できるDiagram as Code(Diagrams)を試してみた

Posted at

Diagram as Code(Diagrams)を試す

普段、構成図はCacooなどのオーサリングツールを利用していますが、
Pythonコードで構成図を描画できるというツールを使ってどこまで書けるか試してみました。

結論、所感

  • シンプルに書けるので謳われてる通り、新しいシステムのプロトタイプ化が素早くできるのがよい
  • 学習コストも低く、Pythonに慣れてさえいればすぐ書き始められる
  • フォントサイズの変更属性はあったが、注釈とか書く方法がわからなかった

環境について

  • macOS Catalina
  • Python 3.6.8

動作要件

  • Python 3.6 以上
  • Graphviz が必要

事前準備

新しく仮想環境を作りその中にパッケージをインストールしていきます。
この手順は任意です。

python -m venv ~/envs/diagrams
source ~/envs/diagrams/bin/activate

Installation

# Homebrewでインストール
brew install graphviz
# pipでインストール
pip install diagrams

例題

とりあえず例題を使って出力してみました。

from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Web Service", show=False):
    ELB("lb") >> EC2("web") >> RDS("db")
python diagram.py
2020-05-29 13:50:05.901 +[__NSCFConstantString length]: unrecognized selector sent to class 0x
2020-05-29 13:50:05.905 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[__NSCFConstantString length]: unrecognized selector sent to class 0x'

早速、エラーに遭遇しました。
まったく原因がわからず、issueなど漁りながらとりあえず元々インストール済みだったgraphvizをアップグレードすることにしました。

brew upgrade graphviz

バージョンを 2.40.1 -> 2.44.0 にアップグレードできました。

python diagram.py

無事出力できました。

お試し構成

from diagrams import Cluster, Diagram
from diagrams.aws.compute import EC2, ElasticBeanstalk
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB, Route53
from diagrams.onprem.client import Client

graph_attr = {
}

def draw():
    with Diagram("web_service", show=False, graph_attr=graph_attr, direction="TB"):
        route53 = Route53('route53')
        client = Client('client')

        client >> route53

        with Cluster("ElasticBeanstalk"):
            with Cluster("WEB"):

                with Cluster("Subnet1"):
                    web1 = EC2("web")
                    lb1 = ELB("lb1")
                    lb1 >> web1

                with Cluster("Subnet2"):
                    web2 = EC2("web")
                    lb2 = ELB("lb2")
                    lb2 >> web2

                route53 - [lb1, lb2]

            with Cluster("DB"):
                db_master = RDS("master")

                with Cluster("Subnet3"):
                    rds1 = RDS("slave1")

                with Cluster("Subnet4"):
                    rds2 = RDS("slave2")

                db_master - [rds1, rds2]

                [web1, web2] >> db_master

if __name__ == '__main__':
    draw()

出力イメージ

web_service.png

14
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
7