Terraform provider for 3x-ui (Xray/VLESS/Reality/WireGuard) — manage inbounds, clients, panel settings, cluster nodes & Xray config as code. GitOps for your VPN panel.
English | فارسی | العربية | 中文 | Español | Русский | Türkçe
Terraform Provider for 3x-ui
Manage 3x-ui inbounds, clients, panel settings, and Xray configuration as code — backup, migrate, and scale your VPN/proxy fleet without clicking through the panel.
Why use it
Running 3x-ui in production means dozens of inbounds, hundreds of clients, and Xray configuration that is easy to break. With this provider you can:
- Treat configuration as code — your inbound list lives in git, every change is reviewed and versioned.
- Migrate between servers — re-create the same setup on a new VPS with one
terraform apply. - Snapshot the panel —
terraform state pullis a full export of inbounds, clients, and settings. - Scale onboarding — add 100 clients in a single PR instead of 100 panel clicks.
- Plan before prod —
terraform planshows exactly what will change before anything ships.
Without vs with the provider
| Task | Panel UI | This provider | | --- | --- | --- | | Add 50 clients | 50 forms, ~30 seconds each | one for_each, one apply | | Migrate to a new server | manual re-entry | terraform apply against the new endpoint | | Audit who has access today | scroll the client list | git log on a .tf file | | Roll back a misconfiguration | restore from a JSON backup | git revert + terraform apply | | Sync staging ↔ production | export/import JSON, fix conflicts | shared module + per-environment vars | | Rotate Reality keys on 10 hosts | open 10 panels, click each | one variable change, one apply |
Quick Start
terraform {
required_providers {
threexui = {
source = "batonogov/threexui"
}
}
}
provider "threexui" { endpoint = "http://localhost:2053" username = "admin" password = "admin" }
resource "threexui_inbound" "vless" { remark = "VLESS Reality" port = 443 protocol = "vless"
vless_settings { decryption = "none" }
stream_settings { network = "tcp" security = "reality" reality_settings { target = "www.amazon.com:443" server_names = ["www.amazon.com"] } }
sniffing { enabled = true dest_override = ["http", "tls", "quic", "fakedns"] } }
resource "threexuiinboundclient" "client_a" { inboundid = threexuiinbound.vless.id email = "client-a@example.com" enable = true flow = "xtls-rprx-vision" }
OpenTofu users: use the full registry address:>
> >> source = "registry.terraform.io/batonogov/threexui"
The provider is not available in the OpenTofu Registry (why).
Compatibility
Support policy: the provider officially supports four 3x-ui minor lines: v3.1.x, v3.2.x, v3.3.x, and v3.4.x — every released patch in all four lines is exercised by the acceptance matrix on each push to main and every pull request.
| 3x-ui version | Status | | --- | --- | | v3.4.2 | Tested | | v3.4.1 | Tested | | v3.4.0 | Tested | | v3.3.1 | Tested | | v3.3.0 | Tested | | v3.2.8 | Tested | | v3.2.7 | Tested | | v3.2.6 | Tested | | v3.2.5 | Tested | | v3.2.0 | Tested | | v3.1.0 | Tested |
Newer protocol features are guarded with requireMinVersion and skip automatically on older versions, so the provider runs cleanly across the matrix without per-version forks.
Examples
| Example | Description | | --- | --- | | Provider with env config | Configure the provider using Terraform variables and TFVAR_* environment variables | | Trojan inbound | Trojan protocol with WebSocket transport | | Shadowsocks inbound | Shadowsocks with AEAD cipher | | Inbound with clients | Complete workflow: inbound + multiple clients | | Multi-server fleet | Manage many 3x-ui hosts via a reusable module + foreach | | Import existing resources | Import existing 3x-ui resources into Terraform state |
Guides
In-repo walkthroughs for common operational scenarios:
- Backup-as-code — keep your full panel state in git, restore in seconds.
- Migrating 3x-ui between servers — move an entire panel to a new VPS without re-typing anything.
- Onboarding many clients at once —
foreachpatterns and CSV-driven onboarding.
Documentation
Full documentation is available on the Terraform Registry.
Resources
| Resource | Description | | --- | --- | | threexui_inbound | Inbound proxy (vless, vmess, trojan, shadowsocks, http, mixed, wireguard, tunnel, hysteria; legacy socks/dokodemo-door before 3.2) | | threexuiinboundclient | Client within an inbound | | threexui_node | Cluster node / multi-node registration | | threexuipanelgeneral | General panel settings | | threexuipanelsecurity | Security settings (2FA) | | threexuipaneluser | Admin credentials | | threexuipaneltelegram | Telegram bot integration | | threexuipanelemail | SMTP/email notifications (v3.4.0+) | | threexuipanelsubscription | Subscription service settings | | threexuixraybasics | Basic Xray config (log, policy, api, stats) | | threexuixraydns | DNS servers and hosts | | threexuixrayrouting | Routing rules | | threexuixraybalancers | Load balancers | | threexuixrayreverse | Reverse proxy (bridges, portals) | | threexuixrayoutbounds | Outbound connections | | threexuixrayversion | Installed Xray core version |
Data Sources
| Data Source | Description | | --- | --- | | threexui_inbounds | List of all inbounds (JSON, sensitive) | | threexui_nodes | Cluster node tree / multi-node surface (JSON, sensitive) | | threexuiserverstatus | Server status: CPU, memory, disk, uptime (JSON) | | threexui_settings | All panel settings (JSON, sensitive) | | threexuixrayconfig | Current Xray template (JSON, sensitive) | | threexuixrayversions | Available Xray versions (list of strings) | | threexuionlineclients | Currently online client emails | | threexuiclienttraffics | Client traffic statistics by email |
Security
The provider handles secrets the panel issues automatically (Reality privateKey, WireGuard secretKey, client UUIDs, Telegram bot tokens, LDAP passwords). All such fields are marked Sensitive and never logged in plaintext. See SECURITY.md for the full list and for guidance on protecting your Terraform state.
Development
Requirements
- Go (version pinned in
go.mod) - Task — task runner
- golangci-lint — linter
- pre-commit — git hooks framework
- Docker — for the local 3x-ui environment
Commands
task build # Build the provider
task fmt # Format code (gofmt)
task vet # Run go vet
task lint # Run golangci-lint
task pre-commit # Run all checks manually (fmt, vet, lint, build)
task test:unit # Run unit tests (no Docker / Terraform needed)
task test:acc # Run acceptance tests (starts docker compose)
task test # Run unit + acceptance tests
Local environment
# Start 3x-ui on localhost:2053
docker compose up -d
Login: admin / admin
Stop
docker compose down
Contributing
See CONTRIBUTING.md for local setup, testing, and submission guidelines. Bug reports, feature requests, and pull requests are all welcome — and so are notes about which 3x-ui versions you run in production.
Changelog
Releases follow Conventional Commits and are published automatically. See CHANGELOG.md for the full version history.