Terraform Provider

The Terraform provider for coreX Manager lets you manage coreX Platform resources as Terraform infrastructure-as-code. It covers HAProxy routing, SSL/TLS, security lists, security rules, WAF, traffic management, observability, MCP gateway, risk scoring, and HA configuration — everything exposed by the coreX REST API (/api/v1) that represents declarative desired state.

Why Use Terraform with coreX?

ApproachBest for
TerraformVersion-controlled config, CI/CD pipelines, multi-environment promotion, drift detection, team collaboration
Web UIExploratory changes, one-off configuration, visual debugging
REST APIScripts, automation, integration with existing tooling

Terraform is ideal when you want your coreX configuration to live alongside your other infrastructure code (cloud resources, DNS, Kubernetes manifests) in a single versioned repository. Every terraform apply produces an audit trail via coreX’s audit system, and terraform plan shows exactly what will change before you commit.

Installation

From source

git clone https://github.com/ne4u/terraform-provider-corex.git
cd terraform-provider-corex
make install

This builds the provider and installs it to ~/.terraform.d/plugins/registry.terraform.io/ne4u/corex/dev/<os>_<arch>/.

Local development overrides

For local development (using a locally-built provider instead of the registry), add to ~/.terraformrc:

provider_installation {
  dev_overrides {
    "registry.terraform.io/ne4u/corex" = "~/.terraform.d/plugins/registry.terraform.io/ne4u/corex/dev/darwin_arm64"
  }
  direct {
    exclude = ["registry.terraform.io/ne4u/*"]
  }
}
dev_overrides skips init

When dev_overrides is active, terraform init will print a warning and the provider won’t be downloaded from the registry. This is expected — Terraform uses your locally-built binary instead. Remove the override when you want to use the published registry version.

Provider Configuration

terraform {
  required_providers {
    corex = {
      source  = "registry.terraform.io/ne4u/corex"
      version = "~> 0.1"
    }
  }
}

provider "corex" {
  host     = "https://corex.example.com"
  username = "admin"
  password = var.corex_password

  # Skip TLS verification (not recommended for production):
  # insecure = true
}

Provider Attributes

AttributeTypeEnv varDescription
hoststringCOREX_HOSTBase URL of coreX Manager. Required.
usernamestringCOREX_USERNAMEOAuth2 username. Mutually exclusive with token.
passwordstringCOREX_PASSWORDOAuth2 password. Sensitive.
totp_codestringCOREX_TOTP_CODETOTP code if 2FA is enabled. Sensitive.
tokenstringCOREX_TOKENPre-issued JWT bearer token. Sensitive. Mutually exclusive with username/password.
insecureboolCOREX_INSECURESkip TLS verification. Default false.

Authentication

The provider supports two authentication modes:

Username + password (OAuth2 password flow):

provider "corex" {
  host     = "https://corex.example.com"
  username = "admin"
  password = var.corex_password
}

Static token (pre-issued JWT — useful for CI/CD):

provider "corex" {
  host   = "https://corex.example.com"
  token  = var.corex_token
}

For CI/CD pipelines, prefer the token method — it avoids storing passwords and supports long-lived service tokens. For 2FA-protected accounts, provide totp_code alongside username/password (note: TOTP codes expire every 30 seconds, so this is only practical for interactive use).

Use environment variables for secrets

Never hardcode credentials in .tf files. Use environment variables (COREX_HOST, COREX_USERNAME, COREX_PASSWORD, COREX_TOKEN) or a secrets manager (Vault, AWS Secrets Manager, etc.) and pass them as variables.

Auto-Apply Behavior

After every Create/Update/Delete on HAProxy control-plane resources (backends, listeners, WAF rules, security rules, etc.), the provider automatically calls POST /config/apply and polls the async task until completion. This means your changes are immediately active in HAProxy after terraform apply — you don’t need to manually click “Apply Changes” in the UI.

MCP Gateway resources do not trigger config apply — they auto-regenerate the gateway config bundle server-side instead.

Apply is automatic

Each resource mutation triggers a full HAProxy config apply. If your Terraform run creates 20 resources, that’s 20 sequential applies. For large initial imports, consider using terraform import to adopt existing resources, or structure your Terraform runs to batch related resources together.

Resources

The provider manages 50+ resource types across all coreX Platform feature areas.

Core Routing

ResourceDescription
corex_backendBackend pool with servers, health checks, stick tables
corex_serverBackend server (child of a backend)
corex_backend_ruleRouting rule from listener to backend
corex_listenerHAProxy listener (bind address/port, SSL, protocol)

SSL/TLS

ResourceDescription
corex_certificateTLS certificate (ACME issuance or custom upload)
corex_cipher_suiteCipher suite configuration

Security Lists

ResourceDescription
corex_network_list / corex_network_list_entryIP/CIDR lists
corex_asn_list / corex_asn_list_entryASN lists
corex_geo_list / corex_geo_list_entryGeoIP country lists
corex_ja4_list / corex_ja4_list_entryJA4 TLS fingerprint lists
corex_pattern_list / corex_pattern_list_entryPattern lists
corex_dynamic_feedDynamic feed for security lists

