モチベーション
- 色んなアイコン使いたい。
- AWS アイコン (2018 以降 ver.)
- 言語アイコン
- 一般的なサーバーアイコン
- etc.
- AWS アイコンのみの構成図サンプルは見つかるが、他はないの?
- 細かい定義・仕様はいいから、コードで語れ。
という方向け。
要件
- とある商品管理システム。
- フロントエンドは、 AWS S3 + CloudFront でホスティングした SPA。
- バックエンドは、Python + Flask on EC2。
- どこかのレコメンドシステムにも接続しているらしい。
サンプル構成図
サンプルコード
コード
@startuml
title 商品管理システム
' @see https://github.com/awslabs/aws-icons-for-plantuml/tree/v5.0
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/AWSCommon.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/Compute/EC2.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/Compute/Lambda.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/Database/Aurora.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/General/Client.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/GroupIcons/Cloudalt.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/NetworkingAndContentDelivery/CloudFront.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/NetworkingAndContentDelivery/ELBApplicationLoadBalancer.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/NetworkingAndContentDelivery/Route53.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/NetworkingAndContentDelivery/VPC.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/Storage/S3Bucket.puml
!includeurl https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v5.0/dist/Storage/SimpleStorageServiceS3.puml
' @see https://github.com/tupadr3/plantuml-icon-font-sprites/tree/v2.1.0
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/common.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/devicons/java.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/devicons/javascript.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/devicons/nginx.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/devicons/python.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/font-awesome-5/file_excel.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/font-awesome-5/server.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/font-awesome-5/slack.puml
!includeurl https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.1.0/material/dns.puml
' @see https://github.com/Roemer/plantuml-office/tree/1.0.0
!includeurl https://raw.githubusercontent.com/Roemer/plantuml-office/1.0.0/office2014/Clouds/cloud.puml
!includeurl https://raw.githubusercontent.com/Roemer/plantuml-office/1.0.0/office2014/Concepts/firewall.puml
!includeurl https://raw.githubusercontent.com/Roemer/plantuml-office/1.0.0/office2014/Servers/cluster_server.puml
!includeurl https://raw.githubusercontent.com/Roemer/plantuml-office/1.0.0/office2014/Servers/datacenter.puml
' ''''''''''''''''''
' Overwrite default
' ''''''''''''''''''
show stereotype
!definelong AWSEntity(e_alias, e_label, e_techn, e_color, e_sprite, e_stereo)
rectangle "==e_label\n<color:e_color><$e_sprite></color>\n" <<e_stereo>> as e_alias
!enddefinelong
!definelong AWSEntity(e_alias, e_label, e_techn, e_descr, e_color, e_sprite, e_stereo)
rectangle "==e_label\n<color:e_color><$e_sprite></color>\n e_descr" <<e_stereo>> as e_alias
!enddefinelong
' 他UMLのキーワードを使用可能にするための設定
allow_mixing
' '''''''''''''''
' Declare object
' '''''''''''''''
actor "ユーザー" as user
Client(user_browser, "ユーザー端末", "") {
DEV_JAVASCRIPT(user_js, "商品管理システム")
}
Cloudalt(aws, "AWS", "") {
Route53(aws_r53, "", "")
' Frontend
CloudFront(aws_cloud_front, "", "")
Lambda(aws_lambda_auth, "Lambda@Edge Basic認証", "")
SimpleStorageServiceS3(aws_s3_frontend, "", "") {
S3Bucket(aws_s3b_frontend, "", "") {
DEV_JAVASCRIPT(user_js_src, "React")
}
}
VPC(aws_vpc, "", "") {
ELBApplicationLoadBalancer(aws_alb, "", "")
' Backend For Frontend
EC2(aws_ec2, "", "") {
DEV_NGINX(aws_ec2_nginx, "")
DEV_PYTHON(aws_ec2_web_api, "Flask") {
component "一覧・詳細・新規作成・編集・削除" as aws_web_api_crud
component "商品リストDL" as aws_web_api_dl
}
FA5_FILE_EXCEL(aws_ec2_output_data, "中間データ")
}
Aurora(aws_web_api_db, "", "")
}
}
OFF_DATACENTER(other, "外部システム") {
OFF_FIREWALL(other_fw, "")
MATERIAL_DNS(other_dns, "DNS")
FA5_SERVER(other_api_server, "") {
DEV_JAVA(other_api_server_api, "レコメンド API")
}
OFF_CLUSTER_SERVER(other_es_master, "Elasticsearch cluster")
}
FA5_SLACK(slack, "")
' ''''''''''
' Data flow
' ''''''''''
user -- user_browser
' render app
user_browser <--> aws_r53
user_browser <-- aws_cloud_front: 画面(html + js)取得
aws_cloud_front <--> aws_lambda_auth
aws_cloud_front <-- user_js_src
' api call
user_js <--> aws_alb
aws_alb <--> aws_ec2_nginx
aws_ec2_nginx <--> aws_ec2_web_api
' events
aws_web_api_crud <--> aws_web_api_db
aws_web_api_dl <--> aws_web_api_db
aws_web_api_dl <--> aws_ec2_output_data
' 外部システム連携
aws_web_api_dl <--> other_fw
other_fw <--> other_dns
other_fw <--> other_api_server_api
other_api_server_api <--> other_es_master
' 異常系
aws_ec2_web_api -left[#red]-> slack: エラー通知
@enduml
※以下の Online PlantUML Editor で、ツールのインストールなしで描画できる
https://plantuml-editor.kkeisuke.com/
雑解説
- 必要な分は見せたということだ・・・で終わりでもいいのだが、いつかの自分のために覚書。
!includeurl
- いわゆる import 文
-
サンプル では、
!define
で繰り返し部分を共通化している。 - しかし、個人的には邪魔・URL直でよいと思う。以下理由。
-
!define
の変数管理が面倒くさいから。- 新たに include したい場合、GitHub から (ファイルファインダー など使って) 探してくる。
- で、見つけたら「Raw」を開き、URLをそのまま貼り付ければよい。
- もしサンプルの通り
AWSPuml
という変数に置き換えていた場合、どこまでが変数値で、どこまでが追加する値か、把握・書き換えなければならない。 - include リポジトリが 1 つならいいが、複数のリポジトリからアイコン参照するようになると、いちいち面倒くさい。
- IDE サポートも多くは望めないので、変数の衝突回避も人間が注意する必要がある。面倒くさい。
-
!includeurl
の後ろを valid な URL にできるから。- なので、そのまま開き、中身を確認できる。
- モノによって、引数の位置や機能が違うとかあるので、いざという時すぐ確認できる方がよい。
-
@see
- 使うリポジトリを記載することで、新たに include したい場合に探しに行きやすくしている。
- また、明示的にバージョン指定しておくことで、「知らない間に Breaking change があって壊れた」という事態を回避できる。
Overwrite default
- もろもろ見やすさの試行錯誤と妥協の結果である。
- 以下を考えた気がする(正直もう忘れた)
- AWS のアイコンとサービス名の対応を覚えるのは諦めたので、デフォルトでサービス名を表示させたい。
- object を宣言した時に与えた名前を表示させたい。
Declare object
- 各種 object の宣言、これまた面倒くさいのが以下。
- 引数の定義(数・機能)が違うこと。
-
!includeurl
の値を見ただけでは、どんな object が使えるようになったかわからないこと(いちいち中身を確認する必要がある)
- 例えば、
EC2
- 例えば、
DEV_JAVASCRIPT
- 間違えた時のエラーメッセージもわかりづらいので、「あのアイコンはうまくいったのに、コピペしたこのアイコンはうまくいかない。なぜ?」みたいな時間泥棒に遭いがち。
Data flow
- よい矢印模索中・・・
- Read/Write 両方なら
<-->
とか、データの流れる方向に-->
とか、作用の主体 --> 客体
とか。でもこれでは矛盾が・・・とか。 - もうちょっとハッキリ指針を決めたいところ。今後考える。
- Read/Write 両方なら
- 位置の強制
-
-left->
のように、位置を強制できる。 - 図が巨大になってくると、「どうしてもこっちに置いた方がわかりやすい」みたいな場合があるので、必要悪か。
- Excel 構成図に比べて、「細かい位置・レイアウトを気にせず書けること」が PlantUML 構成図のメリットの 1 つなので、やりすぎは本末転倒。
-
エディタ
- VSCode + PlantUML がオススメ。
- Syntax highlight やコード補完ができる。
まとめ
- なんだか文句の多い紹介だった気もするが、実際のところ非常に役に立っている。
- サッと書いたホワイドボードの手書き構成図を、記録用の清書にするなど。
- ただのテキストなので、特定サービスのアカウント作ったり、そのサービスの継続性の心配も必要ない。
- 他、PlantUML のメリットは検索すればいくらでも出てくるので割愛する。
- PlantUML はいいぞ。