テキストから図が生成できるMermaidでAWS構成図をつくる

# はじめに

テキストからダイアグラムの図が生成できるMermaidでAWS構成図をつくる方法を紹介します。

また、MermaidはGithubやQiitaなどのWebサービスやVSCodeやIntelliJなどのツール、コマンドやWebシステムでも使用できますので、良ければ下記の記事もご確認ください。

https://qiita.com/b-mente/items/97a4296666faccd53a72

https://qiita.com/b-mente/items/b15011ab3b6c3830e732

本手法でも使用しているflowchartでAWSの画像やアイコンを使う方法を下記にしたので、良ければこちらもご確認ください。

https://qiita.com/b-mente/items/89e900dab7319ef502be

Mermaidのことはなんとなくわかったけど、AWSの構成図や配置図が描けないか考えていた人にも参考になれば幸いです。

# AWSの構成図をつくる

## ・どんな感じの図ができるのか

AWSの構成図を描くときにはAWS公式から提供されている[[AWS Architecture Icons]](https://aws.amazon.com/jp/architecture/icons/)というAWSのダイアグラムを書く際のアイコンセットを利用する機会が多いと思いますが、Mermaidでは残念ながらまだ使用できません。

そこで、アイコンの使用は諦めてAWSに関するグループやサービスについて、それっぽく見える方法を記載しました。

なお、Mermaidの書き方については[[ザックリ解説 - どう書くのか]](https://qiita.com/b-mente/items/97a4296666faccd53a72#%E3%81%A9%E3%81%86%E6%9B%B8%E3%81%8F%E3%81%AE%E3%81%8B)や[[Mermaid公式ドキュメント]](https://mermaid-js.github.io/mermaid/#/)を参照してください。

```mermaid
flowchart LR

%%外部要素のUser
OU1[User]

%%グループとサービス
subgraph GC[AWS Cloud]
  subgraph GR[Region:Tokyo]
    subgraph GV[VPC]
      subgraph GA[AZ:a]
        subgraph GS1[Public subnet]
　　　        NW1{{ELB}}
        end
        subgraph GS2[Private subnet]
          CP1(EC2)
        end
        DB1[(RDS)]
      end
    end
    ST1[("Ｓ３")]
  end
end

%%サービス同士の関係
OU1 --> NW1
NW1 --> CP1
CP1 --> DB1
DB1 -.-> ST1

%%グループのスタイル
classDef SGC fill:none,color:#345,stroke:#345
class GC SGC

classDef SGR fill:none,color:#59d,stroke:#59d,stroke-dasharray:3
class GR SGR

classDef SGV fill:none,color:#0a0,stroke:#0a0
class GV SGV

classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
class GA SGA

classDef SGPrS fill:#def,color:#07b,stroke:none
class GS2 SGPrS

classDef SGPuS fill:#efe,color:#092,stroke:none
class GS1 SGPuS

%%サービスのスタイル
classDef SOU fill:#aaa,color:#fff,stroke:#fff
class OU1 SOU

classDef SNW fill:#84d,color:#fff,stroke:none
class NW1 SNW

classDef SCP fill:#e83,color:#fff,stroke:none
class CP1 SCP

classDef SDB fill:#46d,color:#fff,stroke:#fff
class DB1 SDB

classDef SST fill:#493,color:#fff,stroke:#fff
class ST1 SST
```

:::note info

[Ver 11.1.0](https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.1.0)からArchitecture Diagram(β版)を記載できるようになり、インフラ構成図を作成しやすくなりました。

[公式ドキュメント：Architecture Diagrams Documentation](https://mermaid.js.org/syntax/architecture.html)

デフォルトでは`cloud`、`database`、`server`、`disk`、`internet`の5つのアイコンが使用できます。([Github](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/diagrams/architecture/architectureIcons.ts#L8))

```mermaid
architecture-beta
  group cloud(cloud)[cloud]
    service db1(database)[Database] in cloud
    service server1(server)[server] in cloud
    service disk1(disk)[disk] in cloud

  group internet(internet)[internet]
    service db2(database)[Database] in internet
    service server2(server)[server] in internet
    service disk2(disk)[disk] in internet
    
  server2:R -- L:server1
  server1:B -- T:db1
  server1:R -- L:disk1
  server2:B -- T:db2
  server2:L -- R:disk2

```

また、別途追加手順は必要になりますが、AWSなどのカスタムアイコンを追加することもできますが、QiitaやGithubなどのWebサービスでは使用できないので注意してください。([参考ドキュメント](https://mermaid.js.org/syntax/architecture#icons))

本手法で直接的にAWSの画像やアイコンを使用したい場合は[画像URL指定方法](https://qiita.com/b-mente/items/89e900dab7319ef502be#%E7%94%BB%E5%83%8Furl%E6%8C%87%E5%AE%9A)を参考にしてください。

:::

## ・グループを描く

AWS Architecture Iconsでも様々なグループを示す枠がありますが、今回はよく使うグループをMermaid記法でどのように表現するかまとめてみました。

| Groups | Architecture Icons | Mermaid | Mermaid記法のスタイル |
| --- | --- | --- | --- |
| AWS Cloud | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/a1e6cecb-2dd1-1990-10be-d1b5cdb9f6c9.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/0ad3a744-45bf-87cf-fa5f-2941156ac96d.png" width="300"> | `fill:none,color:#345,stroke:#345` |
| Region | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/56a02e1a-4704-fcc2-85b3-3e1542d877dd.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/79e5de08-9179-cbb9-7b8c-4b49ce7add38.png" width="300"> | `fill:none,color:#59d,stroke:#59d,stroke-dasharray:3` |
| VPC | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/b577cc09-c1a3-822c-1793-bdd0fa9df318.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/e495f09c-fa4f-bb6a-4ba5-6b87eca37295.png" width="300"> | `fill:none,color:#0a0,stroke:#0a0` |
| Availability Zone | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/5fd0f32b-31b6-98fe-2ed5-7f3f08847caf.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/68863a66-3440-acd2-7f8a-413fd265d69b.png" width="300"> | `fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8` |
| Private subnet | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/f1c1ff00-a2d1-e2f1-fbfb-a7b6800e4bf8.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/dac969fc-1875-8581-5a4f-fb0cfe6ee9f3.png" width="300"> | `fill:#efe,color:#092,stroke:none` |
| Public subnet | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/e9059298-a383-1a1f-2baf-5bbea54bbe0a.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/9f339e32-1fbc-54ca-356b-18a8d6a1f1b9.png" width="300"> | `fill:#def,color:#07b,stroke:none` |

## ・グループのサンプル

分かりやすいように上記で記載した各グループをMermaid記法でグループのみ記述し、Qiita上で表現したのが下記になります。

```mermaid
flowchart

%%---グループの設定---

%%Public subnetのグループ
subgraph GS1[Public subnet]
end

%%Private subnetのグループ
subgraph GS2[Private subnet]
end

%%Availability Zoneのグループ
subgraph GA[Availability Zone]
end

%%VPCのグループ
subgraph GV[VPC]
end

%%Regionのグループ
subgraph GR[Region]
end

%%AWS Cloudのグループ
subgraph GC[AWS Cloud]
end

%%---スタイルの設定---

%%AWS Cloudのスタイル
classDef SGC fill:none,color:#345,stroke:#345
class GC SGC

%%Regionのスタイル
classDef SGR fill:none,color:#59d,stroke:#59d,stroke-dasharray:3
class GR SGR

%%VPCのスタイル
classDef SGV fill:none,color:#0a0,stroke:#0a0
class GV SGV

%%Availability Zoneのスタイル
classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
class GA SGA

%%Private subnetのスタイル
classDef SGPrS fill:#def,color:#07b,stroke:none
class GS2 SGPrS

%%Public subnetのスタイル
classDef SGPuS fill:#efe,color:#092,stroke:none
class GS1 SGPuS
```

上記のMermaid記法の記述は下記になります。

```:Mermaid記法
flowchart

%%---グループの設定---

%%Public subnetのグループ
subgraph GS1[Public subnet]
end

%%Private subnetのグループ
subgraph GS2[Private subnet]
end

%%Availability Zoneのグループ
subgraph GA[Availability Zone]
end

%%VPCのグループ
subgraph GV[VPC]
end

%%Regionのグループ
subgraph GR[Region]
end

%%AWS Cloudのグループ
subgraph GC[AWS Cloud]
end

%%---スタイルの設定---

%%AWS Cloudのスタイル
classDef SGC fill:none,color:#345,stroke:#345
class GC SGC

%%Regionのスタイル
classDef SGR fill:none,color:#59d,stroke:#59d,stroke-dasharray:3
class GR SGR

%%VPCのスタイル
classDef SGV fill:none,color:#0a0,stroke:#0a0
class GV SGV

%%Availability Zoneのスタイル
classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
class GA SGA

%%Private subnetのスタイル
classDef SGPrS fill:#def,color:#07b,stroke:none
class GS2 SGPrS

%%Public subnetのスタイル
classDef SGPuS fill:#efe,color:#092,stroke:none
class GS1 SGPuS
```

## ・サービスを描く

サービスはAWS Architecture Iconsのアイコンが使用できないので、ノードの色と形で模倣します。こちらもよく使うサービスをMermaid記法でどのように表現するのかまとめてみました。

| Service | Architecture Icons | Mermaid | Mermaid記法のスタイル | Mermaid記法のノード |
| --- | --- | --- | --- | --- |
| 外部要素 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/5ea471ea-a397-55fc-3d99-910e3badd77b.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/0adeefa2-190d-4d86-a77a-e5986ea704db.png" width="100"> | `fill:#aaa,color:#fff,stroke:#fff` | `[  ]` |
| Network関連 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/69018133-edf1-7fce-7e90-77fc6cd21e63.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/008a3f79-c699-18b0-7d8e-f3b9c4d440af.png" width="100"> | `fill:#84d,color:#fff,stroke:none` | `{{  }}` |
| Compute関連 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/9cbcbc88-f8aa-2958-e454-ccf029ffb104.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/ba5172e8-f1e0-350b-312c-8e4c22ca872e.png" width="100"> | `fill:#e83,color:#fff,stroke:none` | `(  )` |
| DB関連 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/df192b4f-8c62-ec18-7145-8883cf04bf1a.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/6b9cf505-3d27-e793-a060-4ea2571d89da.png" width="100"> | `fill:#46d,color:#fff,stroke:#fff` | `[(  )]` |
| Storage関連 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/1cfe8127-67ec-027b-a258-e0c8d28a32a1.png" width="200"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/cab9e0a1-893e-6022-1faf-632ba809e642.png" width="100"> | `fill:#493,color:#fff,stroke:#fff` | `[(  )]` |

## ・サービスのサンプル

分かりやすいように上記で紹介した各サービスをMermaid記法でサービスのみ記述し、Qiita上で表現したのが下記になります。

```mermaid
flowchart

%%---グループの設定---

%%Storage関連のグループ
subgraph GST[Storage関連]
  ST1[(S3)]
  ST2[(EBS)]
  ST3[(EFS)]
end

%%Database関連のグループ
subgraph GDB[Database関連]
  DB1[(RDS)]
  DB2[(Redshift)]
  DB3[(ElastiCache)]
end

%%Compute関連のグループ
subgraph GCP[Compute関連]
  CP1(EC2)
  CP2(ECS)
  CP3(Lambda)
end

%%Network関連のグループ
subgraph GNW[Network関連]
  NW1{{ELB}}
  NW2{{API Gateway}}
  NW3{{Kinesis}}
end

%%外部要素のグループ
subgraph GOU[外部要素]
  OU1[Users]
  OU2[Server]
  OU3[Client]
end

%%---スタイルの設定---

%%外部要素のスタイル
classDef SOU fill:#aaa,color:#fff,stroke:#fff
class OU1,OU2,OU3 SOU

%%Network関連のスタイル
classDef SNW fill:#84d,color:#fff,stroke:none
class NW1,NW2,NW3 SNW

%%Compute関連のスタイル
classDef SCP fill:#e83,color:#fff,stroke:none
class CP1,CP2,CP3 SCP

%%DB関連のスタイル
classDef SDB fill:#46d,color:#fff,stroke:#fff
class DB1,DB2,DB3 SDB

%%Storage関連のスタイル
classDef SST fill:#493,color:#fff,stroke:#fff
class ST1,ST2,ST3 SST

%%グループのスタイル
classDef SG fill:none,color:#666,stroke:#aaa
class GST,GDB,GCP,GNW,GOU SG
```

上記のMermaid記法の記述は下記になります。

```:Mermaid記法
flowchart

%%---グループの設定---

%%Storage関連のグループ
subgraph GST[Storage関連]
  ST1[(S3)]
  ST2[(EBS)]
  ST3[(EFS)]
end

%%Database関連のグループ
subgraph GDB[Database関連]
  DB1[(RDS)]
  DB2[(Redshift)]
  DB3[(ElastiCache)]
end

%%Compute関連のグループ
subgraph GCP[Compute関連]
  CP1(EC2)
  CP2(ECS)
  CP3(Lambda)
end

%%Network関連のグループ
subgraph GNW[Network関連]
  NW1{{ELB}}
  NW2{{API Gateway}}
  NW3{{Kinesis}}
end

%%外部要素のグループ
subgraph GOU[外部要素]
  OU1[Users]
  OU2[Server]
  OU3[Client]
end

%%---スタイルの設定---

%%外部要素のスタイル
classDef SOU fill:#aaa,color:#fff,stroke:#fff
class OU1,OU2,OU3 SOU

%%Network関連のスタイル
classDef SNW fill:#84d,color:#fff,stroke:none
class NW1,NW2,NW3 SNW

%%Compute関連のスタイル
classDef SCP fill:#e83,color:#fff,stroke:none
class CP1,CP2,CP3 SCP

%%DB関連のスタイル
classDef SDB fill:#46d,color:#fff,stroke:#fff
class DB1,DB2,DB3 SDB

%%Storage関連のスタイル
classDef SST fill:#493,color:#fff,stroke:#fff
class ST1,ST2,ST3 SST

%%グループのスタイル
classDef SG fill:none,color:#666,stroke:#aaa
class GST,GDB,GCP,GNW,GOU SG
```

## ・AWS構成図のサンプル

冒頭で紹介したAWSの構成図ですが、最初にどんな構成図が作れるのかイメージを持ってもらうために便宜上グループをくどいくらい記述しています。

通常はわざわざRegionやAZを記載しない上にEC2などのサービスも複数使用しているためタグ名などを表示しているかと思いますので、もう少し通常使う記載に寄せたAWSの構成図のサンプルを紹介します。

```mermaid
flowchart LR

%%外部要素のUser
OU1[User]

%%グループとサービス
subgraph GC[AWS]
  subgraph GV[vpc-sc1]
    subgraph GS1[subnet-1]
      NW1{{"ELB<br>web1"}}
    end
    subgraph GS2[subnet-2]
      CP1("EC2<br>web1")
    end
    DB1[("RDS<br>db1")]
  end
  ST1[("S3<br>xx.com")]
end

%%サービス同士の関係
OU1 --> NW1
NW1 --> CP1
CP1 --> DB1
DB1 -.-> ST1

%%グループのスタイル
classDef SGC fill:none,color:#345,stroke:#345
class GC SGC

classDef SGV fill:none,color:#0a0,stroke:#0a0
class GV SGV

classDef SGPrS fill:#def,color:#07b,stroke:none
class GS2 SGPrS

classDef SGPuS fill:#efe,color:#092,stroke:none
class GS1 SGPuS

%%サービスのスタイル
classDef SOU fill:#aaa,color:#fff,stroke:#fff
class OU1 SOU

classDef SNW fill:#84d,color:#fff,stroke:none
class NW1 SNW

classDef SCP fill:#e83,color:#fff,stroke:none
class CP1 SCP

classDef SDB fill:#46d,color:#fff,stroke:#fff
class DB1 SDB

classDef SST fill:#493,color:#fff,stroke:#fff
class ST1 SST
```

上記のMermaid記法の記述は下記になります。

```:Mermaid記法
flowchart LR

%%外部要素のUser
OU1[User]

%%グループとサービス
subgraph GC[AWS]
  subgraph GV[vpc-sc1]
    subgraph GS1[subnet-1]
      NW1{{"ELB<br>web1"}}
    end
    subgraph GS2[subnet-2]
      CP1("EC2<br>web1")
    end
    DB1[("RDS<br>db1")]
  end
  ST1[("S3<br>xx.com")]
end

%%サービス同士の関係
OU1 --> NW1
NW1 --> CP1
CP1 --> DB1
DB1 -.-> ST1

%%グループのスタイル
classDef SGC fill:none,color:#345,stroke:#345
class GC SGC

classDef SGV fill:none,color:#0a0,stroke:#0a0
class GV SGV

classDef SGPrS fill:#def,color:#07b,stroke:none
class GS2 SGPrS

classDef SGPuS fill:#efe,color:#092,stroke:none
class GS1 SGPuS

%%サービスのスタイル
classDef SOU fill:#aaa,color:#fff,stroke:#fff
class OU1 SOU

classDef SNW fill:#84d,color:#fff,stroke:none
class NW1 SNW

classDef SCP fill:#e83,color:#fff,stroke:none
class CP1 SCP

classDef SDB fill:#46d,color:#fff,stroke:#fff
class DB1 SDB

classDef SST fill:#493,color:#fff,stroke:#fff
class ST1 SST
```

## ・AWS-CLIを使ってEC2の配置図をつくる

AWS-CLIを使うとEC2やVPCやAZ、Subnetの情報が取得できるので、コンソール上でAWS-CLIと組み合わせたコマンドを使用して簡単な配置図のようなものを作ることができます。

下記はAWS-CLIのEC2情報(`describe-instances`)の情報を元に配置図を作るコマンドです。長いですがテキストをコピーしてAWS-CLIの使えるコンソールに貼り付けるとMermaid記法の記述が出力されます。
```bash:Mermaid記法を出力をするためのコマンド
aws ec2 describe-instances \
  --output text \
  --query \
  'Reservations[*].Instances[*].{N1:NetworkInterfaces[0].VpcId, N2:Placement.AvailabilityZone, N3:NetworkInterfaces[0].SubnetId, N4:Tags[?Key==`Name`]|[0].Value, N5:State.Name, N6:LaunchTime, N7:InstanceId, N8:PrivateIpAddress}' \
| sort -t$'\t' \
| perl -F'\t' -alne 'BEGIN{@s=("GV","GA","GS")};for($i=0;$i<3;$i++){ if($mv[$i] ne $F[$i]){$mc[$i]++;$c=0;for($m=1,$k=$mc[0];$m<=$i;$m++){$k.="_$mc[$m]"};for(;$m<3;$m++){($mv[$m],$mc[$m])=("",0)};if($mv[$i]){for($e=$l;$e>=$i;$e--){print " "x$e."end";}print "$s[$i]".($mc[$i]-1)."---$s[$i]$mc[$i]" if $i==0};print " "x$i."subgraph $s[$i]${k}[$F[$i]]";$l=$i }};$c++;print "   CP${k}_${c}(tag:$F[3]<br>id:$F[6]<br>ip:$F[7])";print "   CP${k}_".($c-1)."---CP${k}_${c}" if $c>1 && $mc[2]==1;@mv=splice(@F,0,3);END{print "  end\n end\nend";}' \
| cat <(cat <<EOF
%%{init:{'themeVariables':{'lineColor':'#000ff'}}}%%
flowchart TB
EOF
) - <(cat <<EOF
classDef SGV fill:none,color:#0a0,stroke:#0a0
classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
classDef SGS fill:#def,color:#07b,stroke:none
classDef SCP fill:#e83,color:#fff,stroke:none
EOF
) \
| perl -ple 'push @{$l{$2}},$1 if / (([A-Z]+)[\d_]+?)[\[\(]/;END{foreach (keys %l){print "class ".join(",",@{$l{$_}})." S$_"}}'
```

上記のコマンドを実行した結果を部分的にマスクしたサンプルが下記になります。

```:コマンド出力結果のサンプル
%%{init:{'themeVariables':{'lineColor':'#000ff'}}}%%
flowchart TB
subgraph GV1[vpc-xxx]
 subgraph GA1_1[ap-northeast-1a]
  subgraph GS1_1_1[subnet-xxx]
   CP1_1_1_1(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP1_1_1_2(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP1_1_1_1---CP1_1_1_2
  end
 end
end
GV1---GV2
subgraph GV2[vpc-xxx]
 subgraph GA2_1[ap-northeast-1a]
  subgraph GS2_1_1[subnet-xxx]
   CP2_1_1_1(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_1_2(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_1_1---CP2_1_1_2
  end
  subgraph GS2_1_2[subnet-xxx]
   CP2_1_2_1(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_2_2(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_2_3(tag:xxx<br>id:i-xxx<br>ip:xxx)
  end
 end
end
classDef SGV fill:none,color:#0a0,stroke:#0a0
classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
classDef SGS fill:#def,color:#07b,stroke:none
classDef SCP fill:#e83,color:#fff,stroke:none
class GV1,GV2 SGV
class GS1_1_1,GS2_1_1,GS2_1_2 SGS
class GA1_1,GA2_1 SGA
class CP1_1_1_1,CP1_1_1_2,CP2_1_1_1,CP2_1_1_2,CP2_1_2_1,CP2_1_2_2,CP2_1_2_3 SCP
```

上記のコマンドで出力されたMermaid記法の記述をQiitaで表現したのが下記になります。

```mermaid
%%{init:{'themeVariables':{'lineColor':'#000ff'}}}%%
flowchart TB
subgraph GV1[vpc-xxx]
 subgraph GA1_1[ap-northeast-1a]
  subgraph GS1_1_1[subnet-xxx]
   CP1_1_1_1(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP1_1_1_2(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP1_1_1_1---CP1_1_1_2
  end
 end
end
GV1---GV2
subgraph GV2[vpc-xxx]
 subgraph GA2_1[ap-northeast-1a]
  subgraph GS2_1_1[subnet-xxx]
   CP2_1_1_1(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_1_2(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_1_1---CP2_1_1_2
  end
  subgraph GS2_1_2[subnet-xxx]
   CP2_1_2_1(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_2_2(tag:xxx<br>id:i-xxx<br>ip:xxx)
   CP2_1_2_3(tag:xxx<br>id:i-xxx<br>ip:xxx)
  end
 end
end
classDef SGV fill:none,color:#0a0,stroke:#0a0
classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
classDef SGS fill:#def,color:#07b,stroke:none
classDef SCP fill:#e83,color:#fff,stroke:none
class GV1,GV2 SGV
class GS1_1_1,GS2_1_1,GS2_1_2 SGS
class GA1_1,GA2_1 SGA
class CP1_1_1_1,CP1_1_1_2,CP2_1_1_1,CP2_1_1_2,CP2_1_2_1,CP2_1_2_2,CP2_1_2_3 SCP
```

上記は標準出力された内容をQiitaに貼り付けていますが、そのまま標準出力をリダイレクトでファイルに出力してMermaidコマンドで画像ファイルを出力することもできます。
Mermaidコマンドについては[[ザックリ解説 - コマンドでmermaidが使える]](https://qiita.com/b-mente/items/97a4296666faccd53a72#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7mermaid%E3%81%8C%E4%BD%BF%E3%81%88%E3%82%8B)か[[公式ドキュメント]](https://github.com/mermaid-js/mermaid-cli#readme)を参照してください。

```bash:Mermaid記法をファイルに出力してpngファイルを作成するコマンド
$ aws ec2 describe-instances \
  --output text \
  --query \
  'Reservations[*].Instances[*].{N1:NetworkInterfaces[0].VpcId, N2:Placement.AvailabilityZone, N3:NetworkInterfaces[0].SubnetId, N4:Tags[?Key==`Name`]|[0].Value, N5:State.Name, N6:LaunchTime, N7:InstanceId, N8:PrivateIpAddress}' \
| sort -t$'\t' \
| perl -F'\t' -alne 'BEGIN{@s=("GV","GA","GS")};for($i=0;$i<3;$i++){ if($mv[$i] ne $F[$i]){$mc[$i]++;$c=0;for($m=1,$k=$mc[0];$m<=$i;$m++){$k.="_$mc[$m]"};for(;$m<3;$m++){($mv[$m],$mc[$m])=("",0)};if($mv[$i]){for($e=$l;$e>=$i;$e--){print " "x$e."end";}print "$s[$i]".($mc[$i]-1)."---$s[$i]$mc[$i]" if $i==0};print " "x$i."subgraph $s[$i]${k}[$F[$i]]";$l=$i }};$c++;print "   CP${k}_${c}(tag:$F[3]<br>id:$F[6]<br>ip:$F[7])";print "   CP${k}_".($c-1)."---CP${k}_${c}" if $c>1 && $mc[2]==1;@mv=splice(@F,0,3);END{print "  end\n end\nend";}' \
| cat <(cat <<EOF
%%{init:{'themeVariables':{'lineColor':'#000ff'}}}%%
flowchart TB
EOF
) - <(cat <<EOF
classDef SGV fill:none,color:#0a0,stroke:#0a0
classDef SGA fill:none,color:#59d,stroke:#59d,stroke-width:1px,stroke-dasharray:8
classDef SGS fill:#def,color:#07b,stroke:none
classDef SCP fill:#e83,color:#fff,stroke:none
EOF
) \
| perl -ple 'push @{$l{$2}},$1 if / (([A-Z]+)[\d_]+?)[\[\(]/;END{foreach (keys %l){print "class ".join(",",@{$l{$_}})." S$_"}}' > input.mmd
$ 
$ mmdc -i input.mmd -o output.png
$ 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699056/63d587f6-e7bd-053e-719d-ab0a0130c94e.png)
また、VPCやSubnetなどはIDしか表示されていないので、もしタグなどに変更したい場合はAWS-CLIの`describe-vpcs`や`describe-subnets`などで取得できるIDとタグ情報を元に、追加で置換して見やすくすることもできます。

# おわりに

先日投稿した[[ザックリ解説]](https://qiita.com/b-mente/items/97a4296666faccd53a72)を見てMermaid面白そうと感じてもらえた方や、AWS構成図をコード管理したい、AWS構成図や配置図を自動生成したい方の参考になれば幸いです。

また、Mermaidは他のモノと組み合わせて使うことで活用範囲が広がっていくので、本稿を読んで興味を持って頂けたらAWS構成図に限らず色々な図の作成にトライしてみてください。
(Mermaid記法は[QiitaやGithubでも手軽に確認できます](https://qiita.com/b-mente/items/97a4296666faccd53a72#web%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%A7mermaid%E3%81%8C%E4%BD%BF%E3%81%88%E3%82%8B))

[^1]:https://plantuml.com/ja/stdlib#a464d2f6236a5c23 
[^2]:https://github.com/mermaid-js/mermaid/issues/1435