Skip to content

corningma/terraform-graph

Repository files navigation

Terraform Graph Online

Terraform Graph Online

Realtime visualization for terraform graph with live execution status overlay.

Python FastAPI D3.js Terraform License PRs Welcome AI Generated

English · 简体中文

Terraform Graph Online Banner

✨ Overview

Terraform Graph Online is a lightweight, self-hosted system that renders a Terraform project's dependency graph in the browser and overlays the live execution state of every resource as terraform plan / apply runs.

It consists of two parts:

Component Role
🖥️ Server FastAPI + WebSocket + static SPA. Stores DOT graphs and logs in SQLite, pushes state changes to browsers.
🤖 Agent A small Python CLI installed on the Terraform runner. Executes terraform graph, wraps terraform commands, and streams stdout/stderr back to the server.

Everything runs as plain Python — no Docker, no message broker, no cloud account required.

🎯 Why?

Terraform's CLI output is linear, but infrastructure is a graph. When dozens of resources are being provisioned in parallel, plain text logs make it hard to answer:

  • Which resource is currently being created?
  • Did this module finish before that one started?
  • Where exactly did apply fail in the dependency tree?

This project answers those questions visually and without requiring plan/apply permissions on the server side — only terraform graph is mandatory.

🌟 Features

  • 🌐 Web-based visualization — interactive DAG rendered with D3 + dagre-d3.
  • 🔴🟢🟡 Live status overlay — resources are colored as queued / running / complete / failed, updated in real time.
  • 🧩 Multi-session — manage multiple Terraform projects/environments side-by-side.
  • 🪶 Zero infra — single FastAPI process + SQLite file. Static frontend served from the same port.
  • 🛡️ Read-only friendly — works in environments where the runner can only execute terraform graph and read logs.
  • 💻 Cross-platform agent — Linux/macOS shell + Windows PowerShell wrappers shipped out of the box.
  • 🔌 Multiple ingestion modes — wrap a command (watch), tail an existing log (tail), upload a finished log (upload-log), or mirror a whole shell session (shell).

🏗️ Architecture

┌────────────────────────────┐         HTTP / WebSocket          ┌────────────────────────────┐
│   Terraform runner host    │ ───────────────────────────────►  │      Server (FastAPI)      │
│                            │  POST /api/sessions/{sid}/graph   │                            │
│  ┌──────────────────────┐  │  POST /api/sessions/{sid}/logs    │  ┌──────────────────────┐  │
│  │  tfgraph-agent       │  │                                   │  │  parser  (DOT)       │  │
│  │  • graph (DOT)       │  │ ◄─────────────────────────────────┤  │  store   (SQLite)    │  │
│  │  • watch / tail      │  │           WebSocket push          │  │  hub     (WS fanout) │  │
│  │  • upload-log        │  │                                   │  └──────────┬───────────┘  │
│  └──────────────────────┘  │                                   │             │              │
└────────────────────────────┘                                   │             ▼              │
                                                                 │  ┌──────────────────────┐  │
                                                                 │  │  Static SPA          │  │
                                                                 │  │  D3 + dagre-d3       │  │
                                                                 │  └──────────────────────┘  │
                                                                 └────────────────────────────┘
  • Graph source: terraform graph (DOT) is parsed once per session.
  • State source: regex matching on console output (Creating..., Creation complete, Modifying..., Destroying..., Apply complete!, …).
  • Transport: Agent → Server via HTTP; Server → Browser via WebSocket.

📁 Project Structure

terraform-graph/
├── server/                     # Online system (FastAPI + static SPA)
│   ├── app.py                  # API + WebSocket entrypoint
│   ├── parser.py               # DOT parser
│   ├── store.py                # SQLite storage layer
│   ├── requirements.txt
│   └── static/                 # Frontend (HTML + CSS + JS)
│       ├── index.html
│       ├── style.css
│       └── app.js
├── agent/                      # Runner-side agent
│   ├── tfgraph_agent.py        # Main CLI
│   ├── tfgraph-agent.sh        # POSIX wrapper
│   ├── tfgraph-agent.ps1       # Windows PowerShell wrapper
│   ├── install.sh              # One-shot installer (Linux/macOS)
│   ├── install.ps1             # One-shot installer (Windows)
│   └── requirements.txt
├── docs/                       # Logos & images
└── README.md

📦 Download

Pre-built single-file binaries are published to Releases — no Python required on target machines.

Platform Server Agent
Linux x86_64 tfgraph-server-linux-amd64 tfgraph-agent-linux-amd64
macOS Intel tfgraph-server-darwin-amd64 tfgraph-agent-darwin-amd64
macOS Apple Silicon tfgraph-server-darwin-arm64 tfgraph-agent-darwin-arm64
Windows x64 tfgraph-server-windows-amd64.exe tfgraph-agent-windows-amd64.exe
# Server
curl -fsSL -o tfgraph-server \
  https://github.com/corningma/terraform-graph/releases/latest/download/tfgraph-server-linux-amd64
chmod +x tfgraph-server && ./tfgraph-server

# Agent
curl -fsSL -o tfgraph-agent \
  https://github.com/corningma/terraform-graph/releases/latest/download/tfgraph-agent-linux-amd64
chmod +x tfgraph-agent
TFGRAPH_SERVER=http://<server-ip>:8000 ./tfgraph-agent ping

Prefer running from source? Read on for the developer flow ↓

🚀 Quick Start

1. Start the server

cd server
pip install -r requirements.txt
python app.py
# → listens on http://0.0.0.0:8000

