【Python】diagramsを使って3分でインフラ図を作製

# はじめに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/e9ff7817-a2ef-326f-0134-ba9ad2fd53e7.png)
><small>diagrams公式より画像を引用</small>

pythonのdiagramsというライブラリを使用することで上記のようなクラウドシステムアーキテクチャを描画することが出来る。
diagramsで使用できるシステムズはAWS、Azure、GCP、Kubernetes、Alibaba Cloud、Oracle Cloudの6大providersの他、各種プログラミング言語やフレームワークにも対応している。
今回は基本的な実装方法をメモ的に記したいと思う。

# インストール
以下のコマンドでインストールすることが出来る。

```
# pipでのインストール
$ pip install diagrams

# pipenv環境でのインストール
$ pipenv install diagrams

```

# 使いかた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/2425e74f-3f1e-1ff1-321a-8ea51b9b7a57.png)

diagramsは以下の4つの要素から成り立っている。

・Diagrams
・Nodes
・Clusters
・Edges

## Diagrams

Diagramsはインフラ構成図のキャンバスみたいなものである。

Nodeは上のようなアーキテクチャ一つ分であり、Diagrams上にNodeを設置していくことで基本的なインフラ構成図を作れる。

以下に公式に乗っている一番シンプルな構成図を示す。
※尚、以下からjupyter notebookを使用してインフラ構成図を作成していく。

```
# Diagramsのimport
from diagrams import Diagrams
# Nodeのインストール(今回はEC2)
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram") as diag:
    EC2("web")
diag
```
このコードで以下のようなインフラ図が出来上がる。
またコードを実行した際にjupyter notebookを使用しているディレクトリにインフラ図がダウンロードされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/564d11b0-0e9c-f0ba-ea95-647eb7a52438.png)


###解説

基本的な文法は以下のように書く。

```
with Diagram("キャンバスに付けたい名前",
             outformat="(png, jpg, svg, and pdf)から選択",
             filename="ファイル名として付けたい名前",
            show=False,
            direction=(TB, BT, LR and RL)の中から選択):
    インフラ図を書く
```

outformat、filename、showは省略可能。

outformat: png, jpg, svg, and pdfからファイルのフォーマットを選択する
filename: ディレクトリにダウンロードするfileの名前を記入する
show:　pythonの外部で表示されない
direction: インフラ構成図の進行の向きを選択できる。
TB: top2bottom, BT: bottom2top,  LR: left2right,  RL: right2left


## Nodes
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/7175857a-021d-c815-bfb4-d0d523ce6aab.png)
Nodeは上のようなiconである。
Nodeオブジェクトはプロバイダ.リソースタイプ.名前でimportすることが出来る。
例: aws->provider compute->リソースタイプ　名前->EC2
`import diagrams.aws.compute.EC2`
公式ページよりどのようなNodeがあるか確かめることが出来る。

以下にNodeを使用したインフラ図の例を示す。


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

with Diagram("Web Services", show=False) as di:
    (ELB("lb") >> EC2("web")) - EC2("web") >> RDS("userdb")
di
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/a0c23aae-a341-40e5-9941-ae3f4875d358.png)

### 解説
Node("付けたい名前")でNodeのicon一つを作成できる。
またNode同士の結合は主に以下の2つの記号で行う。

<span>>></span> : >>の向いている方向に矢印でつなげる
-  : 直接的なつながりを示す

一つのNodeから複数のNodeに結合したいときは以下のように結合したいNodeをlistにまとめる。

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

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

with Diagram("Grouped Workers", show=False, direction="TB") as dd:
    #list型にまとめる
    ELB("lb") >> [EC2("worker1"),
                  EC2("worker2"),
                  EC2("worker3"),
                  EC2("worker4"),
                  EC2("worker5")] >> RDS("events")
dd
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/1a0660b0-69ca-2366-9b62-b57c5847cbff.png)


## Cluster
Clusterを使用することで一部のまとめたいNodeをグループ化することが出来る。
以下に例を示す。

```
from diagrams import Cluster, Diagram
from diagrams.aws.compute import ECS
from diagrams.aws.database import RDS
from diagrams.aws.network import Route53

with Diagram("Simple Web Service with DB Cluster", show=False) as dino:
    dns = Route53("dns")
    web = ECS("service")

    with Cluster("DB Cluster"):
        db_master = RDS("master")
        db_master - [RDS("slave1"),
                     RDS("slave2")]

    dns >> web >> db_master
dino
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/6da48554-ecf4-e6db-7c2e-9a66ec0de715.png)

### 解説
Clusterでまとめたい部分を以下のようにしてまとめる。

```
with Cluster("Cluster名"):
        Clusterの構成を書く
```

また、Cluster内にClusterを書いてネストすることも出来る。

## Edges
EdgesはNode同士の結合に対して効果をつけることが出来る。

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

with Diagram("Web Services", show=False) as di:
    (ELB("lb") >>Edge(color="red", style="dotted",label="collect")>> EC2("web")) -Edge(color="brown", style="dashed")- EC2("web") >> RDS("userdb")
di
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/08c86390-cfca-10b8-4a7a-f066a41ebe6e.png)

###解説
EdgesはNodeの結合の記号(- or >>)の間に入れることができる。

```
#-に入れている例
Node - Edge(color="結合の色", style="結合のstyle",label="結合につけたいラベル名") - Node

#>>も-と同様
Node >> Edge(color="結合の色", style="結合のstyle",label="結合につけたいラベル名") >> Node

```

# 終わりに
Pythonを使用することで簡単にインフラ構成図を作れることがわかった。
ぜひ、Pythonの練習がてらインフラ図を作ってみてはいかがでしょうか。

#参考文献
[Diagrams 公式](https://diagrams.mingrammer.com/docs/getting-started/installation)