graphvizでシステム構成図作成

graphvizでシステム構成図を作ってみる。

インフラエンジニアをやっていて、これまでパワーポイントやエクセルで構成図を
作っていたが、一度作成した図を変更するたびに、
位置関係の微調整を行うのにめんどくささを感じていた。

なんとか簡単に、使えるものができないかと検討した。

そこで検討したのがgraphviz

* install graphviz

インストールは簡単。

```
wget http://www.graphviz.org/graphviz-rhel.repo
mv graphviz-rhel.repo /etc/yum.repos.d/
yum install 'graphviz*' -y
```

* create graph
グラフの作成も簡単
confを用意し、以下のコマンド実行でファイルが生成される。

```
$ dot -Tjpeg -o sample.jpeg sample.dot
```


* sample

以下が非常にシンプルな例。

![sample3.dot_20140905-1105.jpeg](https://qiita-image-store.s3.amazonaws.com/0/42586/465390ea-1737-8577-ddfb-8698d84c4023.jpeg)


confもシンプル。

```
digraph G {
  label="sysmtem component"
  user;
  web;
  app;
  mysql;
  user -> web;
  web -> app;
  app -> mysql;
}
```

これだけ。

これに色々な要素を加えてみる・・・・。

```
digraph G {
  label="sysmtem component"
  user;
  administrator;
  web;
  app;
  mail;
  mysql;
  zabbix;
  gw;
  user -> web;
  administrator -> zabbix;
  administrator -> gw;
  web -> app;
  app -> mail;
  app -> mysql;
  zabbix -> mail;
  postfix -> user;
  postfix -> administrator;
}
```

どうなるか・・・・・

![sample2.dot_20140905-1112.jpeg](https://qiita-image-store.s3.amazonaws.com/0/42586/ac558973-1037-5709-f73e-d5474318cafd.jpeg)

見れなくはないが、ちょっときつい。
このドキュメントが使われることはないだろう。

ここからが色々と工夫したもの。

大きなポイントとしては以下の2点
・サーバーごとにサブグラフを使う
・ラベルを上手に使う
・色を使い分ける

それを意識して書いたconf
非常に長く、複雑そうに見えるが、大きく2つに分かれる。

・上のnode部分がサーバーとその中にあるプロセス
・下のdependency部分がサーバー間のプロセスの依存関係

```
digraph G {
  label="sysmtem component"
  graph [ fontsize=8,fontname="MS Gothic" ];
  node [ fontsize=8,fontname="MS Gothic",fontcoler=blue ];
  edge [ fontsize=8,color="blue",fontcolor="blue",labefloat=flase ];
  graph [ compound=true,overlap=prism ];
  node [ shape=ellipse ];

  // external node
  user [ shape=egg, fillcolor=yellow, style="rounded,filled" ];
  administrator [ shape=egg, fillcolor=yellow, style="rounded,filled" ];

  // internal node
  subgraph cluster_web {
   fontcolor=red;
   label="web";
   web_httpd [ label="httpd" ];
   web_php [ label="php" ];
  }
  subgraph cluster_app {
   fontcolor=red;
   label="app";
   app_app [ label="app" ];
  }
  subgraph cluster_mail {
   fontcolor=red;
   label="mail";
   mail_postfix [ label="postfix" ];
  }
  subgraph cluster_db {
   fontcolor=red;
   label="db";
   db_mysql [ label="mysql"];
  }
  subgraph cluster_monitor {
   fontcolor=red;
   label="monitor";
   monitor_httpd [ label="httpd"];
   monitor_zabbix [ label="zabbix"];
   monitor_mysql [ label="mysql" ];
  }
  subgraph cluster_gw{
   fontcolor=red;
   label="gw";
   gw_sshd [ label="sshd" ];
  }

  // dependency
  user -> web_httpd [ label="https" ];
  user -> monitor_httpd [ label="https" ];
  administrator -> gw_sshd [ label="ssh" ];
  web_php -> app_app [ label="socket" ];
  app_app -> mail_postfix [ label="smtp" ];
  app_app -> db_mysql [ label="mysql" ];
  monitor_zabbix -> mail_postfix [ label="smtp" ];
  mail_postfix -> user [ label="mail" ];
  mail_postfix -> administrator [ label="mail" ];
}
```

これでできる図がこちら。

![sample.fin.dot_20140905-1114.jpeg](https://qiita-image-store.s3.amazonaws.com/0/42586/dd9215a1-7a7f-1356-b58a-a261623c719c.jpeg)

なかなか使えそうです。
何かサーバで障害があったときの影響、アプリ改修時の関連ノードなど。

コードで管理できるので、微妙な位置関係は基本的に不要。
過去に文字が重なって見にくく、パワポやエクセルの位置を調整するのに費やしていた時間は不要。


ただ、色々とまだまだ制約や入れなかった要素がある。
・図は2重まで、3重以上は難しい(例えば、ここに物理の要素をいれるなど)
・位置関係は自動で変わるため、confを変更するたびに各サーバの位置が変わる。
　したがって、過去との比較という意味では見にくい。
・サーバー内のプロセス間通信はいれなかった。
　これを入れると、見れたものじゃなくなる。サイズを調整すればいけなくもないが、今後の変更に耐えられない可能性があるので、サーバ内の通信については別ファイルで用意することにした。

* sample script

https://gist.github.com/shinya-tada/d99f0b3d9da56461f6d9

作成スクリプトを用意


```
$ git init
$ git clone https://gist.github.com/shinya-tada/d99f0b3d9da56461f6d9
$ chmod +x grapviz.sh
```

confを準備

```
$ vi sample.dot
```

実行

```
$ ./grapviz.sh sample.dot

created sample.dot_20140901-1114.jpeg
```