Security Rules & WAF

ResourceDescription
corex_security_ruleExpression-based security rule
corex_waf_ruleWAF rule (Coraza/ModSecurity)
corex_waf_exceptionWAF rule exception

Traffic

ResourceDescription
corex_rate_limitRate limiting rule
corex_response_headerResponse header manipulation
corex_request_headerRequest header manipulation
corex_redirectURL redirect
corex_rewriteURL rewrite
corex_response_transformResponse body transformation
corex_error_pageCustom error page
corex_fcgi_appFastCGI application

Cache

ResourceDescription
corex_cache_configCache configuration (per backend)
corex_cache_ruleCache rule (child of cache config)

Observability

ResourceDescription
corex_log_destinationLog destination (syslog/file)
corex_logged_fieldCustom logged field

Management

ResourceDescription
corex_userUser account
corex_settingGeneric setting (key-value)
corex_maxmind_license_keyMaxMind GeoIP license key (singleton)

Page Protect

ResourceDescription
corex_page_protect_policyPage protection policy
corex_page_protect_scriptPage protection script
corex_page_protect_settingsPage protect global settings (singleton)

API Armor

ResourceDescription
corex_api_armor_auth_policyAPI authentication policy
corex_api_armor_api_key_listAPI key list
corex_api_armor_openapi_specOpenAPI specification
corex_api_armor_settingsAPI Armor global settings (singleton)

Risk Scoring

ResourceDescription
corex_risk_rulesetRisk ruleset
corex_risk_ruleRisk scoring rule

High Availability

ResourceDescription
corex_ha_configHigh availability configuration (singleton)

Singleton Settings

ResourceDescription
corex_global_optionsHAProxy global options (singleton)
corex_captcha_settingsCAPTCHA settings (singleton)
corex_captcha_keyCAPTCHA site key
corex_ssl_labs_settingsSSL Labs scan settings (per certificate)

MCP Gateway

ResourceDescription
corex_mcp_teamMCP gateway team
corex_mcp_team_memberTeam membership
corex_mcp_serverMCP server registration
corex_mcp_server_replicaMCP server replica
corex_mcp_identityMCP identity (PAT/JWT)
corex_mcp_policyMCP access policy
corex_mcp_dlp_ruleDLP rule
corex_mcp_guardrailLLM guardrail
corex_mcp_skillMCP skill
corex_mcp_skill_versionMCP skill version (immutable)
corex_mcp_alert_configAlert configuration (singleton)

Data Sources

Data sources let you read coreX Platform state without managing it — useful for wiring outputs into other Terraform resources or for drift detection.

Data sourceDescription
corex_config_statusHAProxy config apply status
corex_config_previewGenerated HAProxy config text
corex_config_diffDiff between applied and pending config
corex_config_snapshotsConfig snapshot history
corex_backendLook up a backend by name
corex_listenerLook up a listener by name
corex_system_statsHAProxy process stats
corex_haproxy_statsHAProxy frontend/backend metrics
corex_healthSystem health
corex_audit_eventsAudit log events
corex_recent_logsRecent HAProxy logs
corex_stick_tablesStick table summaries
corex_stick_tableStick table entries
corex_valkey_infoValkey server info
corex_valkey_namespacesValkey keyspace namespaces
corex_geoip_statusGeoIP database status
corex_asn_lookupASN/GeoIP lookup for an IP
corex_ssl_labs_scansSSL Labs scan results
corex_mcp_gateway_statusMCP gateway status
corex_mcp_config_statusMCP config bundle status
corex_mcp_eventsMCP gateway events
corex_mcp_marketplace_searchMCP marketplace search

Excluded API Endpoints

The following imperative/action endpoints are not managed by Terraform because they don’t represent declarative desired state. Use the coreX API or UI directly:

EndpointAction
POST /config/revertDiscard pending config changes
POST /config/snapshots/{id}/rollbackRoll back to a previous config
POST /cache/{backend_id}/clearClear cache
POST /settings/geoip/downloadTrigger GeoIP DB download
POST /system/export / POST /system/restoreBackup/restore
POST /mcp/config/regenerateRegenerate MCP gateway config
POST /mcp/skills/{id}/publish / POST /mcp/skills/{id}/rollbackSkill publishing
POST /mcp/skills/importImport skill from URL
POST /mcp/servers/{id}/oauth/configureOAuth setup
POST /mcp/marketplace/install / POST /mcp/marketplace/uninstallMarketplace management
POST /risk-rules/seed-baselineSeed risk rules
POST /ha/applyApply HA config

Examples

Backend with Servers and Listener

resource "corex_backend" "web" {
  name      = "web-pool"
  mode      = "http"
  protocol  = "http"
  algorithm = "roundrobin"

  health_check_enabled  = true
  health_check_interval = 5000
  health_check_uri      = "/health"
  health_check_method   = "GET"

  retries    = 3
  redispatch = true
}

resource "corex_server" "web1" {
  backend_id = corex_backend.web.id
  name       = "web-server-1"
  address    = "10.0.0.1"
  port       = 8080
  weight     = 100
  check      = true
}

