Help us understand the problem. What is going on with this article?

アイコンよりどりみどりの PlantUML 構成図を書く

モチベーション

  • 色んなアイコン使いたい。
    • AWS アイコン (2018 以降 ver.)
    • 言語アイコン
    • 一般的なサーバーアイコン
      • etc.
  • AWS アイコンのみの構成図サンプルは見つかるが、他はないの?
  • 細かい定義・仕様はいいから、コードで語れ。

という方向け。

要件

  • とある商品管理システム。
  • フロントエンドは、 AWS S3 + CloudFront でホスティングした SPA。
  • バックエンドは、Python + Flask on EC2。
  • どこかのレコメンドシステムにも接続しているらしい。

サンプル構成図

plantuml.png

サンプルコード

コード
@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

Data flow

  • よい矢印模索中・・・
    • Read/Write 両方なら <--> とか、データの流れる方向に --> とか、作用の主体 --> 客体 とか。でもこれでは矛盾が・・・とか。
    • もうちょっとハッキリ指針を決めたいところ。今後考える。
  • 位置の強制
    • -left-> のように、位置を強制できる。
    • 図が巨大になってくると、「どうしてもこっちに置いた方がわかりやすい」みたいな場合があるので、必要悪か。
    • Excel 構成図に比べて、「細かい位置・レイアウトを気にせず書けること」が PlantUML 構成図のメリットの 1 つなので、やりすぎは本末転倒。

エディタ

  • VSCode + PlantUML がオススメ。
    • Syntax highlight やコード補完ができる。

まとめ

  • なんだか文句の多い紹介だった気もするが、実際のところ非常に役に立っている。
    • サッと書いたホワイドボードの手書き構成図を、記録用の清書にするなど。
  • ただのテキストなので、特定サービスのアカウント作ったり、そのサービスの継続性の心配も必要ない。
  • 他、PlantUML のメリットは検索すればいくらでも出てくるので割愛する。
  • PlantUML はいいぞ。
arx8
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした