=============== 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; } ```