===============
LIBRARY RULES
===============
From library maintainers:
- This repository is a Terraform Provider (type name `threexui`), NOT the 3x-ui panel. Users manage resources/data sources such as threexui_inbound, threexui_inbound_client, threexui_panel_*, and threexui_xray_*.
- Resources/data sources are built with terraform-plugin-framework (not SDKv2). Schema helpers live in provider/_schema.go.
- JSON string fields (settings, stream_settings, sniffing) convert through three layers: typed model (types.String/Int64/Bool) <-> untyped map <-> JSON string. See provider/settings.go and provider/stream_settings.go.
- The 3x-ui-/ directories are read-only upstream source snapshots used only to verify API/struct truth for drift tests. Never cite their code as the provider's own API.
- Supported 3x-ui versions: v3.1.x, v3.2.x, v3.3.x, v3.4.x, v3.5.x (up to v3.5.0). Version-specific features are gated with requireMinVersion in acceptance tests.
### Local Setup and Build
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/CONTRIBUTING.md
Clone the repository, install pre-commit hooks, and build the provider locally.
```bash
git clone https://github.com/batonogov/terraform-provider-threexui.git
cd terraform-provider-threexui
pre-commit install
task build
```
--------------------------------
### Get Online Clients
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/data-sources/online_clients.md
Example of how to retrieve the list of online client emails and output them.
```hcl
data "threexui_online_clients" "current" {}
output "online_clients" {
value = data.threexui_online_clients.current.clients
}
```
--------------------------------
### Example Usage of threexui_xray_versions Data Source
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/data-sources/xray_versions.md
This example shows how to use the threexui_xray_versions data source to retrieve available Xray versions and output them.
```hcl
data "threexui_xray_versions" "available" {}
output "xray_versions" {
value = data.threexui_xray_versions.available.versions
}
```
--------------------------------
### Example Usage of threexui_client_traffics Data Source
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/data-sources/client_traffics.md
This example demonstrates how to retrieve client traffic statistics using the `threexui_client_traffics` data source and output the upload and download bytes. Ensure the email provided matches an existing client.
```hcl
data "threexui_client_traffics" "example" {
email = "my-client"
}
output "upload_bytes" {
value = data.threexui_client_traffics.example.up
}
output "download_bytes" {
value = data.threexui_client_traffics.example.down
}
```
--------------------------------
### Example Usage
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_routing.md
This example demonstrates how to configure Xray routing using the threexui_xray_routing resource.
```hcl
resource "threexui_xray_routing" "config" {
domain_strategy = "AsIs"
domain_matcher = "hybrid"
rule {
type = "field"
ip = ["geoip:private"]
outbound_tag = "blocked"
}
rule {
type = "field"
domain = ["geosite:category-ads"]
outbound_tag = "blocked"
}
}
```
--------------------------------
### VMess
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for a VMess inbound.
```APIDOC
## threexui_inbound VMess
### Description
Configures a VMess inbound proxy.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "vmess".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### stream_settings
* `network` (string) - Required - The network protocol, e.g., "tcp".
* `security` (string) - Required - The stream security, e.g., "none".
```
--------------------------------
### Manage local 3x-ui environment
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/README.md
Commands to start and stop the local 3x-ui Docker container for development and testing purposes.
```bash
# Start 3x-ui on localhost:2053
docker compose up -d
# Login: admin / admin
# Stop
docker compose down
```
--------------------------------
### Shadowsocks
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for a Shadowsocks inbound.
```APIDOC
## threexui_inbound Shadowsocks
### Description
Configures a Shadowsocks inbound proxy.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "shadowsocks".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### shadowsocks_settings
* `method` (string) - Required - The encryption method, e.g., "chacha20-ietf-poly1305".
* `password` (string) - Required - The password for Shadowsocks.
* `network` (string) - Required - The network protocol, e.g., "tcp,udp".
```
--------------------------------
### threexui_xray_reverse Resource Configuration
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_reverse.md
Example of how to configure the `threexui_xray_reverse` resource to manage Xray reverse proxy settings.
```APIDOC
## Resource: threexui_xray_reverse
### Description
Manages the reverse proxy section of the Xray template configuration. Uses a **set path** strategy -- the provided configuration completely replaces the `reverse` key in the Xray template.
This is a singleton resource. Deleting this resource only removes it from Terraform state; it does not reset the reverse proxy configuration.
> **Compatibility note:** 3x-ui v2.9.4 removed the legacy reverse settings UI page. Keep this resource for legacy panels and existing Xray template imports. For v2.9.4+ VLESS reverse configuration, prefer `reverse_tag` on `threexui_inbound_client` and `threexui_xray_outbounds.vless_settings`.
### Argument Reference
#### bridge (Block, Optional, List)
- `tag` (String, Required) - Bridge tag name.
- `domain` (String, Required) - Bridge domain.
#### portal (Block, Optional, List)
- `tag` (String, Required) - Portal tag name.
- `domain` (String, Required) - Portal domain.
### Attribute Reference
- `id` - The resource identifier (`xray_reverse`).
### Import
```shell
terraform import threexui_xray_reverse.config xray_reverse
```
### Example Usage
```hcl
resource "threexui_xray_reverse" "config" {
bridge {
tag = "bridge"
domain = "test.example.com"
}
portal {
tag = "portal"
domain = "test.example.com"
}
}
```
```
--------------------------------
### Configure 3x-ui Provider
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/index.md
Example of configuring the 3x-ui provider with endpoint, username, and password. This snippet also demonstrates the creation of a VLESS inbound with reality stream settings and sniffing enabled.
```hcl
provider "threexui" {
endpoint = "http://localhost:2053"
username = "admin"
password = "admin"
}
resource "threexui_inbound" "vless" {
port = 443
protocol = "vless"
enable = true
remark = "VLESS Reality"
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"]
}
}
```
--------------------------------
### HTTP Proxy with Authentication
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for an HTTP inbound proxy with basic authentication.
```APIDOC
## threexui_inbound HTTP Proxy
### Description
Configures an HTTP inbound proxy with authentication.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "http".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### http_settings
* `auth` (string) - Required - The authentication method, e.g., "password".
* `allow_transparent` (bool) - Required - Whether to allow transparent proxying.
#### account
* `user` (string) - Required - The username for authentication.
* `pass` (string) - Required - The password for authentication.
```
--------------------------------
### WireGuard
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for a WireGuard inbound.
```APIDOC
## threexui_inbound WireGuard
### Description
Configures a WireGuard inbound interface.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "wireguard".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### wireguard_settings
* `mtu` (list of int) - Required - Maximum Transmission Unit values.
#### peer
* `public_key` (string) - Required - The public key of the peer.
* `allowed_ips` (list of strings) - Required - Allowed IP addresses for the peer.
```
--------------------------------
### VLESS with WebSocket
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for a VLESS inbound using WebSocket transport.
```APIDOC
## threexui_inbound VLESS WebSocket
### Description
Configures a VLESS inbound with WebSocket transport.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "vless".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### vless_settings
* `decryption` (string) - Required - The decryption method, e.g., "none".
#### stream_settings
* `network` (string) - Required - The network protocol, set to "ws".
* `security` (string) - Required - The stream security, e.g., "none".
#### ws_settings
* `path` (string) - Required - The WebSocket path, e.g., "/ws".
```
--------------------------------
### VLESS with Reality
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for a VLESS inbound with Reality stream security.
```APIDOC
## threexui_inbound VLESS with Reality
### Description
Configures a VLESS inbound with Reality security settings.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "vless".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### vless_settings
* `decryption` (string) - Required - The decryption method, e.g., "none".
#### stream_settings
* `network` (string) - Required - The network protocol, e.g., "tcp".
* `security` (string) - Required - The stream security, set to "reality".
#### reality_settings
* `target` (string) - Required - The target address for Reality.
* `server_names` (list of strings) - Required - Server names for Reality.
#### tcp_settings
* `accept_proxy_protocol` (bool) - Required - Whether to accept proxy protocol.
* `header_type` (string) - Required - The header type for TCP settings.
#### sniffing
* `enabled` (bool) - Required - Whether sniffing is enabled.
* `dest_override` (list of strings) - Required - Destinations to override for sniffing.
```
--------------------------------
### Provider Configuration with Bootstrap Credentials
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/index.md
Configures the provider with both steady-state and bootstrap credentials. This is useful for initial setup or when rotating credentials, especially for older 3x-ui versions.
```hcl
provider "threexui" {
endpoint = "http://localhost:2053"
username = var.threexui_username
password = var.threexui_password
bootstrap_username = "admin"
bootstrap_password = "admin"
}
resource "threexui_panel_user" "admin" {
username = var.threexui_username
password = var.threexui_password
}
```
--------------------------------
### Shadowsocks Inbound Setup
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Configure a Shadowsocks inbound with specified method and password. Supports TCP and UDP network.
```hcl
resource "threexui_inbound" "ss" {
port = 8388
protocol = "shadowsocks"
enable = true
remark = "Shadowsocks"
shadowsocks_settings {
method = "chacha20-ietf-poly1305"
password = "my-password"
network = "tcp,udp"
}
}
```
--------------------------------
### VLESS Inbound Client Configuration
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound_client.md
Example of creating a VLESS inbound and a corresponding client with traffic and expiry limits.
```hcl
resource "threexui_inbound" "vless" {
port = 443
protocol = "vless"
enable = true
remark = "VLESS Reality"
vless_settings {
decryption = "none"
}
stream_settings {
network = "tcp"
security = "reality"
reality_settings {
target = "www.amazon.com:443"
server_names = ["www.amazon.com"]
}
}
}
resource "threexui_inbound_client" "user1" {
inbound_id = threexui_inbound.vless.id
email = "user1@example.com"
enable = true
total_gb = 10
expiry_time = 1735689600000
comment = "Main account"
}
```
--------------------------------
### Set Environment Variables for Provider Authentication
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/index.md
Example of setting environment variables to configure the 3x-ui provider. These variables are used for endpoint, username, and password.
```shell
export THREEXUI_ENDPOINT="http://localhost:2053"
export THREEXUI_USERNAME="admin"
export THREEXUI_PASSWORD="secret"
terraform apply
```
--------------------------------
### Subscription URL Generation
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound_client.md
Examples for generating subscription URLs for single and multiple clients using the sub_id attribute.
```hcl
resource "threexui_inbound_client" "user1" {
inbound_id = threexui_inbound.vless.id
email = "user1@example.com"
enable = true
comment = "Main account"
}
output "user1_subscription_url" {
value = "https://your-domain.com/sub/${threexui_inbound_client.user1.sub_id}"
}
```
```hcl
locals {
clients = {
user1 = threexui_inbound_client.user1
user2 = threexui_inbound_client.user2
}
}
output "subscription_urls" {
value = { for name, client in local.clients : name => "https://your-domain.com/sub/${client.sub_id}" }
}
```
--------------------------------
### Restore 3x-ui Panel State After Loss
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/backup-as-code.md
Provides steps to restore a 3x-ui panel after a failure. This involves starting a fresh 3x-ui instance, updating the Terraform configuration to point to the new host, and applying the configuration to recreate all resources from the Terraform state.
```bash
# 1. Spin up a fresh 3x-ui on the new host
docker compose up -d
# 2. Update var.endpoint to point at the new host
echo 'endpoint = "https://new-host:2053"' > terraform.tfvars
# 3. Apply — the provider re-creates everything from your repo
terraform apply
```
--------------------------------
### Example Usage of threexui_panel_telegram
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/panel_telegram.md
This snippet shows how to configure the Telegram bot settings for the 3x-ui panel using the threexui_panel_telegram resource. It includes enabling the bot, setting the token, chat ID, language, and backup/notification preferences.
```hcl
resource "threexui_panel_telegram" "settings" {
tg_bot_enable = true
tg_bot_token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
tg_bot_chat_id = "-1001234567890"
tg_lang = "en-US"
tg_bot_backup = true
tg_bot_login_notify = true
tg_cpu = 80
}
```
--------------------------------
### Run Acceptance Tests
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/CONTRIBUTING.md
Execute acceptance tests which involve spinning up a 3x-ui instance via Docker Compose and running Terraform tests against it. This command handles Docker setup, environment variables, test execution, and teardown.
```bash
task test:acc
```
--------------------------------
### Example Usage of threexui_xray_config Data Source
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/data-sources/xray_config.md
This snippet demonstrates how to retrieve the current Xray configuration using the threexui_xray_config data source and output it as a sensitive value. The `json` attribute is sensitive due to included credentials and identifiers.
```hcl
data "threexui_xray_config" "current" {}
output "xray_config" {
value = data.threexui_xray_config.current.json
sensitive = true
}
```
--------------------------------
### Refresh Test Corpus with Docker and cURL
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/provider/testdata/README.md
Instructions for refreshing the test corpus by starting a local 3x-ui instance, logging in, and fetching raw API payloads using cURL. This process is necessary when the upstream 3x-ui panel updates its API.
```bash
# Login (3x-ui v3 requires CSRF)
COOKIE=$(mktemp)
CSRF=$(curl -fsS -c "$COOKIE" -b "$COOKIE" http://localhost:2053/csrf-token 2>/dev/null \
| sed -n 's/.*"obj":"\([^"].*\)".*/\1/p' || true)
if [ -n "$CSRF" ]; then
curl -fsS -c "$COOKIE" -b "$COOKIE" -H "X-CSRF-Token: $CSRF" \
-d "username=admin&password=admin&_csrf=$CSRF" \
http://localhost:2053/login >/dev/null
else
curl -fsS -c "$COOKIE" -b "$COOKIE" -d 'username=admin&password=admin' \
http://localhost:2053/login >/dev/null
fi
# Inbound list (extract settings/streamSettings/sniffing from each)
curl -s -b "$COOKIE" http://localhost:2053/panel/api/inbounds/list | jq . \
# Xray template
curl -s -b "$COOKIE" -H "X-CSRF-Token: $CSRF" \
-X POST http://localhost:2053/panel/xray | jq .obj \
# Panel settings
curl -s -b "$COOKIE" -H "X-CSRF-Token: $CSRF" \
-X POST http://localhost:2053/panel/setting/all | jq .obj
```
--------------------------------
### Create a threexui_node Resource
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/node.md
Use this snippet to define and configure a new remote 3x-ui node within your cluster. Ensure all required arguments like name, address, and port are provided. Sensitive information such as API tokens should be managed securely, for example, using Terraform variables.
```hcl
resource "threexui_node" "fra1" {
name = "de-fra-1"
remark = "Frankfurt edge"
scheme = "https"
address = "node1.example.com"
port = 2053
base_path = "/"
api_token = var.fra1_api_token
enable = true
tls_verify_mode = "verify"
}
```
--------------------------------
### Basic threexui_panel_general Resource Configuration
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/panel_general.md
Configure general panel settings like web port, base path, page size, and time location. Ensure `web_base_path` matches the provider's `base_path` to maintain connectivity.
```hcl
resource "threexui_panel_general" "settings" {
web_port = 2053
web_base_path = "/panel/"
page_size = 50
time_location = "UTC"
}
```
--------------------------------
### Install a specific Xray version
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_version.md
Use this resource to manage the installed Xray core version. Ensure the desired version is available via the `threexui_xray_versions` data source. Deleting this resource only removes it from Terraform state.
```hcl
data "threexui_xray_versions" "available" {}
resource "threexui_xray_version" "this" {
version = data.threexui_xray_versions.available.versions[0]
}
```
--------------------------------
### Hysteria
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Example configuration for a Hysteria inbound.
```APIDOC
## threexui_inbound Hysteria
### Description
Configures a Hysteria inbound proxy.
### Resource
`threexui_inbound`
### Attributes
* `port` (int) - Required - The port for the inbound.
* `protocol` (string) - Required - The protocol type, set to "hysteria".
* `enable` (bool) - Required - Whether the inbound is enabled.
* `remark` (string) - Required - A remark for the inbound.
### Nested Blocks
#### hysteria_settings
* `version` (int) - Required - The Hysteria version, e.g., 2.
#### stream_settings
* `network` (string) - Required - The network protocol, set to "hysteria".
* `security` (string) - Required - The stream security, e.g., "tls".
```
--------------------------------
### Configure 3x-ui Provider and Resources
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/README.md
Initializes the provider and defines a VLESS inbound with a client.
```hcl
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 "threexui_inbound_client" "client_a" {
inbound_id = threexui_inbound.vless.id
email = "client-a@example.com"
enable = true
flow = "xtls-rprx-vision"
}
```
--------------------------------
### Onboard clients using per-team modules
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/bulk-clients.md
This pattern is ideal when each team manages its own client list. It keeps each team's configuration concise and independently reviewable.
```hcl
module "engineering" {
source = "./modules/team"
inbound_id = threexui_inbound.vless.id
team_name = "engineering"
members = ["alice@example.com", "bob@example.com"]
quota_gb = 500
}
module "sales" {
source = "./modules/team"
inbound_id = threexui_inbound.vless.id
team_name = "sales"
members = ["carol@example.com"]
quota_gb = 200
}
```
```hcl
variable "inbound_id" { type = number }
variable "team_name" { type = string }
variable "members" { type = list(string) }
variable "quota_gb" { type = number }
resource "threexui_inbound_client" "member" {
for_each = toset(var.members)
inbound_id = var.inbound_id
email = each.value
enable = true
total_gb = var.quota_gb * 1024 * 1024 * 1024
}
```
--------------------------------
### Import threexui_xray_basics resource
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_basics.md
Imports an existing xray_basics configuration into the Terraform state.
```shell
terraform import threexui_xray_basics.config xray_basics
```
--------------------------------
### threexui_xray_version Resource
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_version.md
Manages the installed Xray core version on the 3x-ui panel. This is a singleton resource, meaning only one instance should exist per provider. Deleting this resource only removes it from Terraform state; the installed Xray version is not reverted.
```APIDOC
## threexui_xray_version (Resource)
### Description
Manages the installed Xray core version on the 3x-ui panel.
This is a singleton resource -- only one instance should exist per provider. Deleting this resource only removes it from Terraform state; the installed Xray version is not reverted.
### Example Usage
```hcl
data "threexui_xray_versions" "available" {}
resource "threexui_xray_version" "this" {
version = data.threexui_xray_versions.available.versions[0]
}
```
### Argument Reference
- `version` (Required, String) - The desired Xray version to install (e.g. `"v25.1.1"`). Must include the `v` prefix. Available versions can be retrieved via the `threexui_xray_versions` data source.
### Attribute Reference
- `id` (String) - Always `"xray_version"`.
- `current_version` (String) - The currently installed Xray version (with `v` prefix).
### Drift Detection
If the Xray version is changed outside Terraform (e.g. via the panel UI), the next `terraform plan` will detect the drift and propose an update to restore the desired version.
### Known Limitations
- **Stopped Xray**: When the Xray process is not running, the 3x-ui API reports the version as `"Unknown"`. In this case, `Read` preserves the previously known version in state and emits a warning. Drift detection is not possible while Xray is stopped — restart Xray via the panel for accurate version tracking.
- **Delete**: Removing this resource only clears Terraform state. The installed Xray version is not reverted.
```
--------------------------------
### Apply Terraform Configuration to New Host
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/server-migration.md
Execute 'terraform apply' to create all resources on the new, empty 3x-ui panel based on your existing Terraform state. This process recreates inbounds, clients, and other configurations.
```bash
terraform apply
```
--------------------------------
### Execute development tasks
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/README.md
Use these commands via the Task runner to manage the provider lifecycle, including building, formatting, linting, and testing.
```bash
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
```
--------------------------------
### Import
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_routing.md
This example shows how to import an existing threexui_xray_routing resource into Terraform state.
```shell
terraform import threexui_xray_routing.config xray_routing
```
--------------------------------
### Configure Xray settings with threexui_xray_basics
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/xray_basics.md
Defines the basic Xray configuration blocks including logging, policy, API, stats, and metrics. This resource uses a merge root strategy, updating only the specified keys.
```hcl
resource "threexui_xray_basics" "config" {
log {
loglevel = "warning"
access = "/var/log/xray/access.log"
error = "/var/log/xray/error.log"
dns_log = false
}
policy {
system {
stats_inbound_downlink = true
stats_inbound_uplink = true
stats_outbound_downlink = true
stats_outbound_uplink = true
}
level {
id = 0
handshake = 4
conn_idle = 300
uplink_only = 2
downlink_only = 5
stats_user_uplink = false
stats_user_downlink = false
buffer_size = 4
}
}
api {
tag = "api"
services = ["HandlerService", "LoggerService", "StatsService"]
}
stats {}
metrics {
tag = "metrics_out"
listen = "127.0.0.1:11111"
}
}
```
--------------------------------
### Run version-specific acceptance tests
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/AGENTS.md
Execute compatibility tests against a specific 3x-ui version.
```bash
THREEXUI_VERSION=v3.1.0 task test:acc:compat
```
--------------------------------
### Hysteria Inbound Client Configuration
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound_client.md
Example of creating a Hysteria inbound and a corresponding client using an auth password.
```hcl
resource "threexui_inbound" "hysteria" {
port = 8443
protocol = "hysteria"
enable = true
remark = "Hysteria"
hysteria_settings {
version = 2
}
stream_settings {
network = "hysteria"
security = "tls"
}
}
resource "threexui_inbound_client" "hysteria_user" {
inbound_id = threexui_inbound.hysteria.id
email = "hysteria-user@example.com"
auth = "my-secret-auth"
enable = true
}
```
--------------------------------
### Create multiple clients using an inline map
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/bulk-clients.md
Use this pattern for small, hand-curated client lists. Adding or removing a client is as simple as modifying a single line in the map.
```hcl
locals {
clients = {
"alice@example.com" = { flow = "xtls-rprx-vision" }
"bob@example.com" = { flow = "xtls-rprx-vision" }
"carol@example.com" = { flow = "" }
}
}
resource "threexui_inbound_client" "by_email" {
for_each = local.clients
inbound_id = threexui_inbound.vless.id
email = each.key
enable = true
flow = each.value.flow
}
```
--------------------------------
### Commit Message Conventions
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/CONTRIBUTING.md
Examples of commit messages following the Conventional Commits format for different types of changes.
```bash
feat: add mixed inbound support
```
```bash
fix: handle empty client list
```
```bash
docs: update README examples
```
```bash
test: add round-trip tests for DNS
```
```bash
chore: bump golangci-lint version
```
--------------------------------
### Import Existing 3x-ui Inbounds and Clients
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/backup-as-code.md
Demonstrates how to import existing 3x-ui inbounds and clients into Terraform state. Inbounds are imported by their ID, while clients require a composite ID of `:`. After import, run `terraform plan` and reconcile differences.
```bash
# inbounds (look up IDs in the panel or via the API)
terraform import threexui_inbound.vless 5
terraform import threexui_inbound.trojan 6
# clients use composite IDs: :
terraform import 'threexui_inbound_client.alice' '5:d4f1a2b3-c4d5-6e7f-8a9b-0c1d2e3f4a5b'
# panel settings are singletons
terraform import threexui_panel_general.this settings
terraform import threexui_panel_telegram.this settings
```
--------------------------------
### Get Server Status
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/data-sources/server_status.md
Use the `threexui_server_status` data source to retrieve the current server status and output it as a JSON string.
```hcl
data "threexui_server_status" "current" {}
output "server_status" {
value = data.threexui_server_status.current.json
}
```
--------------------------------
### Hysteria Inbound Setup
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/inbound.md
Configure a Hysteria inbound, specifying version and stream settings. Note that 'network' should be set to 'hysteria'.
```hcl
resource "threexui_inbound" "hysteria" {
port = 8443
protocol = "hysteria"
enable = true
remark = "Hysteria"
hysteria_settings {
version = 2
}
stream_settings {
network = "hysteria"
security = "tls"
}
}
```
--------------------------------
### Configure Caddy for Subscription Path
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/panel_subscription.md
When the 3x-ui panel runs behind a reverse proxy like Caddy, configure it to forward requests for the subscription path to the panel's subscription port.
```caddy
handle /sub/* {
reverse_proxy 3x-ui:2096
}
```
--------------------------------
### Run Unit Tests
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/CONTRIBUTING.md
Execute unit tests for the provider. This does not require Docker or Terraform.
```bash
task test:unit
```
--------------------------------
### Minimal Provider Configuration with Environment Variables
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/index.md
Minimal provider configuration that relies on environment variables for authentication details. Ensure THREEXUI_ENDPOINT, THREEXUI_USERNAME, and THREEXUI_PASSWORD are set.
```hcl
provider "threexui" {}
```
--------------------------------
### Configure 3x-ui Provider and S3 Backend
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/backup-as-code.md
Sets up the Terraform configuration with the 3x-ui provider and specifies an S3 backend for storing the Terraform state. Ensure your AWS credentials and S3 bucket are configured.
```hcl
terraform {
required_providers {
threexui = {
source = "batonogov/threexui"
}
}
backend "s3" {
bucket = "panel-state"
key = "production/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "tf-locks"
}
}
provider "threexui" {
endpoint = var.endpoint
username = var.username
password = var.password
}
```
--------------------------------
### Configure Panel Subscription Service
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/panel_subscription.md
Use this snippet to enable and configure the subscription service, including JSON format, port, path, and domain.
```hcl
resource "threexui_panel_subscription" "settings" {
sub_enable = true
sub_json_enable = true
sub_port = 2096
sub_path = "/sub/"
sub_domain = "sub.example.com"
}
```
--------------------------------
### Confirm Clean State with Terraform Plan
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/guides/server-migration.md
Run 'terraform plan' to ensure your current infrastructure matches the configuration before proceeding with the migration. Resolve any reported drift to avoid carrying over unexpected changes.
```bash
terraform plan
# expected: "No changes. Your infrastructure matches the configuration."
```
--------------------------------
### Configure OpenTofu Registry Source
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/README.md
Required source configuration for OpenTofu users due to registry availability.
```hcl
source = "registry.terraform.io/batonogov/threexui"
```
--------------------------------
### Basic Panel User Configuration
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/panel_user.md
Use this snippet to set the admin username and password for the 3x-ui panel. Ensure the username and password are kept in sync with the provider's steady-state configuration.
```hcl
resource "threexui_panel_user" "admin" {
username = "myadmin"
password = "s3cureP@ss"
}
```
--------------------------------
### Configure Nginx for Subscription Path
Source: https://github.com/batonogov/terraform-provider-threexui/blob/main/docs/resources/panel_subscription.md
When the 3x-ui panel runs behind a reverse proxy like Nginx, configure it to forward requests for the subscription path to the panel's subscription port.
```nginx
location /sub/ {
proxy_pass http://3x-ui:2096;
}
```