☁ Cloud · 🔧 Tooling

CloudForge: I Built the Cloud Design Tool I Wish Existed

Visual drag-and-drop infrastructure design that outputs production-ready Terraform HCL — with Terraform reverse-engineering, multi-cloud support, and a context-aware AI assistant baked in from day one.

Live ✍ Shweta Suryavanshi 📅 June 14, 2026 ⏱ 7 min read

// TL;DR — key takeaways

▶ Watch the full demo video

The Problem: Four Tools, Zero Cohesion

Every cloud architecture project I worked on followed the same fragmented playbook: sketch a diagram in Excalidraw, write the actual IaC in VS Code, run validation scripts in the terminal, then try to keep the diagram and the code even vaguely in sync as the architecture evolved. It's 2026 and we're still copy-pasting CIDR blocks between a drawing app and a .tf file like it's 2015.

The problem isn't any single tool — it's that there's no single workspace. Architects think visually, but infrastructure lives in code. CloudForge was built to close that loop: a visual canvas where every drag, drop, and connection is the infrastructure definition, and deployment-ready code is a side-effect of the design.

Architecture: How the Pieces Fit Together

CloudForge is a full-stack TypeScript monorepo managed with npm workspaces. The repo splits cleanly into artifacts/ (deployable apps) and lib/ (shared packages), which kept cross-package imports explicit and prevented the usual monorepo spaghetti.

artifacts/
├── cloudforge/ # React + Vite web app → /
├── api-server/ # Express 5 API → /api
└── cloudforge-mobile/ # Expo (iOS + Android) → /mobile

lib/
├── api-spec/ # OpenAPI spec (single source of truth)
├── api-client-react/ # Generated React Query hooks (Orval)
├── api-zod/ # Generated Zod schemas (Orval)
└── db/ # Drizzle ORM schema + migrations

The guiding principle was code-generate everything that could be generated. The api-spec package owns the OpenAPI definition. Running npm run codegen -w @workspace/api-spec regenerates fully-typed React Query hooks and Zod validation schemas via Orval. The result: frontend types are never manually maintained, and if the API changes, the TypeScript compiler catches every mismatch at build time — not at 2am in production.

Layer Technology Why
Monorepo npm workspaces Simple, native, no Nx/Turborepo overhead
Language TypeScript 5.9 · Node 24 End-to-end type safety; native ESM
Frontend React + Vite + Tailwind v4 Fast HMR; CSS-first Tailwind architecture
Canvas @xyflow/react (ReactFlow v12) Battle-tested graph primitives, extensible node API
API Express 5 Stable, familiar, async-first error handling
Database PostgreSQL + Drizzle ORM Type-safe queries without the Prisma magic-proxy
Validation Zod + drizzle-zod Single schema, runtime + compile-time safety
API codegen Orval OpenAPI → React Query + Zod, zero manual sync
AI GPT-4.1 via Replit AI Context-aware prompting with canvas state
Mobile Expo (React Native) Single codebase, iOS + Android, Expo Go compatible
Build esbuild Sub-second API server builds

The Canvas: ReactFlow as Infrastructure Primitive

The visual canvas is the core of CloudForge. I chose @xyflow/react (ReactFlow v12) because it treats nodes and edges as first-class React state — each cloud component is just a custom React node with its own config panel, and connections between nodes map 1:1 to resource dependencies in the generated IaC. The component registry covers 32 services: EC2, VPC, Lambda, RDS, S3, EKS on AWS; AKS, Azure Functions on Azure; Cloud Run, BigQuery on GCP — each with provider-specific config fields and a validation profile.

State management was the real challenge at scale. A large architecture diagram can have dozens of nodes with deeply nested config objects, real-time validation overlays, and undo/redo history — all of which need to stay in sync without re-rendering the entire canvas on every keystroke. The solution was colocating node state inside ReactFlow's internal store, lifting only the "committed" architecture state to React Query for API persistence, and debouncing writes aggressively.

# The visual connection model maps directly to Terraform dependency graph:

