Skip to content

Commit d08c526

Browse files
fix: harden effective_domains_pre_expansion + drop FACETS-REQUEST-ID
- effective_domains_pre_expansion: rebuild both ternary branches via dynamic-key `for` with explicit per-attribute reconstruction (tostring/tolist/tomap casts). Forces terraform to infer `map(object({uniform shape}))` regardless of whether the wrapper passes typed or untyped spec. Earlier `rules = {}` fix on the facets literal alone wasn't enough — terraform still inferred object-type on the LHS, leaving the inconsistent-conditional-result error. - FACETS-REQUEST-ID header removed: dropped the auto-injected `proxy_set_header FACETS-REQUEST-ID $request_id` in the gateway SnippetsPolicy. Also stripped from the converter's auto-strip set so any user-defined facets-request-id in proxy_set_headers passes through. knowledge-base.md updated. X-Request-ID continues to be auto-injected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 625b4ef commit d08c526

3 files changed

Lines changed: 30 additions & 7 deletions

File tree

modules/ingress/nginx_gateway_fabric_capillary/1.0/convert_to_capillary.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ def convert_advanced_block(advanced, out_spec, report):
746746
if "proxySetHeaders" in controller:
747747
psh = controller.pop("proxySetHeaders") or {}
748748
if isinstance(psh, dict):
749-
auto = {"x-request-id", "facets-request-id"}
749+
auto = {"x-request-id"}
750750
filtered = {k: v for k, v in psh.items() if k.lower() not in auto}
751751
if filtered:
752752
out_spec["proxy_set_headers"] = filtered

modules/ingress/nginx_gateway_fabric_capillary/1.0/knowledge-base.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ Rules can live in two places on the spec. Each domain is in **exactly one of thr
232232
| `ReferenceGrant` | One per external namespace referenced by a backend | Cross-namespace backends |
233233
| `AuthenticationFilter` | Basic auth filter | `spec.basic_auth: true` |
234234
| `ClientSettingsPolicy` | Request body size limit | Always created; reads `spec.body_size` |
235-
| `SnippetsPolicy` | Gateway-wide NGINX directives | `custom_log_format`, `underscores_in_headers`, `ip_access_control`, `proxy_buffer_size`, `proxy_buffers_number`, `proxy_set_headers`, plus always-on `X-Request-ID` / `FACETS-REQUEST-ID` headers |
235+
| `SnippetsPolicy` | Gateway-wide NGINX directives | `custom_log_format`, `underscores_in_headers`, `ip_access_control`, `proxy_buffer_size`, `proxy_buffers_number`, `proxy_set_headers`, plus always-on `X-Request-ID` header |
236236
| `SnippetsFilter` | Per-route NGINX directives | `rules.*.nginx_timeouts`, `configuration_snippet`, `server_snippet` |
237237
| `Certificate` (cert-manager) | One per cert-manager-issued domain | Domains without `certificate_reference`, or `use_dns01: true` |
238238
| `ClusterIssuer` (cert-manager) | HTTP-01 issuer bound to the Gateway's port 80 listener | Any HTTP-01 domain |
@@ -312,7 +312,7 @@ On first deploy, cert-manager has not yet issued the real cert. The module pre-c
312312
|---|---|
313313
| Access logs | NGF stdout. Format set by `spec.custom_log_format`; `log_format_escape: "json"` for structured logs. |
314314
| Metrics | Prometheus endpoints on data plane pods. Module creates a `PodMonitor` when `prometheus_details` is wired. |
315-
| Request correlation | Module injects `X-Request-ID` and `FACETS-REQUEST-ID` (set to NGINX `$request_id`). Extend via `spec.proxy_set_headers`. |
315+
| Request correlation | Module injects `X-Request-ID` (set to NGINX `$request_id`). Extend via `spec.proxy_set_headers`. |
316316

317317
---
318318

modules/ingress/nginx_gateway_fabric_capillary/1.0/main.tf

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,32 @@ locals {
8686
)
8787

8888
# --- Effective domain state (after ACM/DNS-01 rewrites, before expansion) ---
89-
effective_domains_pre_expansion = local.acm_mode ? lookup(var.instance.spec, "domains", {}) : local.modified_domains
90-
effective_disable_base_domain = local.acm_mode ? lookup(var.instance.spec, "disable_base_domain", false) : (local.use_dns01 && !lookup(var.instance.spec, "disable_base_domain", false) ? true : lookup(var.instance.spec, "disable_base_domain", false))
89+
# Both branches rebuild via dynamic-key `for` with explicit attribute
90+
# reconstruction. Terraform infers each side as `map(object({uniform shape}))`
91+
# — without this, static keys force object-type inference and the ternary
92+
# fails with "inconsistent conditional result types" (the synthetic `facets`
93+
# key in modified_domains is absent from the raw spec domains, and the
94+
# wrapper may pass untyped spec where the `rules` default isn't applied).
95+
effective_domains_pre_expansion = local.acm_mode ? {
96+
for k, v in lookup(var.instance.spec, "domains", {}) :
97+
k => {
98+
domain = tostring(v.domain)
99+
alias = tostring(v.alias)
100+
certificate_reference = tostring(lookup(v, "certificate_reference", ""))
101+
equivalent_prefixes = [for p in lookup(v, "equivalent_prefixes", []) : tostring(p)]
102+
rules = { for rk, rv in lookup(v, "rules", {}) : tostring(rk) => rv }
103+
}
104+
} : {
105+
for k, v in local.modified_domains :
106+
k => {
107+
domain = tostring(v.domain)
108+
alias = tostring(v.alias)
109+
certificate_reference = tostring(lookup(v, "certificate_reference", ""))
110+
equivalent_prefixes = [for p in lookup(v, "equivalent_prefixes", []) : tostring(p)]
111+
rules = { for rk, rv in lookup(v, "rules", {}) : tostring(rk) => rv }
112+
}
113+
}
114+
effective_disable_base_domain = local.acm_mode ? lookup(var.instance.spec, "disable_base_domain", false) : (local.use_dns01 && !lookup(var.instance.spec, "disable_base_domain", false) ? true : lookup(var.instance.spec, "disable_base_domain", false))
91115

92116
# --- Final domains (no expansion — equivalent_prefixes is a rule-routing key, not domain multiplication) ---
93117
add_base_domain = local.effective_disable_base_domain ? {} : {
@@ -1092,11 +1116,10 @@ locals {
10921116
])
10931117

10941118
gateway_snippet_http_server_location = compact([
1095-
# Feature 11: proxySetHeaders (always include X-Request-ID + FACETS-REQUEST-ID + custom)
1119+
# Feature 11: proxySetHeaders (always include X-Request-ID + custom)
10961120
join("\n", concat(
10971121
[
10981122
"proxy_set_header X-Request-ID $request_id;",
1099-
"proxy_set_header FACETS-REQUEST-ID $request_id;"
11001123
],
11011124
[for header_name, header_value in lookup(var.instance.spec, "proxy_set_headers", {}) :
11021125
"proxy_set_header ${header_name} ${header_value};"

0 commit comments

Comments
 (0)