Open http://<server-ip>:8000 in a browser.

2. Install the agent on the Terraform runner

Linux / macOS

curl -O http://<server-ip>:8000/install.sh
bash install.sh http://<server-ip>:8000

Windows (PowerShell)

Invoke-WebRequest http://<server-ip>:8000/install.ps1 -OutFile install.ps1
.\install.ps1 -Server http://<server-ip>:8000

Or install manually:

cd agent
pip install -r requirements.txt
export TFGRAPH_SERVER=http://<server-ip>:8000

3. Use the agent

# Connectivity check
tfgraph-agent ping

# In your Terraform project directory: create a session and upload the graph
cd /path/to/your/tf-project
tfgraph-agent graph --name "prod-network"

# Wrap a Terraform command and stream stdout/stderr in real time
tfgraph-agent watch -- terraform plan
tfgraph-agent watch -- terraform apply

# No plan/apply permission? Tail an existing log file instead
tfgraph-agent tail /path/to/terraform.log

# Or upload a complete log file in one shot
tfgraph-agent upload-log /path/to/terraform.log

🧹 Uninstall

Stop the agent (no data deletion)

# Stop the background daemon (TF_LOG tailing, command watching)
tfgraph-agent daemon-stop

# Verify it's gone
tfgraph-agent daemon-status

Logout one session (delete it from the server)

This stops the local daemon, removes local offset/cache files, and deletes the session, its graph and all logs from the server:

tfgraph-agent logout                            # uses current dir's session
tfgraph-agent logout --sid <session-id>         # specific session
tfgraph-agent logout --server http://<srv>:8000 # remote server

Re-register with tfgraph-agent init whenever needed.

Uninstall the agent completely

Linux / macOS — the installer ships an --uninstall flag that:

  1. Stops the daemon (tfgraph-agent daemon-stop)
  2. Removes ~/.tfgraph/ (binaries, scripts, env, state, daemon files)
  3. Cleans up PATH/source lines from ~/.bashrc, ~/.zshrc, ~/.profile
# If install.sh is still around
bash install.sh --uninstall

# Or fetch it from the server again
curl -fsSL http://<server-ip>:8000/install.sh | bash -s -- --uninstall

Manual cleanup as a fallback:

tfgraph-agent daemon-stop || true
rm -rf ~/.tfgraph
# Then remove any `source ~/.tfgraph/env` lines from your shell rc files

Windows (PowerShell):

# Stop the daemon if it's running
tfgraph-agent daemon-stop

# Remove the install dir
Remove-Item -Recurse -Force "$env:USERPROFILE\.tfgraph"

# Remove tfgraph-agent from user PATH (open a new terminal afterwards)
[Environment]::SetEnvironmentVariable(
  "Path",
  ([Environment]::GetEnvironmentVariable("Path", "User") -split ';' |
    Where-Object { $_ -notmatch '\\.tfgraph\\bin$' }) -join ';',
  "User"
)

Reset / wipe the server

To clear all sessions, graphs and logs from the server:

# Stop the server first
# (find its PID, e.g. via systemctl/lsof, then kill it)

# Delete the SQLite database — it's the only persistent state
rm -f /path/to/data.db /path/to/data.db-shm /path/to/data.db-wal

# Restart the server; an empty database will be created on next launch

You can also wipe a single session via the UI ("Delete session" in the ··· menu) without touching the database file.

🧠 Design Highlights

  • Only depends on terraform graph — the full dependency graph comes from DOT, no plan/apply privilege needed.
  • State derived from logs — resource status is inferred by matching keywords like Creating..., Creation complete, Modifying..., Destroying..., Apply complete! in console output.
  • Realtime by default — Agent posts incremental log lines via HTTP; Server fans them out to browsers over WebSocket.
  • Lightweight stack — FastAPI + SQLite on the backend; pure static frontend (D3 + dagre-d3 from CDN).
  • Multi-tenant friendly — session-keyed storage means many runners and many projects can share one server.

🛠️ CLI Reference

Command Purpose
tfgraph-agent ping Verify connectivity to the server
tfgraph-agent init --name <n> Register/update a session without uploading the graph
tfgraph-agent graph --name <n> Run terraform graph and upload the DOT
tfgraph-agent shell Mirror an entire sub-shell session to the server
tfgraph-agent watch -- <cmd...> Wrap a command and stream its output
tfgraph-agent tail <log> Tail an existing log file and upload new lines
tfgraph-agent upload-log <log> Upload a complete log file in one shot

Environment variables

Variable Description
TFGRAPH_SERVER Server URL, e.g. http://10.0.0.1:8000
TFGRAPH_SESSION Explicit session ID (otherwise derived from --name)
TFGRAPH_NAME Default session name (defaults to current directory basename)

🤖 AI-Generated Notice

This project was generated 100% by an AI coding assistant.

Every file in this repository — Python source code, FastAPI server, agent CLI, POSIX/PowerShell wrappers, frontend HTML/CSS/JS, SVG logo & banner, and this README — was authored by an AI based on natural-language requirements from the project owner. No part of the codebase was hand-written by a human developer.

The code is released under the MIT License and provided "AS IS", without warranty of any kind. You are strongly encouraged to review, test, and audit the code before deploying it to production or security-sensitive environments.

🤝 Contributing

Issues and PRs are welcome! If you spot a bug, want to add a status keyword for another locale, or have ideas for the UI — please open an issue first to discuss.

📄 License

Released under the MIT License.

About

Realtime visualization for `terraform graph` with live execution status overlay.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors