https://github.com/naimjeem/cloud-village
Interactive 3D cloud architecture map. Renders services as buildings in a stylized village.
https://github.com/naimjeem/cloud-village
aws azure cloud cloudflare database docker gcp kubernetes storage vpc
Last synced: 5 days ago
JSON representation
Interactive 3D cloud architecture map. Renders services as buildings in a stylized village.
- Host: GitHub
- URL: https://github.com/naimjeem/cloud-village
- Owner: naimjeem
- License: mit
- Created: 2026-05-11T18:30:09.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-13T10:34:05.000Z (about 2 months ago)
- Last Synced: 2026-05-13T12:06:19.249Z (about 2 months ago)
- Topics: aws, azure, cloud, cloudflare, database, docker, gcp, kubernetes, storage, vpc
- Language: TypeScript
- Homepage: https://github.com/naimjeem/cloud-village
- Size: 9.96 MB
- Stars: 3
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Cloud Village
> Interactive 3D cloud architecture map. Renders services as buildings in a stylized village. Live-scan AWS / Cloudflare / Azure / GCP / Docker. Watch traffic flow as particles along roads, alerts pulse buildings, day-night cycle, soft shadows, bloom.





> π½ [Full 1080p MP4](docs/cloud-village-intro.mp4) Β· [Static poster](docs/cloud-village.png)
---
## Features
- **3D village** β services rendered as houses, vaults, silos, towers, gates. Per-kind PBR materials, soft shadows, bloom, HDRI lighting.
- **2D architecture view** β toggleable SVG diagram for a flat overview. Pan, wheel-zoom (cursor-anchored), fit-to-screen. Buildings β rounded rects colored by kind with health-colored border + kind emoji; connections β curved quadratic paths, protocol-colored, arrowheads, traffic-scaled stroke width.
- **Day / night cycle** β dawn β day β dusk β night with stars, lamp glow, fog, lerped lighting. Manual or auto-advance (12 s per phase).
- **Architecture-driven weather** β sky reflects fleet state: β clear (all healthy) β β cloudy (degraded or traffic spike) β π§ rain (β₯30% degraded or 3+ alerts) β β storm (any down / firing critical). 3D rain particles, animated cloud cover, lightning flashes. 2D mode gets canvas rain streaks, drifting cloud blobs, flash overlay. Auto by default; manual override via toolbar.
- **Five sources** β mock demo, JSON upload, Terraform `tfstate`, source-tree generator, or **live cloud scan** via the Go backend.
- **Live metrics** β polls backend every 4 s for CloudWatch alarms + ALB request rates β drives health states, edge particles, deduped alerts.
- **Animated traffic** β request / response / event particles arc along edges. Road color thickens + shifts brown β red as traffic rises, decays over time.
- **Click-to-inspect panel** β incoming / outgoing connections, replayable flows, alert triggers, health override, metadata view.
- **Metrics panel** β toggleable in-app dashboard (π Panel). Tabs: summary (counts + health distribution + top kinds), components (sortable by traffic / health / name / kind), edges (top traffic), alerts (severity-coded, click-to-focus). Provider-agnostic β reads live store state so it works for demo, AWS, Azure, GCP, Cloudflare, Docker.
- **Friendlier labels** β building name pills strip scanner prefixes (`ctr_`, `arn:aws:`, β¦), convert underscores to spaces, truncate to 22 chars with full name in tooltip. Health dot + kind emoji inline. Legend grouped into Buildings / Health / Traffic with hover descriptions; collapsible.
- **Responsive toolbar** β grouped sections on desktop (playback Β· data Β· view+atmosphere Β· telemetry); under 760 px the bar collapses behind a β° hamburger and Legend starts minimised, keeping mobile viewports clean.
- **Settings UI** β store provider credentials (AWS keys, Cloudflare token, Azure service principal, GCP service account JSON) in browser `localStorage`. Used as scan-time overrides.
---
## Quick start
```sh
npm install
npm run dev # frontend β http://localhost:5173
cd backend && go run . # backend β http://localhost:8787 (optional, needed for β Live scan / π Live metrics)
```
Requirements: **Node 18+**, **Go 1.22+**.
First load shows a mock SaaS village. Try β Live scan, π JSON, or generate from a real project.
---
## Generate village from any project
```sh
npm run generate -- /path/to/project
# writes /path/to/project/village.json
npm run generate -- /path/to/project -o /tmp/out.json
npm run generate -- . --skip k8s,serverless
```
Parsers (run by default):
| Parser | Reads | Produces |
|--------|-------|----------|
| **compose** | `docker-compose.yml` / `compose.yml` | service per `services.*`, edges from `depends_on`, kind from image |
| **pkg** | every `package.json` | compute node, externals inferred from deps (`pg`, `redis`, `mongoose`, `@aws-sdk/*`, `stripe`, `resend`, `openai`, β¦) |
| **env** | every `.env*` | externals from var names (`DATABASE_URL`, `REDIS_URL`, `STRIPE_*_KEY`, `OPENAI_API_KEY`, β¦) |
| **serverless** | `serverless.yml` | Lambda fn + DDB/S3/SQS/SNS resources + edges |
| **k8s** | yaml under `k8s/` `kube/` `manifests/` `deploy/` `charts/` `kustomize/` | Deployment / Service / StatefulSet / Job, ServiceβDeployment edges by `app` label |
Output is auto-laid-out (grid by kind, hubs centered by connection degree). Load via π JSON.
---
## Loading architecture
| Source | Trigger | Description |
|--------|---------|-------------|
| Demo | default on first run | Mock SaaS village |
| Source-gen | `npm run generate -- ` | Auto-build from project source (compose, package.json, .env, serverless, k8s) |
| JSON | **π JSON** | Upload `VillageConfig` JSON. Schema below. |
| Terraform | **π§± tfstate** | Upload `terraform.tfstate`. Extracts AWS resources, infers edges from IAM policies + ALB target groups + dependencies. |
| Live cloud | **β Live scan** | Calls backend `/api/scan` for AWS / Cloudflare / Docker / Azure / GCP. Creds come from **β Settings** + backend env. |
Last loaded village persists in `localStorage` (`cloud-village:lastVillage`).
### JSON schema
```json
{
"name": "string",
"components": [
{
"id": "...", "name": "...",
"kind": "compute|storage|database|queue|gateway|cdn|monitoring|auth|cache|external",
"provider": "aws|gcp|azure|cloudflare|docker|generic",
"position": [x, z], "health": "healthy|degraded|down",
"meta": { "any": "string|number" }
}
],
"connections": [
{ "id": "...", "from": "id", "to": "id", "protocol": "http|grpc|sql|event|tcp", "label": "optional" }
]
}
```
Components with `position: [0, 0]` (or missing) get an auto-layout slot based on `kind` columns and connection degree.
---
## Building map
| Cloud kind | Building |
|------------|----------|
| compute | house + pitched roof + lit windows |
| storage | banded silo |
| database | stacked vault discs + pulse beacon |
| queue | post office + flag |
| gateway | arched town gate w/ banners |
| cdn | radio tower + dish + beacon |
| monitoring | watchtower + searchlight |
| auth | guardhouse + lantern |
| cache | well |
| external | signpost / traveler |
---
## UI controls (toolbar)
The toolbar is split into colour-coded groups. On viewports under 760 px the entire bar collapses behind a **β° hamburger** that shows only the brand + health badges; tap it to expand the full menu.
**Brand / status (left)** β village name, component count, health chips (green / amber / red), live alert badge.
**Playback** (icon-only buttons with tooltips)
| Icon | Action |
|------|--------|
| βΈ / βΆ | Pause / resume all animation (also `Space`) |
| β‘ | Replay flows on every edge |
| β | Spawn a random alert |
| βΊ | Reload mock village |
**Data** (icon-only on mobile)
| Button | Action |
|--------|--------|
| β€ Data βΎ | Dropdown: load JSON, load Terraform `tfstate`, export current village |
| β Live scan | Open scan modal (live cloud scan via backend) |
| β | Provider credentials modal |
**View + atmosphere**
| Button | Action |
|--------|--------|
| π 3D / πΊ 2D | Segmented switch between 3D village and 2D architecture |
| π
/ π / π / π phase | Cycle time-of-day. β³ side button toggles auto-cycle (12 s per phase) |
| β / β / π§ / β weather | Cycle weather mode. β³ side button re-engages auto-derivation from fleet health |
**Telemetry (right)**
| Button | Action |
|--------|--------|
| π Live | Toggle backend metrics polling (4 s). Pulsing dot indicates active polling |
| π Panel | Toggle in-app metrics dashboard (summary / components / edges / alerts) |
### Keyboard
| Key | Action |
|-----|--------|
| `/` | Focus search bar |
| `Esc` | Deselect / clear search |
| `Space` | Pause / resume animation |
---
## Animations
- **Request / response / event particles** arc along edges (blue / green / yellow).
- **Critical alerts** pulse the building red + slide a toast in (auto-dismiss 6 s, deduped 60 s window).
- **Health states** β green (healthy) / amber (degraded) / red (down) emissive glow.
- **Traffic heatmap** β roads thicken + shift brown β orange β red based on recent flow count, decays exponentially.
- **Day / night** β sun pos / color / intensity, hemisphere + ambient colors, fog, exposure, sky turbidity, bloom threshold, star field, lamp emissive β all lerp between phases. Auto-cycle: 12 s per phase.
- **Postprocessing** β Bloom + HueSaturation + BrightnessContrast + Vignette + ACES filmic tonemap + SMAA.
- **Live metrics mode** β client polls `/api/metrics` every 4 s. Falls back to client-side simulator only if no real scan has run.
---
## Architecture-driven weather
The sky is a glanceable health gauge β operators can read the overall fleet state without opening any panel. Auto-derivation samples store state every 2 s ([src/hooks/useWeatherAuto.ts](src/hooks/useWeatherAuto.ts)).
| Mode | Triggers (first match wins) |
|------|-----------------------------|
| β Storm | any component `health === 'down'` **OR** any active alert with `severity === 'critical'` |
| π§ Rain | β₯30 % components `degraded` **OR** β₯3 active alerts |
| β Cloudy | any component `degraded` **OR** any active alert **OR** sustained edge traffic |
| β Clear | fully healthy and quiet |
3D scene effects ([src/scene/WeatherSystem.tsx](src/scene/WeatherSystem.tsx))
- **Rain** rendered as instanced `lineSegments` (rain 220 drops / storm 420). Position updates throttled to 30 Hz to cap GPU upload.
- **Storm lightning** randomly spikes the directional-light intensity every 3β12 s, decays back over ~300 ms.
- **Fog + sun** lerp to per-mode tint (cloudy β grey, rain β blue-grey, storm β dark navy) and dim (cloudy 0.78Γ, rain 0.55Γ, storm 0.35Γ).
- **Cloud sprites** get heavier opacity + darker tint per mode.
2D-view effects ([src/ui/WeatherOverlay.tsx](src/ui/WeatherOverlay.tsx))
- Canvas rain streaks with slant + slight perspective (rain 50 / storm 110), capped at 30 fps.
- Drifting cloud blobs (cloudy +).
- Full-screen tint per mode + lightning flash overlay synchronised to storm strikes.
Manual override via the toolbar weather chip flips `weatherAuto` off so the sky stays put while investigating; the β³ Auto side button re-engages derivation.
---
## Metrics panel
Open with **π Panel** on the toolbar. Side panel docked right; auto-shifts left when an inspect panel is open so both fit side-by-side.
| Tab | Shows |
|-----|-------|
| Summary | Component count, connection count, active-edge count, alert count, health distribution bar (healthy / degraded / down), top kinds breakdown |
| Components | All components in a sortable table (traffic / health / name / kind). Click a row β focuses the building and opens InspectPanel |
| Edges | Top 20 connections by current traffic, from β to + protocol + rate |
| Alerts | Recent alerts feed, severity-colored, timestamped. Click β focus the offending component |
Panel reads directly from the live store (`village`, `alerts`, `edgeTraffic`), so it is **provider-agnostic**: works with demo data, JSON uploads, Terraform state, or any of the live scanners (AWS, Azure, GCP, Cloudflare, Docker). When π Live metrics is on, numbers update every 4 s automatically.
`backend/internal/metrics/docker.go` is what feeds the panel for local Docker setups: container `running`/`exited`/`dead` β health, CPU% β₯ 85 β degraded, β₯ 99 β down with critical alert, and network (rx+tx) bytes/sec scaled into edge rates. Same `Snapshot` shape as the AWS adapter, no external service required.
---
## Backend
Go module at `backend/` exposing a small HTTP API.
```
backend/main.go # chi router, /health /api/scan /api/metrics
backend/internal/village/types.go # VillageConfig / Component / Connection
backend/internal/scan/aws.go # AWS SDK Go v2 (ECS, Lambda, DDB, ALB, S3, ECR, SQS, SNS, SFN, CloudFront, APIGW, CWLogs)
backend/internal/scan/cloudflare.go # Cloudflare REST API
backend/internal/scan/docker.go # Local Docker engine via docker SDK
backend/internal/scan/azure.go # Azure Resource Manager SDK
backend/internal/scan/gcp.go # GCP Cloud Asset Inventory (REST + google ADC)
backend/internal/metrics/aws.go # CloudWatch alarms + ALB RequestCountPerTarget
backend/internal/metrics/docker.go # Local Docker container CPU%, net rx/tx, run state
backend/internal/metrics/handler.go # /api/metrics provider switch
```
Endpoints:
- `GET /health` β `{ok: true}`
- `POST /api/scan` β body `{ provider, ... }` β `VillageConfig`
- `GET /api/metrics?provider=aws` β CloudWatch alarms + ECS health + ALB request rate
- `GET /api/metrics?provider=docker` β local Docker container CPU%, network rx+tx, run state (no external service)
### Docker live metrics (local, zero external dependencies)
After running a Docker scan, toggle **π Live metrics**. Each 4 s poll reads from the local Docker socket and reports:
- **Health** β container `running` β healthy, `exited`/`dead` β down, else degraded. CPU β₯ 85% downgrades to degraded; β₯ 99% to down.
- **Edge rates** β sum of (rx + tx) bytes/sec for the two endpoints of each connection, scaled into a request-rate proxy.
- **Alerts** β high-CPU per container (`warning` β₯ 85%, `critical` β₯ 99%).
All data comes from `/var/run/docker.sock`. No Prometheus, no exporter, no third-party service.
### Credential resolution
| Provider | Precedence (highest first) |
|----------|----------------------------|
| **AWS** | β Settings static keys β β Settings profile β scan-body keys/profile β SDK default chain (env vars, `~/.aws/credentials`, SSO, IMDS) |
| **Cloudflare** | β Settings API token β scan-body token β `CLOUDFLARE_API_TOKEN` env |
| **Docker** | β Settings socket path β scan-body socket β `/var/run/docker.sock` |
| **Azure** | β Settings service principal (`tenantId` + `clientId` + `clientSecret`) β `DefaultAzureCredential` (env, `az login`, managed identity) |
| **GCP** | β Settings service-account JSON β Application Default Credentials (`gcloud auth application-default login`) |
Credentials entered in β Settings are stored in browser `localStorage` (key `cloud-village-creds`) in plaintext. Use read-only credentials only. For shared machines, prefer shell env vars on the backend.
### AWS IAM read-only perms
```
ecs:List*, ecs:Describe*
lambda:ListFunctions
dynamodb:ListTables, dynamodb:DescribeTable
elasticloadbalancing:Describe*
s3:ListAllMyBuckets
ecr:DescribeRepositories
sqs:ListQueues, sqs:GetQueueAttributes
sns:ListTopics
states:ListStateMachines
cloudfront:ListDistributions
apigateway:GET
logs:DescribeLogGroups
cloudwatch:DescribeAlarms, cloudwatch:GetMetricData
```
### Resource β kind per provider
| Provider | Mapping |
|----------|---------|
| AWS | ECS / Lambda / SFN β compute, DDB β database, S3 / ECR β storage, SQS / SNS β queue, ALB / APIGW β gateway, CloudFront β cdn, CWLogs β monitoring |
| Cloudflare | Worker / Pages β compute, KV β cache, R2 β storage, D1 β database, Queues β queue, Zones β gateway |
| Docker | postgres / mysql / mongo β database, redis β cache, rabbitmq / kafka β queue, nginx / traefik β gateway, prometheus / grafana β monitoring, others β compute |
| Azure | VM / App / AKS / Functions β compute, Storage / ACR β storage, SQL / Postgres / MySQL / Cosmos β database, ServiceBus / EventHub β queue, LB / AppGW / APIM β gateway, CDN β cdn, Insights β monitoring, KeyVault β auth, Redis β cache |
| GCP | GCE / GKE / CloudRun / Functions β compute, GCS / AR β storage, SQL / Spanner β database, PubSub / Tasks β queue, LB / APIGW β gateway, Memorystore β cache, Secret / IAM β auth |
---
## Tech stack
- **Frontend** β React 18, TypeScript, Vite
- **3D** β three.js via `@react-three/fiber`, `@react-three/drei`, `@react-three/postprocessing`
- **State** β `zustand`
- **Backend** β Go 1.22+, `chi` router, AWS SDK Go v2, Azure SDK, Docker SDK, `golang.org/x/oauth2/google`
---
## Security
- β Settings stores credentials in browser `localStorage` in plaintext. Anyone with access to the browser, browser extension permissions, or via XSS can read them. **Use read-only credentials only.**
- Never paste production write-capable keys.
- Backend forwards credentials directly to provider SDKs β it does not log or persist them.
- For shared / multi-user setups, prefer backend env vars or SSO-issued temporary credentials over the β Settings dialog.
- IAM perms in this README are read-only by design. Audit before granting.
---
## Roadmap
- [x] Phase 1 β 3D village render + mock data
- [x] Phase 2 β Click panel, health states
- [x] Phase 3 β Particle flow animation + alerts
- [x] Phase 4 β JSON config loader
- [x] Phase 5 β Terraform `tfstate` parser
- [x] Phase 6 β Live cloud scan backend (Go + chi + AWS SDK Go v2)
- [x] Phase 7 β Cloudflare, Docker, Azure, GCP scanners
- [x] Phase 8 β CloudWatch alarms + ALB request-rate metrics ingest
- [x] Phase 9 β Realistic rendering pass (HDRI, bloom, soft shadows, day/night, props)
- [x] Phase 10 β β Settings credential vault (per-provider)
- [x] Phase 11 β Docker live metrics (local CPU% / network / state, no external service)
- [x] Phase 11b β In-app Metrics Panel + 2D architecture view + 3D/2D toggle
- [x] Phase 11c β Architecture-driven weather (clear / cloudy / rain / storm), auto-derived from fleet health
- [x] Phase 11d β Toolbar redesign (grouped sections, segmented switch, Data dropdown, mobile hamburger, collapsible Legend)
- [ ] Phase 11e β Azure Monitor / GCP Cloud Monitoring / Cloudflare Analytics metrics adapters
- [ ] Phase 12 β Code-split bundle (lazy-load three.js + postprocessing)
- [ ] Phase 13 β GLTF asset kit support (Quaternius / Kenney)
- [ ] Phase 14 β Multi-account / multi-region AWS scan in one render
---
## Contributing
PRs welcome. Keep parsers / scanners pure functions where possible. New backend providers go under `backend/internal/scan/.go` and register in `main.go`. New frontend kinds go under `src/scene/Building.tsx` `buildingGeo()` switch.
```sh
npm run dev # frontend
cd backend && go run . # backend
# type-check / vet before PR
npx tsc --noEmit -p tsconfig.json
cd backend && go vet ./...
```
---
## License
MIT β see [LICENSE](LICENSE).
Built by [Naimuddin Shahjalal Bhuyan](https://naimjeem.me).