resource "aws_vpc" "app_vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  tags = { Name = "CloudForge-VPC", ManagedBy = "CloudForge" }
}

resource "aws_subnet" "public_subnet" {
  vpc_id            = aws_vpc.app_vpc.id   # ← drawn as an edge on the canvas
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-east-1a"
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.app_vpc.id              # ← another edge
  tags   = { Name = "CloudForge-IGW" }
}

Design insight: Every edge drawn on the canvas carries semantic meaning — it encodes a depends_on or attribute reference in the output IaC. Visually drawing a line from a subnet to a VPC is writing vpc_id = aws_vpc.app_vpc.id. This is what makes the diagram and the code the same artifact.

Terraform Reverse-Engineering: The Hard Part

Importing an existing .tf file and turning it into a clean canvas layout was the hardest engineering problem in this project. Terraform HCL is designed to be written by humans, not parsed by tools: resources use string interpolation for references ("${aws_vpc.main.id}"), modules abstract entire sub-graphs, locals create intermediate values, and for_each meta-arguments can instantiate multiple resources from a single block. None of this maps cleanly to a node-edge graph without genuine semantic understanding.

My approach: build a lightweight HCL AST parser that walks the resource blocks, extracts attribute values, and runs a reference-detection pass to find implicit dependencies (string interpolation patterns, depends_on blocks, count/for_each iterators). Detected resources are matched against the 32-component registry by type, unrecognized resources fall back to a generic "Custom Resource" node. Then a force-directed auto-layout algorithm (with provider-grouping hints) positions the nodes so AWS, Azure, and GCP resources cluster visually. It's not perfect on pathological Terraform, but it handles the 80% case — real-world single-provider infra — cleanly.

// hot take Visual IaC tools failed in the past because they tried to replace code with diagrams. The right abstraction is the opposite: make code the canonical truth and let the diagram be a live, editable view of it. CloudForge succeeds because exporting HCL is a read operation on the canvas state — there's no translation layer that can drift. — Shweta Suryavanshi

The AI Assistant: Context-Aware, Not Generic

The floating AI chat panel is powered by GPT-4.1 via Replit AI Integrations. The key design decision was what context to pass. Generic "ask AI about cloud architecture" tools give you textbook answers. CloudForge serializes the current project state — component types, provider labels, connection topology, and active validation errors — and prepends it as a structured prompt context before every message. The result: "Should I add a NAT gateway?" gets an answer that looks at your actual canvas, not a five-paragraph essay about NAT gateways in general.

Prompt orchestration lives in the /api/ai/chat route on the Express server, not the client. This keeps the context-assembly logic server-side, makes it easy to iterate on prompt structure without app redeployments, and avoids leaking the OpenAI API key to the browser.

Multi-Format Export: One Model, Four Outputs

The export engine (POST /api/export) takes the canvas node-edge graph and a format parameter, then walks the same dependency-ordered graph to emit the target syntax. Each cloud component has a code-generator interface with four implementations: toTerraform(), toCloudFormation(), toKubernetes(), toYAML(). Supporting multiple outputs from one visual model forces you to build a genuinely provider-agnostic internal representation — which paid dividends when adding new components, since you only write the graph model once and all four exporters just work.

What's Coming Next

The roadmap is AI-heavy. I'm building automated cost estimation that annotates components with monthly spend projections directly on the canvas, security hardening suggestions that flag specific misconfigurations with remediation steps, and a resiliency scorer that grades the architecture's high-availability posture. The endgame is turning the canvas into a live architecture health dashboard, not just a design tool.

On the collaboration side: Google-Docs-style real-time multi-user editing via WebSockets, GitOps pipeline integration (push to a branch, CI runs terraform plan), and infrastructure drift detection that re-imports the live state and highlights canvas divergences. The vision is CloudForge as the operating system for cloud architecture — design, validate, deploy, and monitor, all in one place.

DevOps Terraform ReactFlow Multi-Cloud TypeScript OpenAPI