Diagramsを使用してOCIのアーキテクチャ図を生成

# Diagramsとは
DiagramsはPythonでコードを記述することにより、各種アーキテクチャ図のファイルを生成するOSSです。
本記事公開時点のバージョンは0.6.2です。

Oracle Cloudはもちろんのこと、オンプレミス、Kubernetes、AWS、Azure、GCP、Alibaba Cloudのアーキテクチャ図や、これらが混在するアーキテクチャ図を生成することが可能です。
本記事はOCIをベースに解説していますが、OCI以外のアーキテクチャ図においてもインポートするパッケージが異なるだけで、基本的な使い方は同様です。
生成されるアーキテクチャ図は各種クラウド標準のそれとは異なるものになりますが、本家サイトでも謳っている"Diagram as Code"、コードベースでのアーキテクチャ図のバージョン管理が実現できる点が大きいと思います。
ライセンスはMITライセンスです。

[Diagramsのサイト](https://diagrams.mingrammer.com/)
[GitHub](https://github.com/mingrammer/diagrams)


# Diagramsの導入
## Graphvizの導入
Diagramsは図の描写をGraphvizというOSSに依存しています。
Diagramsを利用するには、先にGraphvizを導入する必要があります。
MacでHomebrewを利用している場合は`brew install graphviz`でインストール可能です。
Windowsの場合は[Graphvizのサイト](https://www.graphviz.org/)からソフトウェアをダウンロード、インストールしてください。
また、インストールパス\binに対してパスを通してください。

## Diagramsの導入
Python3.6以上の環境にて、`pip install diagrams`で導入できます。


# 実行サンプルと解説

## アーキテクチャ図の出力例
今回は以下のようなサンプルを出力してみます。
例のように、日本語も利用可能です。
<img width="600" alt="screenshot_20200224_124458.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125837/10e8f6e4-c366-33f6-a025-38ebc50ce348.png">

## コーディングサンプル
```python:sample.py
from diagrams import Cluster, Diagram
from diagrams.oci.compute import Vm as VM
from diagrams.oci.database import Databaseservice as DBCS
from diagrams.oci.network import Loadbalance as LB, Drg as DRG
from diagrams.oci.connectivity import Fastconnect as FC

with Diagram("OCIサンプルアーキテクチャ図", outformat="pdf", filename="oci_sample", show=False):
    with Cluster("Sample VCN"):
        drg = DRG("DRG")
        with Cluster("Private Subnet"):
            lb = LB("Load Balancer")
            ap = [VM("Application\nServer2"), VM("Application\nServer1")]
            db = DBCS("Database Server")
    FC("FastConnect") >> drg >> lb >> ap >> db
```

## 基本概念
DiagramsにはDiagram, Node, Clusterという基本概念があります。
##### Diagram
アーキテクチャ図のクラスです。
Diagramクラスはwith文に対応しているので、サンプルのような記述が可能です。
以下、サンプルソースの引数の解説です。

- name : 最初の引数です。サンプルコードでは引数名を省略しています。図のタイトルを指定します。
- outformat : 出力されるファイルのフォーマットを指定します。無指定時のデフォルトはpngです。他にはjpg, svg, and pdfに対応しています。
- filename : 出力ファイル名を指定します。無指定時のデフォルトは、図のタイトルを小文字に変換したものとなります。
- show : 出力したファイルを標準のビューワで表示させるか否かをboolで指定します。デフォルトはTrueです。

サンプルで指定している以外にも、以下の引数が指定可能です。

- direction : フローの方向を指定します。以下の4種類が指定可能です。
    - LR : 左から右(デフォルト)
    - RL : 右から左
    - TB : 上から下
    - BT : 下から上
- graph_attr, node_attr, edge_attr : それぞれアーキテクチャ図、Node(後述)、エッジの書式をJSON形式で指定します。指定できる内容はGraphvizがサポートしているものとなります。指定可能な内容の詳細は[Graphvizの解説](https://www.graphviz.org/doc/info/attrs.html)をご確認ください。

##### Node
ノード(インスタンス、サービス等)のクラスです。
サンプルの図だと「DRG」とか「Database Server」となっている個所などが該当します。
Nodeのオブジェクト名称は「プロバイダ.リソースタイプ.名称」という形式になっています。
Nodeの一覧は[こちら](https://diagrams.mingrammer.com/docs/nodes/oci)を参照してください。
引数はlabelのみとなります。
- label: サンプルコードでは引数名を省略しています。ノードのタイトルを指定します。

##### Cluster
Nodeをグルーピングするクラスです。
サンプルの図では、VCNやサブネットを表現するためにClusterを使用しています。
サンプルの図のようにClusterをネストさせることも可能です。
ネストの階層数に特段の制限はありません。
同一階層に複数のClusterを表示することも可能です。
以下、引数の解説です。
- label: 最初の引数です。サンプルコードでは引数名を省略しています。グルーピングのタイトルを指定します。無指定時は「cluster」と表示されます。
- direction : Diagramのdirection引数と同様です。

## コーディングの流れ
基本はDiagramクラスのwith文の中で表示させるNodeのインスタンスを作成し、表示順に並べてNodeをつなぐ線の方向を指定するだけです。
必要に応じてClusterを指定し、クラスタに属するNodeはClusterのwith文中で生成します。
線の方向は、以下の3種類となります。

- >> : 前から後への矢印
- << : 後から前への矢印
- - : 矢印のない線


# 最後に
全体的には、Pythonに慣れている方であれば、引数の解説以外はコーディングサンプルをしばらく眺めていれば理解できるものと思われます。
記事執筆時点では対応しているサービスの網羅性がやや弱い印象ですが、Diagramsは活発に更新が行われており、より進化することが期待されます。