Diagramsを使ってPythonでシステム構成図を描く
Pythonでシステム構成図を書ける、DiagramsというOSSが便利そうだったので試してみました。
対応プロバイダ
現在、Diagramsは以下の7種類のプロバイダに対応しています。各プロバイダが提供している各種サービスがノードとして対応されています。以下は対応プロバイダとそのノード一覧へのリンクです。
オンプレミスプロバイダには、GitHubやCircleCIといったサービス、汎用的なクライアント、各種DBなど幅広い種類のノードが含まれています。このアイコンないかなと思った場合は、オンプレミスプロバイダを調べてみるともしかしたらあるかもしれません。
試してみる
AWS上のシステム構成図を書いてみて各機能を試していきます。
まずはDiagramsをインストールします。
pip install diagrams
Diagramsを使うためにはGraphvizが必要となります。インストールされていない環境の場合は、ドキュメントに従い、インストールしてください。macOSの場合はbrew install graphviz
でインストールできます。
基本
diagrams.Diagramを使ってコンテキストを作成することで、図を表示できます。
図を構成する要素であるノードはdiagrams.{プロバイダ}.{リソースタイプ}.{名前}
という形式で参照できます。
ノード同士の関係性は無向の場合は-
、有向の場合は>>
と<<
で表すことができます。
クライアントからのイベントデータの流れを書いてみます。
from diagrams import Diagram from diagrams.aws.compute import Lambda from diagrams.aws.ml import Personalize from diagrams.aws.analytics import KinesisDataStreams, KinesisDataFirehose, Athena, Quicksight, Glue from diagrams.onprem.client import Client from diagrams.aws.storage import S3 with Diagram('イベントストリーミング'): # インスタンス化によってノードを作成 # ノードにラベルを付与でき、\nを入れることでラベルの改行も可能 stream = KinesisDataStreams('Kinesis\nData Streams') s3 = S3('S3') athena = Athena('Athena') # 定義したノードを始点とした流れを作成 # 変数に代入せずとも、ノードは作成可能 Client() >> stream >> Lambda('Lambda') >> Personalize('Personalize\nEventTracker') stream >> KinesisDataFirehose('Kinesis\nData Firehose') >> s3 s3 - athena >> Quicksight('QuickSight') << Client() s3 >> Glue('Glue') >> athena
スクリプトを実行し、図を作成します。
python sample.py
実行が完了すると、作成した図が表示されます。
図はPNG形式で保存されています。
Diagramの設定
Diagramでは次のような引数で図に関する情報を設定できます。
- name: 図の名前
- filename: ファイル名(デフォルト: nameによって決まる)
- 拡張子はoutformatによって定まるため含めない
- outformat: 図の保存形式(デフォルト: png)
- png、jpg、svg、pdf
- show: スクリプト実行時に作成した図を表示するかどうか(デフォルト: True)
- direction: データフローの向き(デフォルト: LR)
- TB、BT、LR、RL
- graph_attr、node_attr、edge_attr: Graphvizでの図全体、ノード、エッジの設定情報
先ほどと同様の構成で、図の設定を次のように変更してみます。
from diagrams import Diagram from diagrams.aws.compute import Lambda from diagrams.aws.ml import Personalize from diagrams.aws.analytics import KinesisDataStreams, KinesisDataFirehose, Athena, Quicksight, Glue from diagrams.onprem.client import Client from diagrams.aws.storage import S3 graph_attr = { 'bgcolor': 'gray', 'fontsize': '28' } node_attr = { 'fontsize': '14' } edge_attr = { 'arrowsize': '2.0', 'penwidth': '5.0' } with Diagram(name='イベントストリーミング2', filename='event_streaming', show=True, direction='TB', graph_attr=graph_attr, edge_attr=edge_attr, node_attr=node_attr): # インスタンス化によってノードを作成 # ノードにラベルを付与でき、\nを入れることでラベルの改行も可能 stream = KinesisDataStreams('Kinesis\nData Streams') s3 = S3('S3') athena = Athena('Athena') # 定義したノードを始点とした流れを作成 # 変数に代入せずとも、ノードは作成可能 Client() >> stream >> Lambda('Lambda') >> Personalize('Personalize\nEventTracker') stream >> KinesisDataFirehose('Kinesis\nData Firehose') >> s3 s3 - athena >> Quicksight('QuickSight') << Client() s3 >> Glue('Glue') >> athena
見やすい図とは言えませんが、先ほどとは雰囲気が変わった図になりました。好みや用途に応じて設定をカスタマイズすると良さそうです。
グループ化
ノードをリストに格納することで、ひとまとめに扱うことができます。
from diagrams import Diagram from diagrams.aws.compute import EC2 from diagrams.aws.network import ELB with Diagram('グループサンプル'): ELB() >> [EC2(), EC2(), EC2()]
クラスター
diagrams.Cluster
を使うことで、複数のノードを網掛けしてクラスターとして設定することができます。
クラスターは引数としてlabel
とdirection
が設定できますが、direction
は今の所、機能していないようです。
from diagrams import Diagram, Cluster from diagrams.aws.compute import EC2 from diagrams.aws.network import ELB from diagrams.onprem.client import Client with Diagram('クラスターサンプル'): client = Client() with Cluster('AWS'): elb = ELB() client >> elb # クラスターはネストさせることもできる with Cluster('Auto Scaling Group'): elb >> [EC2(), EC2()]
エッジ
diagrams.Edge
を使うことで、ノード間のエッジ(辺、Edge)をカスタマイズできます。
エッジは引数としてlabel
とcolor、styleが主に設定できます。他にもGraphVizが対応している各項目も設定可能です。
from diagrams import Diagram, Edge from diagrams.aws.compute import EC2 from diagrams.onprem.client import Client with Diagram('エッジサンプル'): Client() >> Edge(color='blue', style='dashed') >> EC2() >> Edge(style='bold', arrowsize='2') >> EC2()
さいごに
Diagramsを使ったシステム構成図の作成について試した内容を紹介しました。Diagramsを使った構成図作成は、要素間を結ぶ線(エッジ)のことをあまり考えなくて良いのと、コードなのでコンポーネントの切り貼りや修正が楽で、試行錯誤がしやすかったです。こういうツールを積極的に活用し、楽できるところは楽したいですね。