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.
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
applyfail 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.
- 🌐 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 graphand 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).
┌────────────────────────────┐ 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.
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
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 pingPrefer running from source? Read on for the developer flow ↓
cd server
pip install -r requirements.txt
python app.py
# → listens on http://0.0.0.0:8000Open http://<server-ip>:8000 in a browser.
Linux / macOS
curl -O http://<server-ip>:8000/install.sh
bash install.sh http://<server-ip>:8000Windows (PowerShell)
Invoke-WebRequest http://<server-ip>:8000/install.ps1 -OutFile install.ps1
.\install.ps1 -Server http://<server-ip>:8000Or install manually:
cd agent
pip install -r requirements.txt
export TFGRAPH_SERVER=http://<server-ip>:8000# 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# Stop the background daemon (TF_LOG tailing, command watching)
tfgraph-agent daemon-stop
# Verify it's gone
tfgraph-agent daemon-statusThis 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 serverRe-register with tfgraph-agent init whenever needed.
Linux / macOS — the installer ships an --uninstall flag that:
- Stops the daemon (
tfgraph-agent daemon-stop) - Removes
~/.tfgraph/(binaries, scripts, env, state, daemon files) - Cleans up PATH/
sourcelines 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 -- --uninstallManual cleanup as a fallback:
tfgraph-agent daemon-stop || true
rm -rf ~/.tfgraph
# Then remove any `source ~/.tfgraph/env` lines from your shell rc filesWindows (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"
)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 launchYou can also wipe a single session via the UI ("Delete session" in the ··· menu) without touching the database file.
- Only depends on
terraform graph— the full dependency graph comes from DOT, noplan/applyprivilege 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.
| 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 |
| 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) |
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.
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.
Released under the MIT License.