DiagramsでAWS構成図をパッと記載しよう！

## 概要
突然ですが、AWS構成図は皆さんどうしていますか？
コーディングで構成図を作成する方法を最近知ったので、本記事で紹介します！

AWSアーキテクチャ図を手軽に可視化できるので、インフラ設計の効率化に役立ちます！

##  Diagramsとは？
- Pythonでインフラ図を作成できるライブラリ
- コードを実行するとPNGファイル等として出力が可能

公式サイト：

https://diagrams.mingrammer.com/

## メリット・デメリット
### メリット
- AWSだけでなくGCP、Azureなどの構成図も対応可
- コードでリソース管理できるので、変更等が柔軟に！
- ソースなのでバージョンGitで管理も可能

### デメリット
- AWSのアイコンが一部存在しない
  - IoT Core, Bedrock、Local Zones等 (2024年現在)
  - https://diagrams.mingrammer.com/docs/nodes/aws
- 複雑な設計になるとコーディングに時間がかかる 

こう見るとかなり複雑な構成になるのであれば、
draw.ioなどの使用を検討してもいいかもしれません。

ただ個人的にはコーディングで作成も楽しいですし、
選択肢が増えるのは良いことかと思います！

## コーディング準備
### Diagramsのインストール

```
pip install diagrams
```

### Graphvizインストール
Graphvizというライブラリも必要になります。
テキストデータをグラフ画像に変換するツールになります。

```
sudo apt-get install graphviz
```



## 実際に作成してみよう！
では実際に記載してみましょう。
まずは公式を参考に、EC2等をいくつか書いてみましょう。

### 例

```sample.py
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Grouped Workers", show=False, direction="TB"):
    ELB("lb") >> [EC2("worker1"),
                  EC2("worker2"),
                  EC2("worker3"),
                  EC2("worker4"),
                  EC2("worker5")] >> RDS("events")

```
### コード解説
- name: 図の名前(ここではGrouped Workers)
- filename: ファイル名(デフォルト: nameによって決まる)
- outformat: 図の保存形式(デフォルト: png)
  - png、jpg、pdfなど
- show: スクリプト実行時に作成した図を表示するか(デフォルト: True)
- direction: データフローの向き
  - TB、BT、LR、RL

:::note info
#### directionについて
- TB (Top to Bottom): 上から下への配置
- BT (Bottom to Top): 下から上への配置
- LR (Left to Right): 左から右への配置
- RL (Right to Left): 右から左への配置

例えば、direction="LR" を設定すると、ノードが左から右へ順に並びます。
:::


### 上記コードを実行

```
python3 sample.py
```

### 出力画像

![スクリーンショット 2024-10-28 0.04.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/fd22bda0-3b12-84f7-ded4-391a60a296b0.png)


実行が完了すると、作成した図が表示されます。
png形式で画像がPythonコードと同じ場所に出力されます。


## AWS以外にも記載可能
### Kubernetes

```k8s.py
from diagrams import Diagram
from diagrams.k8s.clusterconfig import HPA
from diagrams.k8s.compute import Deployment, Pod, ReplicaSet
from diagrams.k8s.network import Ingress, Service

with Diagram("Exposed Pod with 3 Replicas", show=False):
    net = Ingress("domain.com") >> Service("svc")
    net >> [Pod("pod1"),
            Pod("pod2"),
            Pod("pod3")] << ReplicaSet("rs") << Deployment("dp") << HPA("hpa")
```

### 結果

Exposed Pod with 3 Replicas on Kubernetes

![スクリーンショット 2024-10-28 0.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/1e9b8db7-577b-1d77-1901-2e0f8cce4dc7.png)

## k8s + AWS + Monitoring
一時期私が個人開発で使用していた設計を思い出して書いてみました。
監視やKubernetesの混合です。

### 構成
#### AWSリソース

- VPC: ネットワークの基盤となる仮想NW
- Public Subnet: インターネットアクセスを必要とするリソース（NLBやGrafana）を配置
- Private Subnet: Kubernetesクラスタのワーカーやデータベースなど、内部専用リソースを配置
- NAT Gateway: プライベートサブネットからインターネット接続を提供
- RDS: MySQLを使用したDB

#### Kubernetesクラスタ
- Node Group: アプリケーションを稼働するためのワーカーノードグループ
- Prometheus: メトリクスを収集するモニタリングサービス
- Grafana: Prometheusからメトリクスを取得し、視覚化して監視


### コード

```develop.py
from diagrams import Diagram, Cluster, Edge
from diagrams.aws.network import VPC, PublicSubnet, PrivateSubnet, NATGateway, InternetGateway
from diagrams.aws.database import RDS
from diagrams.aws.compute import EKS
from diagrams.k8s.compute import Pod
from diagrams.k8s.controlplane import API
from diagrams.k8s.network import Ingress, Service
from diagrams.onprem.monitoring import Prometheus, Grafana

with Diagram("Modern Kubernetes on AWS with Grafana Monitoring", direction="TB"):

    # AWS Infrastructure
    with Cluster("AWS Cloud"):
        vpc = VPC("VPC")

        igw = InternetGateway("Internet Gateway")
        nat_gw = NATGateway("NAT Gateway")
        
        with Cluster("Public Subnet"):
            public_subnet = PublicSubnet("Public Subnet")
            grafana = Grafana("Grafana")
            nlb = Service("Network Load Balancer")
            
        with Cluster("Private Subnet"):
            private_subnet = PrivateSubnet("Private Subnet")
            rds = RDS("Database")

            with Cluster("Kubernetes Cluster"):
                eks = EKS("EKS Cluster")
                with Cluster("Node Group"):
                    app_pod = Pod("App Pod")
                    ingress = Ingress("Ingress Controller")
                    prometheus = Prometheus("Prometheus")
                    
                    # Application Pod and Services
                    app_pod - Edge(label="Metrics") - prometheus
                    prometheus >> Edge(label="Metrics") >> grafana

        # Networking Connections
        vpc >> igw
        vpc >> public_subnet >> nlb >> ingress >> eks
        eks >> private_subnet

```

### 結果

![スクリーンショット 2024-10-28 0.18.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/8d35d07c-d820-10a9-8008-b5e2e6c90135.png)

## まとめ
こんな感じでAWSを始めとした様々な構成図を
コーディング可能です！

業務はもちろん、個人開発や提案資料などにも何かと便利です！
紹介した内容以外にも、公式にコーディング例がありますので
参考になれば幸いです！

https://diagrams.mingrammer.com/docs/getting-started/examples