【Mermaid】Azureのアーキテクチャ図をMermaidで書いてみるよ！🧜‍♀️

## はじめに
システム設計やアーキテクチャを説明する際、図解が必要になることが多々あるかと思います。
この記事ではコードで図を描ける「Mermaid」を使って、Azureのアーキテクチャ図を描いて得た知見を共有します。

## Mermaidとは
https://mermaid.js.org/

Mermaidはダイアグラムやチャートを作成でき、GitHubやVSCode、Notion等で利用可能で、簡単に図を描くことができます。
↓Qiitaも対応しており、このような図をさくっと作成することができます。
```
graph LR;
    A--> B & C & D;
    B--> A & E;
    C--> A & E;
    D--> A & E;
    E--> B & C & D;
```

```mermaid
graph LR;
    A--> B & C & D;
    B--> A & E;
    C--> A & E;
    D--> A & E;
    E--> B & C & D;
```

```
sequenceDiagram
    Alice->>Bob: Hello Bob, how are you ?
    Bob->>Alice: Fine, thank you. And you?
    create participant Carl
    Alice->>Carl: Hi Carl!
    create actor D as Donald
    Carl->>D: Hi!
    destroy Carl
    Alice-xCarl: We are too many
    destroy Bob
    Bob->>Alice: I agree
```

```mermaid
sequenceDiagram
    Alice->>Bob: Hello Bob, how are you ?
    Bob->>Alice: Fine, thank you. And you?
    create participant Carl
    Alice->>Carl: Hi Carl!
    create actor D as Donald
    Carl->>D: Hi!
    destroy Carl
    Alice-xCarl: We are too many
    destroy Bob
    Bob->>Alice: I agree
```


## architecture-betaについて
Architecture Diagrams Documentation (v11.1.0+)

https://mermaid.js.org/syntax/architecture

mermaid.js v11.1.0+にて「Architecture Diagrams」という構文が追加されたらしく、これを使って案件のAzure構成図を作ればコード管理もできて運用が楽になりそうだなと触ってみることにしました。

調べたところ今回対象となる「architecture-beta」についてですが、まだまだ構文に対応していないサービスが多いためVscodeで検討してみることにしました。

## 公式サンプル
```
architecture-beta
    group api(cloud)[API]

    service db(database)[Database] in api
    service disk1(disk)[Storage] in api
    service disk2(disk)[Storage] in api
    service server(server)[Server] in api

    db:L -- R:server
    disk1:T -- B:server
    disk2:T -- B:db

```

```mermaid
architecture-beta
    group api(cloud)[API]

    service db(database)[Database] in api
    service disk1(disk)[Storage] in api
    service disk2(disk)[Storage] in api
    service server(server)[Server] in api

    db:L -- R:server
    disk1:T -- B:server
    disk2:T -- B:db
```
Qiitaも「architecture-beta」に対応しているため、
これくらいの簡易的な構成図であれば画像を用意する必要なく作れるのは素晴らしいですね。


次は、凝った構成図を作れるのか確認してみましょう。
AzureサービスでVnetを跨いだサービスや複数のSubnetが存在するアーキテクチャ構成図を作ってみることにします。

