Self-hosted AWS control plane for running Trino SQL clusters from the browser.
Provision and operate EC2-backed Trino clusters, wire up data catalogs, and run SQL — all from one box, with no static AWS credentials and a Trino-aware autoscaler.
MANAGED TRINO CLUSTERS · FastAPI + boto3 + SQLite · managed-platform workflow, original implementation
demo.trinohub.org — sign in as demo / trinohub-demo.
A real TrinoHub install, not a mockup. Browse clusters and catalogs, open the SQL
editor, notebooks, Ask Trino, the MCP page and the docs — then run actual SQL
against the tpch and tpcds sample catalogs.
The demo cluster is suspended when idle. Running a query starts it automatically, so your first query takes a minute or two to come back while the cluster boots; after that it is quick. That auto-resume is a real TrinoHub feature, not a demo shim.
The demo account is read-only by design: it cannot create, start or delete clusters, add catalogs, or change settings, and it reaches only the sample catalogs. To see the parts it can't reach, run it yourself — there is nothing different about the build.
TrinoHub runs as a single control-plane host: one EC2 instance serving the TrinoHub UI + API, a local SQLite database, and an AWS orchestration service. It installs into your own VPC, so clusters and query data stay inside your AWS account — nothing routes through a TrinoHub-hosted service. From that one box, operators launch and manage separate EC2-based Trino coordinator/worker clusters and data catalogs. Analysts pick a cluster, write SQL, and pull results.
It replaces the "spin up Trino by hand with Terraform/Ansible" workflow with a few clicks and a Trino-aware autoscaler — while keeping the security model tight: the control plane authenticates to AWS via its EC2 instance profile (no access keys, ever), and cluster nodes fetch signed, per-cluster bootstrap config over the private network.
Two roles, one app:
| Role | What they do |
|---|---|
| Admin / platform engineer | First-run setup, validate AWS IAM, create/operate clusters and catalogs, manage users, review settings. |
| Analyst / query user | Pick a cluster + catalog, run SQL, watch query status, cancel their own queries, download CSV, browse their own history. |
- Cluster lifecycle from the browser — create, start/resume, suspend, disable, and delete EC2-backed Trino clusters. Each cluster maps to a tagged set of AWS resources (coordinator EC2, worker launch template, worker Auto Scaling Group, security-group rules). Delete terminates every tracked resource.
- Preset tiers —
Cost/Balanced/Powerresolve to region-available M-family instance types (m7i.large/m7i.xlarge/m7i.2xlarge, with prior-generation fallbacks). - Trino-aware autoscaling — a control loop (not a raw CPU policy) that scales workers on queued queries and CPU, with cooldowns and min/max bounds. Auto-suspend tears down idle clusters; a query against a suspended cluster resumes it first.
- Catalogs — built-in
system,tpch,tpcds, plus AWS Glue-backed lakehouse catalogs on S3, Google Cloud Storage, and Azure Data Lake. Worker IAM roles grant S3/Glue access; cross-cloud credentials live in AWS Secrets Manager and catalog records contain references only. - Accelerated clusters (object-store caching) — optional warm cache for S3-backed catalogs
(Hive, Iceberg, Delta Lake) built on Trino's file system cache: nodes keep hot data pages on
local NVMe instance-store SSDs and the scheduler routes work to the nodes that already hold
the file, so repeated scans read from local disk instead of S3. Toggle Accelerated at
cluster create with an NVMe instance type (
i4i/r6id/i3en) — seedocs/accelerated-clusters.md. - SQL editor — schema browser, cluster/catalog/schema selectors, live status polling, tabular results, error display, and CSV export. Browser results cap at 1,000 rows / 10 MB; CSV export streams a larger capped buffer.
- Notebooks — organize SQL into an ordered document of cells (Jupyter/Databricks-style, scoped to Trino). Each cell runs independently with its own inline table or chart, supports per-cell cluster/catalog/schema overrides, reorder, Run all, and per-cell CSV. Notebooks autosave to your account.
- Security by default — instance-profile auth, allowed-UI-CIDR enforcement at the app layer, signed per-cluster bootstrap tokens, hashed passwords, and httpOnly session cookies.
- Polished UI — purple/blue design system, light/dark themes, and responsive layouts down to phone widths (operators check clusters on the go).
┌──────────────────────── Control-plane EC2 (the "AMI") ───────────────────────┐
Browser ───► │ FastAPI app (trinohub/api.py) ──► TrinoHubApp business logic (server.py) │
(static UI) │ static UI (web/) SQLite (.trinohub/trinohub.sqlite3) │
│ OpenAPI docs (/docs) boto3 → AWS (EC2, ASG, STS, CloudWatch) │
└───────────────┬──────────────────────────────────────────────────────────────┘
│ provisions + bootstraps (tagged, instance-profile auth only)
▼
┌──────────── Per-cluster AWS resources ────────────┐
│ Coordinator EC2 ──► Workers Auto Scaling Group │
│ Launch template · Security group · Boot tokens │
└────────────────────────────────────────────────────┘
| Layer | Choice |
|---|---|
| API | FastAPI (trinohub/api.py); OpenAPI docs at /docs; stdlib TrinoHubApp (trinohub/server.py) holds business logic. |
| AWS | boto3 — EC2, Auto Scaling, STS, CloudWatch (read). |
| Storage | SQLite (.trinohub/trinohub.sqlite3) — users, sessions, setup, clusters, catalogs, query runs, events. |
| Frontend | Static HTML/CSS/JS in web/ — no build step, browser-native. |
| Deploy | systemd unit + nginx config under deploy/; runs uvicorn trinohub.api:app. |
TrinoHub provisions real AWS infrastructure, so every install needs AWS credentials and a VPC — first-run setup validates STS, EC2, Auto Scaling, and CloudWatch and runs an EC2 launch dry-run before it will let you finish. Three ways to get there:
| Path | Use it when |
|---|---|
| CloudFormation stack | You want the fastest working install — the stack builds the IAM roles, security group, and host for you. |
| Bring your own host | You already manage EC2 with Terraform/Ansible or golden images, or CloudFormation is restricted in your account. |
| Local development | You're hacking on the app or running the tests. No AWS needed. |
A single CloudFormation stack creates the IAM roles (instance-profile auth — no static keys), a security group, and an EC2 instance that installs and starts the app. From there you launch and manage Trino clusters in the browser.
aws cloudformation deploy \
--stack-name trinohub \
--template-file deploy/aws/cloudformation.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
VpcId=vpc-xxxx SubnetId=subnet-xxxx \
AllowedUiCidr="$(curl -s https://checkip.amazonaws.com)/32"Then open the stack's UiUrl output and complete the setup wizard. Full
step-by-step (console + CLI, retrieving the first-run setup token via SSM, teardown):
The control plane is a plain Python app — FastAPI, SQLite, and static files, with no
build step. The CloudFormation stack only automates what you can do by hand: it boots a
stock Ubuntu 24.04 AMI and runs the same apt → venv → systemd steps documented in
deploy/README.md. So if CloudFormation is off the table, install
it directly on any Ubuntu 24.04 host:
sudo apt-get install -y python3-venv python3-pip nginx
git clone https://github.com/BitRefinery/trinohub.git /sites/trinohub
cd /sites/trinohub && python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
# the shipped unit runs as user `trinohub` from /sites/trinohub — see deploy/README.md
sudo cp deploy/trinohub.service /etc/systemd/system/
sudo systemctl enable --now trinohubTwo things the host needs, because they're what the stack would otherwise set up:
- The control-plane instance profile attached —
TrinoHubControlPlaneRolewithdeploy/iam-control-plane-policy.json, plusTrinoHubNodeRoleforiam:PassRole. Instance-profile auth is the supported model: boto3's default credential chain means static keys do work, but they give up the "no AWS keys, ever" guarantee the security model is built on. - Network reach to the clusters it launches — nodes fetch signed config from the
control plane on port
8000, and the control plane polls coordinators on8080. The host should sit in, or be routed to, the VPC where clusters run.
Running the control plane off EC2 entirely works but degrades. Without EC2 instance metadata it can't discover its own private IP or security groups, so it won't auto-authorize node ↔ control-plane traffic (you add those security-group rules yourself), and node config gets embedded in EC2 user data instead of fetched over a signed URL.
Full walkthrough — systemd, nginx, IAM, the first-run setup token, the UI CIDR allowlist, and AMI-hygiene notes:
You don't need AWS to develop the app or run the tests — the suites use in-memory AWS/Trino fakes. You only need real AWS to actually provision clusters.
git clone https://github.com/BitRefinery/trinohub.git
cd trinohub
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m uvicorn trinohub.api:app --host 0.0.0.0 --port 8000 --log-level warning
# then open http://127.0.0.1:8000 (OpenAPI docs at /docs)First run shows the setup wizard; once an admin exists, sign in. (Cluster
provisioning expects the TrinoHubControlPlaneRole instance profile, so that part
only works on AWS.)
Run the tests with the project virtualenv (bare python3 may silently skip the
FastAPI route tests if dependencies are missing):
.venv/bin/python -m unittest discover -s tests -v # unit + API route tests
.venv/bin/python testing/run_e2e.py # end-to-end workflow suite (no AWS, no billing)- Runs entirely in your own AWS account — the control plane and every Trino cluster are deployed into your VPC. Query data flows between your worker nodes and your S3/Glue over your own network and IAM; it never traverses a TrinoHub-hosted service or leaves your account.
- No AWS static credentials, ever — instance-profile auth for the control plane, a passed node role for clusters. The UI never displays AWS keys or secrets.
- Allowed-UI-CIDR enforcement at the application layer (loopback health/node-config exempt).
- Signed, per-cluster bootstrap tokens so EC2 nodes fetch only their own Trino config.
- Hashed passwords, httpOnly session cookies,
401→ redirect to login. .gitignoreexcludes.env,.venv/,*.key,*.pem,.trinohub/. Never commit tokens.
| Path | What it is |
|---|---|
trinohub/ |
The app — api.py (FastAPI routes), server.py (TrinoHubApp logic), aws_checks.py, database.py, security.py. |
web/ |
The served frontend — index.html, styles.css, app.js, logo.svg. |
deploy/ |
systemd unit + nginx config, IAM templates, and the clean-account validation driver. |
tests/ |
Unit and API route tests. |
testing/ |
End-to-end workflow suite with in-memory AWS/Trino fakes. |
docs/ |
Operator-facing guides (getting started, clusters, catalogs, queries, security). |
docs/getting-started.md— getting started with TrinoHub.docs/first-run-setup.md— first-run setup & AWS IAM validation.docs/managing-clusters.md— create, operate, and tune clusters.docs/accelerated-clusters.md— object-store caching on NVMe for S3 / Iceberg / Delta catalogs, and when it pays off.docs/settings-and-security.md— settings and the security model.deploy/aws/README.md— deploy on AWS with the CloudFormation stack (recommended install).deploy/README.md— install on a host you manage yourself — systemd, nginx, IAM, setup token, and AMI notes.deploy/VALIDATION.md— clean-account validation gate (launches billable AWS resources; requires explicit billing confirmation).CHANGELOG.md— release history, notable changes, and per-release upgrade notes.docs/releasing.md— maintainer release checklist and upgrade procedure.
Kubernetes, billing/chargeback, replicated clusters, query routing, and replicating any commercial managed-Trino product's UI or trademarks are kept deliberately out of scope.
TrinoHub also doesn't ship Terraform or Helm modules. You can absolutely run the control plane on a host you provision yourself (see Bring your own host) — the infrastructure-as-code around it is just yours to own, not something TrinoHub generates.
Not out of scope, only not built yet: a second cloud provider. AWS is the only
implementation today, but trinohub/cloud_provider.py is a deliberate seam for adding
another — tracked in #7.
See LICENSE.