resource "corex_server" "web2" {
  backend_id = corex_backend.web.id
  name       = "web-server-2"
  address    = "10.0.0.2"
  port       = 8080
  weight     = 100
  check      = true
}

resource "corex_listener" "https" {
  name               = "https-listener"
  bind_address       = "0.0.0.0"
  bind_port          = 443
  mode               = "http"
  protocol           = "https"
  ssl_enabled        = true
  http2              = true
  default_backend_id = corex_backend.web.id
}

Security Lists

resource "corex_network_list" "blocked_ips" {
  name        = "blocked-ips"
  description = "Known malicious IP addresses"
}

resource "corex_network_list_entry" "bad_ip_1" {
  list_id = corex_network_list.blocked_ips.id
  value   = "10.0.0.0/24"
  note    = "Internal test range"
}

resource "corex_asn_list" "blocked_asns" {
  name        = "blocked-asns"
  description = "Blocked autonomous systems"
}

resource "corex_asn_list_entry" "bad_asn" {
  list_id = corex_asn_list.blocked_asns.id
  value   = "AS12345"
  note    = "Abuse provider"
}

resource "corex_geo_list" "blocked_countries" {
  name        = "blocked-countries"
  description = "Blocked countries"
}

resource "corex_geo_list_entry" "blocked_country" {
  list_id = corex_geo_list.blocked_countries.id
  value   = "CN"
  note    = "Geo-blocking"
}

MCP Gateway

resource "corex_mcp_team" "engineering" {
  name        = "Engineering"
  slug        = "engineering"
  description = "Engineering team MCP gateway"
}

resource "corex_mcp_server" "github" {
  team_id      = corex_mcp_team.engineering.id
  name         = "github-mcp"
  display_name = "GitHub MCP Server"
  description  = "GitHub tools via MCP"
  url          = "https://mcp.github.example.com/mcp"
  enabled      = true
  verify_tls   = true
  auth_type    = "bearer"
  auth_secret  = var.github_mcp_token
  timeout_ms   = 30000
}

resource "corex_mcp_policy" "allow_engineering" {
  team_id    = corex_mcp_team.engineering.id
  name       = "allow-engineering-tools"
  enabled    = true
  expression = "team.name == \"engineering\""
  action     = "allow"
  log        = true
}

resource "corex_mcp_dlp_rule" "block_secrets" {
  team_id   = corex_mcp_team.engineering.id
  name      = "block-aws-keys"
  enabled   = true
  direction = "both"
  detector  = "aws_key"
  action    = "block"
}

resource "corex_mcp_guardrail" "jailbreak" {
  team_id   = corex_mcp_team.engineering.id
  name      = "jailbreak-protection"
  enabled   = true
  direction = "request"
  pack      = "builtin:jailbreak_v1"
  action    = "block"
}

Reading State with Data Sources

# Check if there are unapplied config changes
data "corex_config_status" "current" {}

output "has_pending_changes" {
  value = data.corex_config_status.current.has_pending
}

# Get the generated HAProxy config for review
data "corex_config_preview" "current" {}

output "haproxy_config" {
  value     = data.corex_config_preview.current.config_text
  sensitive = true
}

# Look up a backend by name to reference its ID
data "corex_backend" "web" {
  name = "web-pool"
}

# Check system health before deploying
data "corex_health" "status" {}

output "system_healthy" {
  value = data.corex_health.status.healthy
}

Importing Existing Resources

If you have an existing coreX deployment configured via the UI, you can adopt those resources into Terraform using terraform import:

# Import a backend by its coreX ID
terraform import corex_backend.web 5

# Import a listener
terraform import corex_listener.https 12

# Import a security rule
terraform import corex_security_rule.block_bots 8

After import, run terraform plan — Terraform will show the current state as the desired state. Add the corresponding resource blocks to your .tf files to match, then subsequent plans will show no changes.

Import before writing resource blocks

For existing deployments, import first, then write resource blocks that match the imported state. This avoids Terraform trying to recreate resources that already exist. Use terraform show after import to see the exact attributes you need to replicate.

CI/CD Integration

For pipeline-based deployments, use a service token and environment variables:

# GitHub Actions example
- name: Terraform Apply
  run: terraform apply -auto-approve
  env:
    COREX_HOST: ${{ secrets.COREX_HOST }}
    COREX_TOKEN: ${{ secrets.COREX_TOKEN }}
# main.tf — no credentials in the file
provider "corex" {
  # host and token come from COREX_HOST / COREX_TOKEN env vars
}
Auto-apply in CI

Each resource mutation triggers a HAProxy config apply. In CI, a large terraform apply will apply the config once per resource change. For initial deployments with many resources, expect the apply to take longer than a typical Terraform run. Subsequent runs with few changes are fast.

Development

The provider is written in Go and uses the Terraform Plugin Framework.

# Build the provider binary
make build

# Run the test suite
make test

# Format and lint
make fmt
make vet

# Install to the local Terraform plugin directory
make install

The source code is available at github.com/ne4u/terraform-provider-corex.

Next Steps