Manage HTTP container path rules with Terraform
A path rule applies basic authentication, rate limiting, or IP allow / deny lists to a specific URL prefix on an HTTP container. The longest matching path wins per request — a rule on /api/admin takes precedence over the container's defaults for requests that start with /api/admin.
A path rule applies basic authentication, rate limiting, or IP allow / deny lists to a specific URL prefix on an HTTP container. The longest matching path wins per request — a rule on /api/admin takes precedence over the container's defaults for requests that start with /api/admin.
Path rules are child resources of an HTTP container, scoped via container_id. You manage the parent container separately (bahriya_container) and reference its id.
Required fields
| Field | Type | Description |
|---|---|---|
container_id | string | UUID of the HTTP container the rule attaches to. Changing this replaces the rule. |
handle | string | A unique identifier for the rule on the container (DNS-1123 compliant: lowercase, alphanumeric, hyphens). Changing this replaces the rule. |
path | string | URL path prefix the rule applies to. Must start with /. |
Optional fields
| Field | Type | Description |
|---|---|---|
priority | integer | Tiebreaker for equal-length prefix matches. Higher wins. Defaults to 0. |
ratelimitingenabled | bool | Turn on per-IP rate limiting on this path. |
ratelimitingrequestspersecond | integer | Max requests per second per IP. |
ratelimitingrequestsperminute | integer | Max requests per minute per IP. |
ratelimitingrequestsperhour | integer | Max requests per hour per IP. |
ipwhitelistenabled | bool | Restrict access to the listed IPs. |
ipwhitelist | list(string) | IP addresses or CIDR ranges. |
ipblacklistenabled | bool | Block the listed IPs. |
ipblacklist | list(string) | IP addresses or CIDR ranges. |
basicauthenabled | bool | Enable HTTP basic authentication on this path. |
basicauthcredentials | list(object) | List of { username, password } pairs accepted on this path. Passwords are sensitive. |
At least one control (basic auth, rate limiting, IP allow-list, or IP deny-list) must be enabled — the apply step fails otherwise.
Example
resource "bahriya_container" "api" {
handle = "my-api"
name = "Public API"
type = "http"
image = "ghcr.io/myorg/api:1.0.0"
project = bahriya_project.production.id
cpu = "500"
memory = "512"
containerport = "8080"
healthcheckpath = "/health"
activeregions = ["falkenstein-1"]
}
resource "bahriya_path_rule" "admin_area" {
container_id = bahriya_container.api.id
handle = "admin-area"
path = "/api/admin"
priority = 100
basicauthenabled = true
basicauthcredentials = [
{
username = "alice"
password = var.admin_password
},
]
ipwhitelistenabled = true
ipwhitelist = ["10.0.0.0/8"]
}
resource "bahriya_path_rule" "webhook" {
container_id = bahriya_container.api.id
handle = "webhook"
path = "/webhook"
ratelimitingenabled = true
ratelimitingrequestsperminute = 60
ratelimitingrequestsperhour = 1000
}How matching works
Per request, the longest matching path prefix wins. If two rules tie on path length, the rule with the higher priority wins. A rule's controls fully override the container-wide settings for the same control type on that path — there is no merge.
For example, a container with rate limiting at 1000 / minute and a path rule with rate limiting at 60 / minute caps the rule's path at 60 / minute (not 1000, not 1060).
Passwords and drift
The API stores basic auth passwords encrypted and never returns the plaintext on subsequent reads — it echoes the sentinel value-hidden-for-your-own-good instead. The provider treats the sentinel as a no-op so re-applying without changing the password does not show as drift. To rotate a password, update the value in your Terraform config and run terraform apply.
Importing an existing rule
To bring an existing path rule under Terraform management, import it with the composite id <container_id>:<path_rule_id>:
terraform import bahriya_path_rule.admin_area \
c0ffee00-aaaa-bbbb-cccc-000000000001:dd0ffee0-1111-2222-3333-444444444444After import the basic auth password starts as the sentinel — the next apply with a real password rotates it.
Pricing
Each enabled control on each rule bills at the same per-region rate as the corresponding container-wide control. A rule with both rate limiting and basic authentication enabled counts as two control instances per region; combined with the container-wide controls, the total per-region billed instances equals (container-wide-enabled ? 1 : 0) + N path rules with that plugin enabled.