PlantUMLを使って、AWS構成図を描いてみる。

n-ozawan

皆さん、こんにちは。技術開発グループのn-ozawanです。
春分の日では太陽は赤道の真上を通るため、昼と夜の長さが等しくなる日と言われています。しかし実際のところは大気の屈折などにより、昼間の方が少し長いのだそうです。

本題です。
テキストベースで図を描画するツールとしてPlantUMLがあります。このPlantUMLですが、UMLを描けるのはもちろん、AWSの構成図を描くことも出来ます。今回はAWS構成図の描く方法と、綺麗に描くためのテクニックを少しだけ紹介します。

PlantUMLでAWSアイコンを描く

AWSのアイコンを表示する

PlantUMLには標準ライブラリとして、多くのアイコンが扱えるようになっています。その標準ライブラリで用意されている数多くのアイコンの中に、AWSに関するアイコンも含まれています。他に何があるのか知りたい方は公式サイトを参照してください。以下はEC2アイコンを表示してみただけの、最小のコードです。

@startuml
!include <awslib/AWSCommon>
!include <awslib/Compute/EC2>

EC2(ec2, "Label", "Technology", "Optional Description")
@enduml

!include(...)は外部ファイルを読み込むことが出来ます。冒頭のawslib/AWSCommonは、AWSアイコンを利用するための共通関数などが定義されており、先頭に定義する必要があります。awslib/Compute/EC2を読み込むことでEC2のアイコンを表示する関数を使えるようにします。そして、その関数であるEC2(...)を記述することでEC2のアイコンを描画します。

EC2(...)関数の第1引数はエイリアスです。ec2 -> rdbなど、他のアイコンと線を結ぶ時などに利用します。第2引数はラベルです。第3引数はシステムにおける仕様を端的に記載します。第4引数は任意で詳細な説明を記載します。

よりそれっぽい構成図を描いてみる

アイコン1つでは寂しいので、それっぽく構成図を描いてみましょう。以下は、EC2インスタンスをプライベートサブネットに配置して、DBにはMySQLを利用している構成図になります。

@startuml
!include <awslib/AWSCommon>
!include <awslib/General/Users>
!include <awslib/Groups/AWSCloud>
!include <awslib/Groups/VPC>
!include <awslib/Groups/PublicSubnet>
!include <awslib/Groups/PrivateSubnet>
!include <awslib/NetworkingContentDelivery/VPCInternetGateway>
!include <awslib/NetworkingContentDelivery/VPCNATGateway>
!include <awslib/Compute/EC2>
!include <awslib/Database/AuroraMySQLInstance>

Users(users, "利用者", "")

AWSCloudGroup(cloud) {
  VPCGroup(vpc) {
    VPCInternetGateway(ig, "Internet Gateway", "")

    PrivateSubnetGroup(private, プライベートサブネット) {
      AuroraMySQLInstance(mysql, "Aurora MySQL", "")
      EC2(ec2, "App Server", "")
    }

    PublicSubnetGroup(public, パブリックサブネット) {
      VPCNATGateway(ng, "NAT Gateway", "")
    }
  }
}

users -> ig
ig -> ng
ng -> ec2
ec2 -> mysql
@enduml

一気にコード量が増えましたが、やっていることは先ほどと変わりません。使いたいアイコンの定義を読み込み、関数を記述することで描画しています。

アイコンをシンプルにしたい

アイコンを描画出来るのは良いのですが、なんだか文字が多くて見辛く感じるかもしれません。その時はawslib/AWSCommonの後に、awslib/AWSSimplifiedをincludeしてください。

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified>
' 以下省略
@enduml

どのアイコンが使えるの?

先ほどの構成図ではawslib/Compute/EC2awslib/Database/AuroraMySQLInstanceなどをincludeしていますが、これらをどこから探せばいいのでしょうか?どこかにドキュメントが整備されているのでしょうか?

残念ながら、私が探した限り、ドキュメントなどは用意されていないようです。なので、現状ではGitHubを直接見るしかありません。S3アイコンであれば、awslib14/Storage/SimpleStorageService.pumlに格納されていることが分かります。あとはそこまでのパスに合わせて、!include <awslib/Storage/SimpleStorageService>と定義すればOKです。

少々不便ではありますが、頑張って探してみてください。

テクニック集

アイコンの背景を透明にしたい

