こんにちは。ひぐらし業を見て毎週心を痛めているふそやん@azihsoynです。
コロナ禍でIT業界ではリモートワークが増えてきて、オンボーディングもオンラインで行うことが多くなってきており、ドキュメントの重要性がさらに増している気がします。
恥ずかしながら弊チームはサーバーサイドのドキュメントが豊富にあるとは言えず、オンボーディングは手書きで構成図を書きながら口頭で説明していました。
そろそろちゃんとしないとと思い始めドキュメントを作り始めたのですが、一番重要なシステム構成図がなかなか描けずに苦労していました。
そもそもなぜシステム構成図が描けないのか? いくつか理由はあると思うのですが、自己分析した結果、
- デザインセンスがない
- 辛い
- GUIのツールで書いても秘伝のタレ化してしまう
- 継続的に更新されなさそう
- → 一回だけの図を描くことになりコスパが悪い
などがありそうでした。
自分に向いてるやり方はないものかといろいろと調べた結果、
というのがバチバチによかったので今回はその紹介をしたいと思います。
diagramsとは
Diagrams lets you draw the cloud system architecture in Python code. It was born for prototyping a new system architecture without any design tools. You can also describe or visualize the existing system architecture as well.
Diagram as Code
allows you to track the architecture diagram changes in any version control system.
aboutにあるとおり、pythonで構成図を描くツールです(go版もあります)。Diagram as Codeの通り、githubで差分を確認したり履歴を追うことが可能になります。
導入 はとても簡単で、graphvizとpythonがあれば動きます。
早速例を見てみましょう。
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 diagram: ELB("lb") >> [EC2("worker1"), EC2("worker2"), EC2("worker3"), EC2("worker4"), EC2("worker5")] >> RDS("events") if __name__ == '__main__': diagram
こんなコードを書くと
こんな図が出力されます。
from diagrams import Cluster, Diagram from diagrams.aws.compute import ECS, EKS, Lambda from diagrams.aws.database import Redshift from diagrams.aws.integration import SQS from diagrams.aws.storage import S3 with Diagram("Event Processing", show=False): source = EKS("k8s source") with Cluster("Event Flows"): with Cluster("Event Workers"): workers = [ECS("worker1"), ECS("worker2"), ECS("worker3")] queue = SQS("event queue") with Cluster("Processing"): handlers = [Lambda("proc1"), Lambda("proc2"), Lambda("proc3")] store = S3("events store") dw = Redshift("analytics") source >> workers >> queue >> handlers handlers >> store handlers >> dw
こんなコードだと
こんな図が作成されます。
これだけで大体のイメージは掴めたのではないでしょうか。
AWSのリソース以外にもGCPやFirebase、k8sなど豊富なリソースが標準で用意されているのですぐに構成図を描き始められます。
例は他にもここに載ってるのでまずは書いて動かしてみるのがいいと思います。
よかったこと
GUIのツールでももちろん同様の図は書けるのですが、コードで書けると何が嬉しいかを使ってみた感想とともに書いてみます。
レイアウトをあまり考えなくてよい
デザインセンスがない人でも安心です。
リソースを定義して矢印でつなげば優先度に従って自動で配置してくれます。
再現性がある
1つめと重複しますが、自動でレイアウトを調整してくれるということは誰が書いても同じ図になるということです。
前任者から引き継いだコードを手元で動かしても同じ図になるので秘伝のタレ化することがなくなりそうです。
pythonの文法が使える
これは今のところメリットを感じているわけではないですが、普通にif文書いたりforでループを回したりということも出来ます。
例えば本番とステージングでリソースが異なる場合はif文で生成される図を変更することもできそうです。
一つ書くと使い回せる
これは実際に書き始めて感じたのですが、1つ構成図を描くと次の構成図を描くときに一部を持ってきたり参考にすることが出来ます。
要はコピペが捗ります。
コードとして持ってこれるので一括置換したりとIDEの恩恵を受けられるのも嬉しいです。
拡張性がすごい
diagramsは dot言語というgraphvizで図を描くための言語をラップしたものになっています。
つまりgraphvizでできることは理論上なんでもできます。
issueを見てみるとdotを使って複雑なdiagramを描いてるのがいくつか見つかるので探してみるのも面白そうです(レシピ集が欲しいです)。
https://github.com/mingrammer/diagrams/issues/452
こちらのissueでは標準だとできないclusterからclusterへのedgeを描く方法が説明されています。
from diagrams import Diagram, Cluster, Edge from diagrams.oci.compute import VM graph_attr = { "layout":"dot", "compound":"true", "splines":"spline", } with Diagram("cluster to cluster edge", graph_attr=graph_attr, show=False) as diag: with Cluster("Cluster 1"): c1node1 = VM("c1node1") with Cluster("Cluster 2"): c2node1 = VM("c2node1") c1node1 - Edge(color="red", ltail="cluster_Cluster 1", lhead="cluster_Cluster 2") - c2node1
CI/CDとの相性
github等で管理することでCI/CDのフローに乗せることが出来ます。
今のところ必要性を感じていないですが、新しい構成図をpushしたらS3に自動でアップロードしてcloudfrontのinvalidationを実行するようにすれば更新漏れなどもなくせそうです。
その他
使ってる中で発見したTipsを紹介します。
配置を指定したい
自動で並べてくれるのがとても嬉しいのですが、graphvizの優先度順に並ぶので、例えば次の様な構成図は見栄えが悪くなってしまいます。
from diagrams import Cluster, Diagram from diagrams import Edge from diagrams.aws.compute import ECS, EKS with Diagram("Event Processing", show=False) as diagram: source = EKS("k8s source") with Cluster("Event Flows"): a = ECS("A") b = ECS("B") c = ECS("C") d = ECS("D") source >> a source >> b source >> c source >> d if __name__ == '__main__': diagram
こういうときは見えないEdgeでつないで内部的に優先度を変えてあげると見た目を変えることができます。
from diagrams import Cluster, Diagram from diagrams import Edge from diagrams.aws.compute import ECS, EKS with Diagram("Event Processing", show=False) as diagram: source = EKS("k8s source") with Cluster("Event Flows"): a = ECS("A") b = ECS("B") c = ECS("C") d = ECS("D") # 追加 a >> Edge(style="invis") >> b c >> Edge(style="invis") >> d source >> a source >> b source >> c source >> d if __name__ == '__main__': diagram
diagramsにない画像を出したい
できます。
CustomNodeを使えば簡単に画像を表示できます
from diagrams import Diagram from diagrams.custom import Custom with Diagram("test4", show=False) as diagram: Custom("Operator", "../custom_resources/operator.png") # 画像を配置 if __name__ == '__main__': diagram
おわりに
いかがでしたでしょうか。diagramsの素晴らしさが少しでも伝われば幸いです。
同じような思想のツールは他にもあると思うので、こんなのがあるよなど紹介していただけるととても嬉しいです。