Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bnk/cneinstance/bnkforge.pack.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@
"default": "",
"source": "auto"
},
{
"name": "bnk_gateway_chassis",
"type": "object({name=optional(string),default_listener_networks=list(object({name=string,start_address=string,end_address=string}))})",
"description": "F5BnkGateway chassis CR — required on AWS/EKS for Gateway-API translation. Without it the CNE controller silently ignores all Gateway/HTTPRoute CRs even when Programmed=True. Empty default_listener_networks = skip (on-prem default).",
"default": {
"default_listener_networks": []
},
"source": "user"
},
{
"name": "tmm_init_enabled",
"type": "boolean",
Expand Down
61 changes: 61 additions & 0 deletions bnk/cneinstance/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,67 @@ MANIFEST
}
}

# =============================================================================
# F5BNKGATEWAY CHASSIS CR (AWS/EKS — required for Gateway-API translation)
# =============================================================================
# Despite F5 docs saying F5BnkGateway is optional, in f5ingress:v14.19.4-0.1.36
# it's the trigger that activates the entire Gateway translation pipeline on
# AWS/EKS. Without it the controller logs "Watched application namespaces: []"
# and silently ignores all Gateway+HTTPRoute CRs even with Programmed=True.
#
# Recipe verified on aws-syd-test 2026-04-30 — see agent memory note
# project_aws_syd_test_tmm_kernelmode_break.md for the discovery trail.
#
# Created in the same namespace as the CNEInstance (controller's namespace).
# Empty default_listener_networks list = skip (preserves on-prem behavior).

resource "null_resource" "f5_bnkgateway_chassis" {
count = length(var.bnk_gateway_chassis.default_listener_networks) > 0 ? 1 : 0

triggers = {
chassis_hash = sha256(jsonencode(var.bnk_gateway_chassis))
namespace = var.instance_namespace
name = var.bnk_gateway_chassis.name
kubeconfig = local_file.kubeconfig.filename
}

provisioner "local-exec" {
command = <<-EOT
echo "=== Creating F5BnkGateway chassis CR ==="
cat <<'MANIFEST' | ${local.kubectl} apply -f -
apiVersion: k8s.f5net.com/v1
kind: F5BnkGateway
metadata:
name: ${var.bnk_gateway_chassis.name}
namespace: ${var.instance_namespace}
spec:
ingressConfig:
defaultListenerNetworks:
%{for net in var.bnk_gateway_chassis.default_listener_networks~}
- name: "${net.name}"
startAddress: "${net.start_address}"
endAddress: "${net.end_address}"
%{endfor~}
MANIFEST
echo "F5BnkGateway chassis ${var.bnk_gateway_chassis.name} created"
EOT
}

provisioner "local-exec" {
when = destroy
command = <<-EOT
echo "=== Deleting F5BnkGateway chassis ${self.triggers.name} ==="
kubectl --kubeconfig ${self.triggers.kubeconfig} delete f5-bnkgateway ${self.triggers.name} \
-n ${self.triggers.namespace} 2>/dev/null || \
echo "F5BnkGateway already deleted or not found"
EOT
}

depends_on = [
null_resource.cneinstance,
]
}

# =============================================================================
# WRITE MANIFEST TO FILE
# =============================================================================
Expand Down
28 changes: 28 additions & 0 deletions bnk/cneinstance/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,34 @@ variable "cloud_az_subnet_mappings" {
default = []
}

variable "bnk_gateway_chassis" {
description = <<-EOT
F5BnkGateway chassis CR config. Must be set for AWS/EKS deployments —
the CNE controller's Gateway-API translation pipeline depends on it.
Without this CR, the controller logs "Watched application namespaces:
[]" and ignores all Gateway+HTTPRoute CRs even when CNEInstance shows
Programmed=True.

Use explicit start_address + end_address per listener network. The
CRD's ipv4BaseCidr alternative is rejected by the controller runtime
("IPRange error: start/end IP addresses do not match IPv4 family").

Empty default_listener_networks list = skip chassis CR creation
(preserves pre-existing on-prem behavior).
EOT
type = object({
name = optional(string, "bnk-gateway-chassis")
default_listener_networks = list(object({
name = string
start_address = string
end_address = string
}))
})
default = {
default_listener_networks = []
}
}

# =============================================================================
# DEPLOYMENT CONFIGURATION
# =============================================================================
Expand Down
Loading