```mermaid
architecture-beta
    group azure(azure:resource-groups)[Azure]
    group vnet(azure:virtual-networks)[VNet] in azure
    group subnet1(azure:subnet)[Subnet1] in vnet
        service vintegration1[VNet Integration] in subnet1
        group appserviceplan(azure:app-service-plans)[App Service Plan] in azure
        service appservice(azure:app-services)[App Service] in appserviceplan
    group subnet2(azure:subnet)[Subnet2] in vnet
        service pep(azure:private-endpoints)[Private Endpoint] in subnet2
    group subnet3(azure:subnet)[Subnet3] in vnet
        service vintegration3[VNet Integration] in subnet3
    group subnet4(azure:subnet)[Subnet4] in vnet
        service vintegration4[VNet Integration] in subnet4
    group resource[Resources] in vnet
        service aisearch(azure:cognitive-services)[Azure AI Search] in resource
        service openai(azure:azure-openai)[Azure OpenAI] in resource
        service cosmosdb(azure:azure-cosmos-db)[Cosmos DB] in resource
        service storageaccount(azure:storage-accounts)[Azure Storage Account] in resource
        service documentintelligence(azure:form-recognizers)[Document Intelligence] in resource

    group langfuse(azure:container-apps-environments)[Azure Container Apps Environment] in azure
        service langfuse1(azure:worker-container-app)[LangFuse] in langfuse
    service postgres(azure:azure-database-postgresql-server)[Azure Database for PostgreSQL] in azure
    
    appservice:R <--> L:vintegration1{group}
    vintegration1{group}:R --> L:pep{group}

    pep:B --> T:cosmosdb{group}

    langfuse1:R <--> L:vintegration3{group}
    postgres:R <--> L:vintegration4{group}
    langfuse1:B <--> T:postgres
```
私の書き方が悪いのか、まだbeta版だからなのか
保存する毎にデザインが変わってしまいます。
Aパターン
![スクリーンショット 2024-12-15 20.49.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516184/baedbf71-b3ad-8545-c156-1fdbc5eaae1d.png)
Bパターン
![スクリーンショット 2024-12-15 20.49.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516184/36033dad-6701-4298-ebc9-982c75b9cb4f.png)

Mermaidの良さはdrow.ioやcacooなど他のダイアグラム作成ツールと違い、デザインを意識することなく作成することのできる点だと個人的に思っているため、ある程度複雑な図を作ろうとすると枠線や矢印を動かしたくなるため今後のアップデートで改善されることを期待しています。(まだbeta版ですしね）

## アイコンの変え方
現時点でMermaidがデフォルトで対応しているアイコンはcloud, database, disk, internet, server の5つになります。Qiitaに関しても5つのアイコンのみのようです。

アイコンを追加するにはいくつかの手法があるのですが、VScodeの拡張でも設定ができるようです。

- Markdown Preview Enhanced

https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced

こちらの拡張機能を使うことでMermaidのコードを図へ変換し確認することができます。

1. コマンドパレットから Markdown Preview Enhanced: Customize Preview Html Head を選択して、head.html ファイルを開く
1. head.html ファイルを下記のように編集する

```html
  <script type="text/javascript">
    const configureMermaidIconPacks = () => {
      window["mermaid"].registerIconPacks([
        {
          name: "azure",
          loader: () => fetch("https://unpkg.com/azureiconkento@1.1.1/azureicons/allicons.json").then((res) => res.json())
        },
        {
          name: "logos",
          loader: () => fetch("https://unpkg.com/@iconify-json/logos/icons.json").then((res) => res.json())
        }
      ]);
    };
    
    if (document.readyState !== 'loading') {
      configureMermaidIconPacks();
    } else {
      document.addEventListener("DOMContentLoaded", () => {
        configureMermaidIconPacks();
      });
    }
    </script>
```


Azureのアイコンをnpmで公開されている方がいたのでそちらを利用しています。

https://www.kentsu.website/ja/posts/2024/iconfy_customicon/

やったね！アイコンが変わるだけで構成図が５割り増しでいい感じに見えます。
![スクリーンショット 2024-12-15 21.13.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516184/3f7452ac-cfb9-ac95-bd00-f9ced81dbc9c.png)


## まとめ
今回初めてMermaidの「architecture-beta」を利用して構成図を書いてみたのですが、
まだベータ版だからなのかできることがシンプルで非常に描きやすく迷うことがあまりなかったです。
しかし、作成後のデザインが安定しておらず、矢印や枠線が重なり合ったりするため複雑な図を書くのは難しそうです。

クラウドサービスのアイコンはデザインが一新されたり、新しいサービスが追加されたりすることも多いため
容易にアイコンを追加できると嬉しいのですが、現状のMermaidだとアイコンを追加するのに結構ハードルあるのが悩ましいですね。

自プロジェクトでは現在アーキテクチャ図にCacooを利用しているのですが、Git化とかが目的であれば
draw.ioのVSCode拡張とかの方が良かったりするのかもしれません。

以上です！

ではでは！