関数の後ろに#transparentを指定することで、背景を半透明にすることが出来ます。

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified>
!include <awslib/Groups/PrivateSubnet>
!include <awslib/Compute/EC2>
!include <awslib/Storage/SimpleStorageService>
!include <awslib/Database/AuroraMySQLInstance>

PrivateSubnetGroup(private, プライベートサブネット) {
  AuroraMySQLInstance(mysql, "Aurora MySQL", "") #transparent
  EC2(ec2, "App Server", "") #transparent
}
@enduml

矢印の方向を指定したい

線を結ぶ際に、updownrightleftを指定します。以下のように略して記述することも可能です。

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified>
!include <awslib/Compute/EC2>
!include <awslib/Storage/SimpleStorageService>

EC2(ec2, "App Server", "")
SimpleStorageService(s3_bucket01, "Bucket01", "")
SimpleStorageService(s3_bucket02, "Bucket02", "")
SimpleStorageService(s3_bucket03, "Bucket03", "")
SimpleStorageService(s3_bucket04, "Bucket04", "")

ec2 -u-> s3_bucket01
ec2 -r-> s3_bucket02
ec2 -d-> s3_bucket03
ec2 -l-> s3_bucket04
@enduml

矢印の長さを調整したい

アイコン同士をつなぐハイフンの数により、矢印の長さを調整することが出来ます。また、これにより、見栄えが少し改善する場合があります。

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified>
!include <awslib/General/Users>
!include <awslib/Compute/EC2>

Users(users_01, "利用者", "")
Users(users_02, "利用者", "")
Users(users_03, "利用者", "")
EC2(ec2_01, "App Server 01", "")
EC2(ec2_02, "App Server 02", "")
EC2(ec2_03, "App Server 03", "")

users_01 -> ec2_01
users_02 --> ec2_02
users_03 ---> ec2_03
@enduml

アイコンを思い通りに並べたい

なんかアイコンの並びに不満がある場合は、アイコン同士を非表示の矢印で結んでみましょう。

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified>
!include <awslib/General/Users>
!include <awslib/Compute/EC2>

Users(users, "利用者", "")
Users(developer, "開発者", "")

EC2(prd, "本番環境", "")
EC2(stg, "検証環境", "")

users -r-> prd
developer -r-> stg

' 利用者と開発者のアイコンを見えない矢印で結ぶ
users -[hidden]d->developer
@enduml
users -[hidden]d->developerがない場合
users -[hidden]d->developerがある場合

アイコンをパーティション分けしたい

AWSアイコンにはGroupが用意されていますので、用途ごとにGroupでアイコンを分けると良いでしょう。しかし、中には枠線を描画せずに、アイコンを分けたいときがあると思います。その時はskinparamでスタイルを透明にすることが出来ます。

@startuml
!include <awslib/AWSCommon>
!include <awslib/AWSSimplified>
!include <awslib/Compute/EC2>
!include <awslib/Storage/SimpleStorageService>

skinparam rectangle<<hidden>> {
  FontColor transparent
  BackgroundColor transparent
  BorderColor transparent
}

rectangle hoge <<hidden>> {
  SimpleStorageService(s3_bucket01, "Bucket01", "")
  SimpleStorageService(s3_bucket02, "Bucket02", "")
  SimpleStorageService(s3_bucket03, "Bucket03", "")
}
rectangle foo <<hidden>> {
  SimpleStorageService(s3_bucket04, "Bucket04", "")
  SimpleStorageService(s3_bucket05, "Bucket05", "")
  SimpleStorageService(s3_bucket06, "Bucket06", "")
}
@enduml

おわりに

PlantUMLによるAWS構成図の描き方と、少しでも綺麗に見えるようにするテクニックでした。今回紹介したテクニックはAWS構成図とは関係なく使えますので、是非ご活用ください。

今回紹介したのは、まだ小さい構成図なので、特に違和感は感じないかもしれません。ここから更に複雑な構成図を描いていくと、こちらの意図とはかけ離れた図が出来上がることが多々あります。今回紹介したテクニック以外にも色々とありますので、試行錯誤してみてください。

ただし、あまり試行錯誤しすぎると、誰も読めないコードが出来上がり、誰もメンテナンスが出来なくなります。「諦めが肝心」という言葉がある通り、あまり拘り過ぎず、適度なところでやめましょう。

ではまた。

Recommendおすすめブログ