はじめに
こんにちは!
今回は、Googleの最新モデルGemini3とclineを使って、「指示だけでDraw.ioの構成図を描画」し、さらに「構成図を読み込ませてTerraformコードを生成」し、実際にGCP上にデプロイまで成功した流れを紹介します。
実現したいこと
今回のターゲットとなるシステム構成は、Google Cloud上の一般的なWebアプリケーション構成です。具体的には以下の要件を満たすアーキテクチャを目指します。
- 前段:Cloud Load Balancing
- アプリケーション:Cloud Run
- Database:CloudSQL
- Storage:Google Cloud Storage
上記構成をドラッグ&ドロップすることなく、プロンプトだけでDraw.ioの図にし、さらにコード化まで行います。
Draw.ioでGCP構成図を自動生成
構成図を生成する前に、一つ重要なポイントがあります。それは、あらかじめ「使用したいGCPアイコンのリストをまとめたファイルを用意しておくこと」です。
何もない状態から「図を作って」と頼むと、スタイルが不揃いなアイコンを使ってしまうことがあります。そこで、Google公式の最新アイコンセットだけを集めたXMLファイルをコンテキストとして渡すことで、統一感のある綺麗な図を確実に作らせることができます。
今回はアイコンリストとしてdraw.ioに標準であるGCPのアイコンリストを全て並べたgcp_icon.drawio.xmlを作成し、読み込ませた上で厳密なルールを与えて作図を依頼しました。
gcp_icon.drawio.xmlは下記のような図となっています。
computeのアイコンリスト一覧
storageのアイコンリスト一覧
それでは実際のプロンプトは下記になります。今回はcline+gemini-3-pro-previewを利用しています。# Role「作成したい構成図の内容を入力」と赤字で記載しているところに構成図作成のプロンプトを入力します。今回は下記を入力しました。
あなたは熟練したGoogle Cloud Platform (GCP) のソリューションアーキテクトであり、Draw.ioのXML構造を完全に理解しているエンジニアです。
# Task
提供された `gcp_icon.drawio.xml` ファイルに含まれているリソース**のみ**を使用して、後述するシステム要件に基づいたGCP構成図を作成し、`drawio.xml` 形式で出力してください。
# Constraints & Rules (厳守事項)
1. **コンポーネントの選定と白枠の維持 (Crucial):**
- 各GCPサービスを配置する際は、単なるアイコン画像だけでなく、それを囲んでいる**「白枠(矩形の親コンテナ)」も含めて**使用してください。
- `gcp_icon.drawio.xml` 内では、多くの場合 `mxCell` が親子関係(親が枠、子がアイコン画像)になっています。この**親子の構造とスタイル(strokeColor, rounded, shadow等)を完全に維持**したままコピー・配置してください。
- 白枠を削除したり、スタイルを変更して透明にしたりしないでください。
2. **ゾーン/コンテナの配置:**
- `name="zones"` のページ(diagram)にある「Google Cloud Platform」というラベルの付いたコンテナ(矩形)を必ずルートとして使用してください。
- 全てのリソース(白枠付きアイコン)は、この「Google Cloud Platform」コンテナの内部(座標上、内側)に配置してください。
3. **接続線 (Connections):**
- 各コンポーネント間を線(矢印)で接続してください。
- **重要:** 線の始点(source)と終点(target)は、中のアイコン画像ではなく、必ず**外側の「白枠(矩形コンテナ)」**に接続してください。
- 線のスタイルは `edgeStyle=orthogonalEdgeStyle` を基本とし、見やすく配置してください。
4. **レイアウト (Left-to-Right Flow):**
- システムの構成要素は、**左(入力/ユーザー側)から右(バックエンド/データ側)に向かって**配置してください。
- コンポーネントのX座標を順次増やし、データの流れが左から右へ可視化されるように整理してください。
- 白枠同士が重ならないように、適切な間隔(余白)を空けて配置してください。
# Input Data (Source XML)
現在開いている(またはコンテキストにある) `gcp_icon.drawio.xml` を参照してください。
# System Architecture Requirements (作成する構成の内容)
{作成したい構成図の内容を入力}
# Output Format
作成した構成図を含む完全なXMLコードブロック(`mxGraphModel`)を「{現在日時}_gcp_architecture.drawio.xml」の新しいファイルとして出力してください。前段にロードバランサを設置し、アプリケーションサーバーとしてcloud runを設置してください。
cloud runにはcloud sqlとGCSを接続してください。
最終的に出力された構成図が下記になります。
少し線の位置がおかしいですがおおよそ想定していた構成図ができました!
見ての通り、事前に定義したGCPのアイコンリストから取得したアイコンを利用しています!
構成図からTerraformコードを生成
先ほど生成された「Draw.ioのXMLデータ」をそのままプロンプトに貼り付け、Terraformコードに変換してもらいます。ここでは、実運用を意識して main.tf, variables.tf, terraform.tfvars にファイルを分離するように指示しました。
あなたはGoogle Cloud Platform (GCP) とTerraformのエキスパートです。上記プロンプトをclineから実行すると以下の3ファイルが出力されます。
以下に貼り付けるDraw.ioのXMLデータを解析し、GCPの構成図をTerraformコードに変換してください。
### 構成ルール(重要)
1. **設定値の分離**:
- 構成内の具体的な値(CIDR、インスタンスタイプ、リージョン、ゾーン、リソース名など)は `main.tf` にハードコードしないでください。
- 変数定義は `variables.tf` に記述し、**具体的な設定値の代入は必ず `terraform.tfvars` に記述してください。**
2. **ファイル構成**: 以下の3つのファイルブロックを出力してください。
- `main.tf`: リソース定義(値は `var.xxx` で参照)。
- `variables.tf`: 変数の型(type)と説明(description)の宣言。
- `terraform.tfvars`: プロジェクトID、Region、および図から読み取れた具体的な値やプレースホルダーの設定。
3. **リソースの解釈**:
- `google` プロバイダーを使用してください。
- XML内のテキストラベルやプロパティから値を読み取れる場合は、その値を `terraform.tfvars` に反映させてください。
- 図から読み取れない必須値(Project IDなど)は、`terraform.tfvars` 内で `"YOUR_PROJECT_ID"` のようなプレースホルダーにしてください。
### Draw.io XMLデータ
```xml
```
- main.tf:構成のメイン
- variables.tf:Terraformプロジェクト内で使用する変数を定義
- terraform.tfvars:設定値パラメータ
main.tfterraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
# ------------------------------------------------------------------------------
# Cloud Storage
# ------------------------------------------------------------------------------
resource "google_storage_bucket" "default" {
name = var.bucket_name
location = var.bucket_location
force_destroy = true
uniform_bucket_level_access = true
}
# ------------------------------------------------------------------------------
# Cloud SQL
# ------------------------------------------------------------------------------
resource "google_sql_database_instance" "main" {
name = var.db_instance_name
database_version = var.db_version
region = var.region
settings {
tier = var.db_tier
ip_configuration {
ipv4_enabled = true
}
}
deletion_protection = false
}
resource "google_sql_database" "database" {
name = var.db_name
instance = google_sql_database_instance.main.name
}
resource "google_sql_user" "users" {
name = var.db_user
instance = google_sql_database_instance.main.name
password = var.db_password
}
# ------------------------------------------------------------------------------
# Cloud Run Service
# ------------------------------------------------------------------------------
resource "google_cloud_run_v2_service" "default" {
name = var.cloud_run_service_name
location = var.region
ingress = "INGRESS_TRAFFIC_ALL"
template {
containers {
image = var.container_image
env {
name = "DB_HOST"
value = "/cloudsql/${google_sql_database_instance.main.connection_name}"
}
env {
name = "BUCKET_NAME"
value = google_storage_bucket.default.name
}
volume_mounts {
name = "cloudsql"
mount_path = "/cloudsql"
}
}
volumes {
name = "cloudsql"
cloud_sql_instance {
instances = [google_sql_database_instance.main.connection_name]
}
}
}
}
resource "google_cloud_run_service_iam_member" "public" {
location = google_cloud_run_v2_service.default.location
service = google_cloud_run_v2_service.default.name
role = "roles/run.invoker"
member = "allUsers"
}
# ------------------------------------------------------------------------------
# Cloud Load Balancing (HTTP)
# ------------------------------------------------------------------------------
# 1. Serverless Network Endpoint Group (NEG)
resource "google_compute_region_network_endpoint_group" "serverless_neg" {
name = "${var.cloud_run_service_name}-neg"
network_endpoint_type = "SERVERLESS"
region = var.region
cloud_run {
service = google_cloud_run_v2_service.default.name
}
}
# 2. Backend Service
resource "google_compute_backend_service" "default" {
name = "${var.cloud_run_service_name}-backend"
protocol = "HTTP"
port_name = "http"
load_balancing_scheme = "EXTERNAL"
timeout_sec = 30
backend {
group = google_compute_region_network_endpoint_group.serverless_neg.id
}
}
# 3. URL Map
resource "google_compute_url_map" "default" {
name = "${var.cloud_run_service_name}-url-map"
default_service = google_compute_backend_service.default.id
}
# 4. Target HTTP Proxy
resource "google_compute_target_http_proxy" "default" {
name = "${var.cloud_run_service_name}-http-proxy"
url_map = google_compute_url_map.default.id
}
# 5. Global Forwarding Rule
resource "google_compute_global_forwarding_rule" "default" {
name = "${var.cloud_run_service_name}-lb-forwarding-rule"
target = google_compute_target_http_proxy.default.id
port_range = "80"
}
variables.tfvariable "project_id" {
description = "Google Cloud Project ID"
type = string
}
variable "region" {
description = "The region to deploy resources in"
type = string
default = "asia-northeast1"
}
variable "zone" {
description = "The zone to deploy resources in"
type = string
default = "asia-northeast1-a"
}
# Cloud Run Configuration
variable "cloud_run_service_name" {
description = "The name of the Cloud Run service"
type = string
default = "my-app-service"
}
variable "container_image" {
description = "The container image to deploy to Cloud Run"
type = string
default = "us-docker.pkg.dev/cloudrun/container/hello"
}
# Cloud SQL Configuration
variable "db_instance_name" {
description = "The name of the Cloud SQL instance"
type = string
default = "my-db-instance"
}
variable "db_version" {
description = "The database version for Cloud SQL"
type = string
default = "MYSQL_8_0"
}
variable "db_tier" {
description = "The machine type for the Cloud SQL instance"
type = string
default = "db-f1-micro"
}
variable "db_name" {
description = "The name of the database to create"
type = string
default = "my_database"
}
variable "db_user" {
description = "The database user name"
type = string
default = "admin"
}
variable "db_password" {
description = "The database user password"
type = string
sensitive = true
}
# Cloud Storage Configuration
variable "bucket_name" {
description = "The name of the GCS bucket"
type = string
}
variable "bucket_location" {
description = "The location of the GCS bucket"
type = string
default = "ASIA"
}
terraform.tfvars(環境に応じてパラメータを記載)project_id = "プロジェクトIDを記載"
region = "asia-northeast1"
zone = "asia-northeast1-a"
# Cloud Run
cloud_run_service_name = "gcp-arch-demo-service"
container_image = "us-docker.pkg.dev/cloudrun/container/hello"
# Cloud SQL
db_instance_name = "gcp-arch-demo-db"
db_version = "MYSQL_8_0"
db_tier = "db-f1-micro"
db_name = "app_db"
db_user = "ユーザー名記載"
db_password = "パスワード記載"
# Cloud Storage
bucket_name = "バケット名記載"
bucket_location = "asia-northeast1"
デプロイ確認
生成されたコードに対して terraform init & terraform apply を実行して、実際にコンソールから確認してみましょう。
Cloud Load Balancing
Cloud Run
CloudSQL
Google Cloud Storage
ブラウザからの確認(Cloud Load BalancingのフロントにあるIPアドレスから遷移)
パラメータ(プロジェクトIDの入力など)を入力するだけでデプロイが完了し、実際にブラウザからアクセスできることが確認できました!
まとめ
今回ご紹介したワークフローは、「構成図」と「Terraformコード」というこれまで別々に扱われがちだった成果物を、Gemini 3 を介して一気通貫で自動生成できる点が大きなポイントです。標準化されたアイコンセットとプロンプト設計さえ用意しておけば、要件定義からデプロイ可能な状態までを、誰でも短時間で再現できるようになります。
今後は、より複雑な構成や既存リソースとの連携パターンなどにも展開していくことで、インフラ設計〜IaC化のプロセス自体をさらに自動化していけるはずです。
まずは小さな構成から、みなさんの環境でもぜひ試していただき、「AIに任せられる部分」を一緒に広げていきましょう!
Google Cloud、Google Workspace に関するご相談はXIMIXへ!
Google Cloud、Google Workspaceに関する お問い合わせはこちら
- カテゴリ:
- クラウド
- キーワード:
- Google Cloud