Amazon VPC SecurityGroupのルールの内訳を生成AIを活用してMermaid記法で可視化してみた
コンバンハ、千葉(幸)です。
Amazon VPCのSecurityGroupを管理していく中で、直感的にその内容を把握しづらい、と感じることがあります。例えば自分が新規にプロジェクトに参画するなどの場面で、SecurityGroupルールの全体像がパッと図で見れたら助かるのにな……と思うこともあります。
SecurityGroupの一覧やルールの詳細はAWSマネジメントコンソールからCSV形式でダウンロードできます。
「これをうまいことMermaid記法で描画できれば分かりやすいのでは?」「CSVファイルを元にしてChatGPTなどのAIツールにMermaidのコードを書いてもらえれば楽できるのでは?」 とふと思ったので、どんな形になるか少し試してみました。
こんな感じのものが出来上がりました。
割といい感じ
先にまとめ
-
AWSマネジメントコンソールからSecurityGroupの情報をCSV形式でダウンロードできる
- 一度のダウンロードに含められるのは最大で50個のSecurityGroupまで
- SecurityGroup単位での情報と、SecurityGroup内のルールまで含めた情報を選択できる
-
Mermaid記法のコードのプレビューや画像のエクスポートは以下で行える
-
SecurityGroupの数が多いとコードの生成に時間がかかるし見栄えもあまり良くないので、一度に描画するのは20個未満程度に抑えたほうが良さそう
- もちろんルール数などにもよるので一概には言えない
実行環境
今回わたしが試したのは以下環境ですが、大抵の他の環境でも同様のことは実現できるかと思います。
- 使用ツール(インターフェース):AI-Starter
- モデル:Claude 3.7 Sonnet
全体の流れ
- SecurityGroup情報のCSVファイルを取得する
- (AWSマネジメントコンソールからのダウンロードを想定しているが、独自にAWS CLIなどで取得するのも可)
- 任意のAIチャットツールにCSVファイルとプロンプトを入力し、Mermaidコードを生成してもらう
- 生成されたMermaidコードを任意のツールで描画する
生成してもらったMermaidコードの描画イメージ
いくつかイメージを載せておきます。
対象SecurityGroup8個、凡例以外のサブグラフ(黄色くグルーピングしている部分)なしのパターン。(冒頭の再掲)
対象SecurityGroup15個、VPC単位でサブグラフをグループ化したパターン。
せっかくなのでこのパターンの実際のコードも載せておきます。
flowchart LR
%% スタイル定義
classDef sgStyle fill:#e6e6fa,stroke:#333,stroke-width:1px
classDef sgWithPublicAccess fill:#e6e6fa,stroke:#ff0000,stroke-width:2px
classDef cidrStyle fill:#d0f0c0,stroke:#333,stroke-width:1px
classDef publicStyle fill:#ffcccb,stroke:#333,stroke-width:1px
classDef prefixStyle fill:#ffdead,stroke:#333,stroke-width:1px
%% 凡例
subgraph 凡例
legend_sg1[SecurityGroup]:::sgStyle
legend_sg2[SecurityGroup]:::sgStyle
legend_sg3[公開SG]:::sgWithPublicAccess
legend_cidr[/CIDRブロック/]:::cidrStyle
legend_public[/0.0.0.0/0/]:::publicStyle
legend_prefix[/プレフィックスリスト/]:::prefixStyle
legend_sg1 --> |インバウンド| legend_sg2
legend_sg2 -.->|アウトバウンド| legend_sg1
end
%% SecurityGroups
sg1["1: tokyo192-pub"]:::sgWithPublicAccess
sg2["2: default"]:::sgStyle
sg3["3: vpce-sg"]:::sgStyle
sg4["4: tokyo192-efs"]:::sgStyle
sg5["5: launch-wizard-1"]:::sgStyle
sg6["6: tokyo192-pri"]:::sgStyle
sg7["7: tokyo192-client-vpn"]:::sgStyle
sg8["8: default"]:::sgStyle
sg9["9: EC2ContainerService-default-EcsSecurityGroup-MXC94ZLRB2GW"]:::sgWithPublicAccess
sg10["10: launch-wizard-4"]:::sgStyle
sg11["11: default"]:::sgStyle
sg12["12: d-95671b938e_workspacesMembers"]:::sgStyle
sg13["13: launch-wizard-2"]:::sgStyle
sg14["14: tokyo192"]:::sgStyle
sg15["15: default"]:::sgStyle
%% CIDRs
cidr1[/0.0.0.0/0/]:::publicStyle
cidr2[/::/0/]:::publicStyle
cidr3[/10.0.0.0/16/]:::cidrStyle
cidr4[/13.x.x.x/32/]:::cidrStyle
cidr5[/3.x.x.x/29/]:::cidrStyle
cidr6[/x.x.x.x/32/]:::cidrStyle
cidr7[/192.168.0.0/16/]:::cidrStyle
cidr8[/x.x.x.x/32/]:::cidrStyle
cidr9[/5.x.x.x/32/]:::cidrStyle
%% VPC単位でサブグラフ化
subgraph "vpc-0e4acafc38414468c"
sg1
sg4
sg6
sg7
sg8
sg10
sg12
sg14
end
subgraph "vpc-0f4af0dd9672f6eb1"
sg2
sg9
end
subgraph "vpc-07ea4b9ce269fce6a"
sg3
sg11
sg13
end
subgraph "vpc-09beb440a1e665383"
sg5
sg15
end
%% sg1 connections
cidr1 -->|TCP 80| sg1
sg1 -.->|すべて| cidr1
sg1 -.->|すべて| cidr2
%% sg2 connections
sg2 -->|すべて| sg2
sg2 -.->|すべて| cidr1
%% sg3 connections
cidr3 -->|TCP 443| sg3
%% sg4 connections
sg14 -->|TCP 2049| sg4
sg4 -.->|すべて| cidr1
sg4 -.->|すべて| cidr2
%% sg5 connections
cidr4 -->|TCP 3389| sg5
sg5 -.->|すべて| cidr1
sg5 -.->|すべて| cidr2
%% sg6 connections
sg14 -->|TCP 1024-1064| sg6
sg14 -->|すべて| sg6
sg7 -->|TCP 22| sg6
%% sg7 connections
sg7 -.->|すべて| cidr1
%% sg8 connections
sg14 -->|TCP 443| sg8
sg8 -.->|すべて| cidr1
sg8 -.->|すべて| cidr2
%% sg9 connections
cidr1 -->|TCP 80| sg9
sg9 -.->|すべて| cidr1
%% sg10 connections
sg10 -.->|すべて| cidr1
sg10 -.->|すべて| cidr2
%% sg11 connections
sg11 -->|すべて| sg11
sg13 -->|TCP 3306| sg11
sg13 -->|TCP 443| sg11
sg11 -.->|すべて| cidr1
%% sg12 connections
sg12 -.->|すべて| cidr1
sg12 -.->|すべて| cidr2
%% sg13 connections
cidr5 -->|TCP 22| sg13
sg13 -.->|すべて| cidr1
%% sg14 connections
cidr6 -->|TCP 80| sg14
cidr7 -->|TCP 80| sg14
cidr8 -->|すべて| sg14
cidr6 -->|TCP 22| sg14
cidr6 -->|TCP 3128| sg14
cidr9 -->|ICMP| sg14
cidr6 -->|TCP 3389| sg14
sg14 -.->|すべて| cidr1
sg14 -.->|すべて| cidr2
%% sg15 connections
sg5 -->|TCP 0-65535| sg15
sg15 -->|ICMP| sg15
sg15 -.->|すべて| cidr1
sg15 -.->|すべて| cidr2
SecurityGroupが100個以上ある環境で、対象のSecurityGroupを一貫性なく25個程度選択して描画したパターン。(全量おさまらないので一部抜粋。)
25個の対象のSecurityGroupのルールの宛先/送信元になっている他のSecurityGroupも描画されるので、割とカオスになった。ある程度のまとまりで対象を選ばないとそうなりそう
SecurityGroupルールの内訳を生成AIにいい感じにMermaidコードで書いてもらう
1. SecurityGroup CSVファイルの取得
AWSマネジメントコンソールの「EC2」もしくは「VPC」の画面からSecurityGroup一覧画面に遷移します。
一覧画面でエクスポートが行えます。
- A.セキュリティグループを CSV にエクスポート
- SecurityGroupルールの内訳は含まれない(ルール数までは分かる)
- 説明、タグ、VPCなどの情報が含まれる
- B.セキュリティグループのインバウンド / アウトバウンドルールを CSV にエクスポート
- SecurityGroupルールの内訳が含まれる
- SecurityGroup自体の情報はグループID、グループ名のみ含まれる
いずれもコンソールの一覧画面でチェックを入れたSecurityGroupのみが対象になります。SecurityGroupが大量にある場合にはフィルタリングをした上で選択する、などのコントロールをすると良いでしょう。
また、一度に表示できるSecurityGroupの数は最大50であり、まとめてチェックできる数もそれに準じるため、一度にCSVにエクスポートできる数も50となります。それより多くのSecurityGroupの情報を取得したい場合、「複数回に分けてエクスポートし結合」「AWS CLIで独自に取得するコマンドを作成」などで対応しましょう。
後続の手順で入力するプロンプト次第ではありますが、ひとまずA,B両方の情報をエクスポートしておくとよいでしょう。
2. 生成AIのチャットツールに情報を渡してMermaidコードを生成してもらう
任意のツールを用いて、Memaid記法のコードを生成してもらいましょう。
いきなり生成を依頼してもいいですが、まずは必要な情報を提示してもらい、その中から取捨選択してコードの生成対象としてもらう流れにしました。
前段の手順で取得したA,BによるCSVファイルを添付した上で、以下を依頼します。
添付のSecurityGroup設定CSVファイルを元に、以下をテーブル形式で一覧出力してください
- 連番(GroupIdをもとに採番する)
- GroupName
- GroupId
- VpcId
このような形で一覧を教えてくれました。
ここから「1~10まで」「14以外」「vpc-0e4acafc38414468cのもののみ」などを後段のプロンプトで指定することで対象を絞り込めます。
コード生成を依頼するプロンプト例は以下です。
SecurityGroupルールの内訳をMermaid記法のコードで生成してください。
【出力対象SecurityGroup】
- すべて
【前提】
- インバウンドは自分向けの矢印、アウトバウンドは対向向けの矢印で表す
【レイアウトと構造】
- flowchart LR記法を使用(左から右への流れ)
- 同じCIDRブロック、プレフィックスリストへの接続は集約して表現
【凡例以外のサブグラフの利用】
- 関連するSecurityGroupをサブグラフでグループ化
【視覚的区別】
- SecurityGroupは四角形で紫色
- 0.0.0.0/0もしくは::/0からのインバウンドが許可されているSecurityGroupは紫色を赤枠で囲む
- CIDRブロックは平行四辺形で緑色
- 0.0.0.0/0もしくは::/0は平行四辺形で赤色
- プレフィックスリストは平行四辺形で橙色
- インバウンドは実線
- アウトバウンドは破線
- SecurityGroupの自己参照はループバック
【表示内容】
- SecurityGroupは「連番: 名前」の形式で表示(GroupIdは不要)
- CIDRブロックの表示に改行を挟まない
- 接続ラベルはプロトコルとポート範囲を記す(例:TCP 80-88)
- IpProtocolが−1のものは「すべて」と表現する
【スタイル定義】
以下を使用してください
```
%% スタイル定義
classDef sgStyle fill:#e6e6fa,stroke:#333,stroke-width:1px
classDef sgWithPublicAccess fill:#e6e6fa,stroke:#ff0000,stroke-width:2px
classDef cidrStyle fill:#d0f0c0,stroke:#333,stroke-width:1px
classDef publicStyle fill:#ffcccb,stroke:#333,stroke-width:1px
classDef prefixStyle fill:#ffdead,stroke:#333,stroke-width:1px
```
【その他】
- 凡例を追加する
- %%のコメントは最大5個まで
- できる限り全体のコード量を少なくするよう工夫すること
【コードの分割出力】
- 300行を超える場合
接続の表現は省略せず全量を対象にしてください。万が一省略した場合は、その旨をコメントしてください。
その他特筆事項がない場合は、コメントは不要です。
いくつか補足します。
【出力対象SecurityGroup】
先述の通り、この段階で対象をフィルタリングできます。
【凡例以外のサブグラフの利用】
「関連するSecurityGroupをサブグラフでグループ化」と指定すると、どのようなグルーピングをするかの観点から含めて判断してくれます。(試行のたびに結構ブレ幅がありました。)
コントロールしたいのであれば、例えば以下のような形の指定もできます
- 「VPCごとにグループ化」
- 「対象コンポーネントごとにグループ化」
- 「システムごとにグループ化」
逆にコードや描画結果をスッキリさせたい場合は「なし」を指定してください。
【視覚的区別】
今回は個人的な好みでいくつか指定をしています。必要に応じて取捨選択/改修してください。
- SecurityGroupは四角形で紫色
- 0.0.0.0/0もしくは::/0からのインバウンドが許可されているSecurityGroupは紫色を赤枠で囲む
- CIDRブロックは平行四辺形で緑色
- 0.0.0.0/0もしくは::/0は平行四辺形で赤色
- プレフィックスリストは平行四辺形で橙色
- インバウンドは実線
- アウトバウンドは破線
- SecurityGroupの自己参照はループバック
この指定だけではなかなか出力が安定しなかったので、【スタイル定義】も指定するようにしています。あわせてこちらも修正してください。
【コードの分割出力】
対象のルール数が多いとコードの生成に時間がかかり、場合によっては途中でハングすることもあると思います。
その場合、一定の行数を超えるようであれば分割して出力するように、と指示することで回避できたことがありました。
分割して出力された場合には、「分割して出力した3つの結果をマージして全体を整形して」と依頼することで全量を出力させることができました。
3. 生成されたMermaidコードを描画する
任意の環境でMermaidコードを描画しましょう。
特に普段使っているものがないということであれば、以下を用いるのがおすすめです。
コードを貼り付ければ自動で描画してくれ、その内容をPNGやSVGでエクスポートすることもできます。
Mermaidコードの構文に誤りがあった場合はエラー内容が表示されるので、それを生成AIチャットツールに渡して修正してもらいましょう。
終わりに
Amazon VPC SecurityGroupのルールをいい感じに可視化したい、という話でした。
規模が大きい環境では対象を絞り込んだり複数回にコードを分けたりなど工夫が必要そうですが、10数個程度のSecurityGroupであればいい感じに可視化してくれそうです。
プロンプトをもっと工夫すればもっと捗る気もするので、いろいろ試してみてください。
以上、チバユキ (@batchicchi)がお送りしました。
余談1 SVGコードの生成はちょっと早かった
Mermaid記法でのコード生成を試す前に、SVGとして図が生成できないかを検討していました。
依頼したプロンプトは以下の通り。
添付のSecurityGroup設定CSVファイルを元に、SVGコードを生成してください。
コメントは最小限とし、コードの全体量が少なくなるように最適化してください。
【基本構造】
1. SecurityGroup
- 長方形オブジェクトで表現
- オブジェクトには連番とGroupNameを表示(GroupIdは不要)
2. CIDR/プレフィックスリスト
- 円形オブジェクトで表現
- 共通の要素は1つにまとめる
3. 接続関係
- インバウンド:青矢印
- アウトバウンド:赤矢印
- 矢印には通信仕様を添える(プロトコル:ポート)
- 自己参照は曲線矢印で表現
【デザイン指定】
- 要素間の重なりを避ける
- 要素間に十分な余白を設ける
- 矢印は対象の縁に接続
- テキストは読みやすい位置に配置
SVGコードの出力後、連番とSecurityGroup Name、SecurityGroup IDの対応表を出力してください。
その他は特筆事項がない限り出力は不要です。
結果、生成されたコードを描画すると以下のようになりました。
まぁ……これはこれで?
早々に方向転換をしました。
余談2 視覚化できるツールもあります
以下のブログで紹介されているように、SecurityGroupの視覚化を目的としたツールもあります。
わたしの今回のモチベーションは「あまり大それたことしなくてもチャチャっとやってくれる」だったので試していませんが、規模が大きい環境での視覚化はこういったツールを活用するのもよいでしょう。
参考