Skip to content
Merged
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
88 changes: 88 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# BNK-Forge Module Repo — Migration to Per-Cloud Architecture

This document captures the architectural direction for the BNK-Forge module ecosystem and the role this repository will play once the migration is complete.

## Target architecture

The BNK-Forge module ecosystem is moving to a **per-target-platform repo** pattern, modelled on [`jgruberf5/bnk-forge-ibm-roks-cluster`](https://github.com/jgruberf5/bnk-forge-ibm-roks-cluster). Each target platform gets its own repo with:

- **`modules/`** — single-purpose Terraform modules, one per deployment step (cluster create, install cert-manager, install FLO, deploy CNEInstance, apply license, etc.). Cloud-specific concerns (IAM, registry auth, networking) live here.
- **`blueprints/`** — hand-authored `forge-blueprint.json` manifests that chain those modules together end-to-end.
- The repo registers in Forge as both a Module Source and a Blueprint Source.

```
bnk-forge-modules <-- THIS REPO: shared cloud-agnostic k8s layer
├── k8s/bnk-prerequisites/ (namespaces + FAR secrets + manifest)
├── k8s/cert-manager/ (Jetstack Helm install)
└── k8s/bnk-cert-issuer/ (BNK Issuer/ClusterIssuer CRs)

bnk-forge-ibm-roks-cluster <-- EXISTS (jgruberf5)
bnk-forge-aws-eks-cluster <-- PLANNED
bnk-forge-azure-aks-cluster <-- PLANNED
bnk-forge-gcp-gke-cluster <-- PLANNED
bnk-forge-onprem-k8s <-- PLANNED (any on-prem Kubernetes)
```

## What this repository becomes

After the migration, `bnk-forge-modules` is **the shared cloud-agnostic Kubernetes layer**. It hosts only modules that:

- Touch the Kubernetes API exclusively (no cloud-provider APIs).
- Use no cloud-specific authentication (no IAM trusted profiles, no IRSA, no GCP service account keys).
- Have the same behavior on EKS, AKS, GKE, ROKS, vanilla on-prem, and kind.

Every per-cloud and on-prem repo will reference modules from here for their shared prerequisites, rather than vendoring copies.

### What stays here

| Module | Purpose |
|---|---|
| `k8s/bnk-prerequisites` | Namespaces, FAR pull secrets, BNK manifest download + version discovery. Foundation module — every downstream module depends on it. |
| `k8s/cert-manager` | Deploys Jetstack cert-manager with BNK-compatible defaults. |
| `k8s/bnk-cert-issuer` | Creates BNK-managed self-signed CA + ClusterIssuer CRs for FLO certificate flows. |

### What moves out

| Module | Where it goes | Why |
|---|---|---|
| `bnk/flo` | Vendored per-cloud (each per-cloud repo gets its own copy) | Install model differs by cloud: IBM IAM trusted profile, AWS IRSA, Azure workload identity. BIG-IP CIS controller wiring is cloud-specific. |
| `bnk/cneinstance` | Vendored per-cloud | Chassis configuration tracks the underlying NIC stack (AWS ENA vs IBM SR-IOV vs Azure Accelerated Networking). PR #58 added AWS-specific `F5BnkGateway` chassis logic — exactly the kind of cloud-specific divergence that vendoring contains. |
| `k8s/network-setup` | Vendored per-cloud | Multus + NAD configuration depends on cloud-specific NIC drivers and SR-IOV/DPDK knobs. |

### What retires

| Module | Replacement | When |
|---|---|---|
| `k8s/bnk-namespaces` | `k8s/bnk-prerequisites` (superset) | Phase 4 — only `bnk/far-setup` still references it, and that retires too. |
| `bnk/far-setup` | `k8s/bnk-prerequisites` (already absorbs FAR secret setup) | Phase 4 — catalog `reason` field already names bnk-prerequisites as the replacement. |
| `bnk/bnk-gateway-ext` | None | Phase 4 — no consumers anywhere in the repo or templates. |
| `bnk/bnk-vlans`, `bnk/gateway`, `bnk/routes`, `bnk/bnk-netpolicy`, `bnk/bnk-secpolicy`, `bnk/bnk-gatewayclass` | TBD per-module | Phase 4 decision: some may move to per-cloud repos, some may stay shared, some may retire. Driven by whether the underlying CR apply is cloud-specific. |

## Phased plan

| Phase | Scope | Status |
|---|---|---|
| 0 | Land in-flight PRs (manifest `version` fix, AWS/EKS chassis, namespace alignment) | Done |
| 1 + 2 | Create missing `bnkforge.pack.json` for `k8s/bnk-prerequisites`; add `k8s/bnk-cert-issuer` to the catalog; document the migration direction (this file) | In progress |
| 3 | Create per-cloud repos: `bnk-forge-aws-eks-cluster`, then Azure, GCP, on-prem. Vendor FLO + CNEInstance + network-setup into each. Hand-author per-cloud blueprints. | Not started |
| 4 | Retire deprecated/legacy modules from this repo once per-cloud repos cover the moved-out modules. Per-module decision for ambiguous legacies. | Not started |
| 5 | Drop the `catalog/release-*.json` auto-generated transition blueprint path entirely; this repo serves only its shared modules. | Not started |

## Versioning contract

This repo (and every per-cloud repo) follows the **BNK release cadence**. Current BNK GA is **2.3**. Branches and tags should track BNK release boundaries:

- `release/2.2` — current branch
- `release/2.3` — when BNK 2.3 content lands
- `release/2.4`, `release/3.x` — as BNK ships them

The pack JSON schema (`bnkforge.pack.json`) and blueprint manifest schema (`forge-blueprint.json`) are the **stable API** between module repos and Forge. BNK version bumps ship as content changes here, never as Forge code changes. Forge must never branch on a BNK version string.

## Reference

- IBM repo (gold-standard pattern): https://github.com/jgruberf5/bnk-forge-ibm-roks-cluster
- Forge app: `bnk-forge-v2`

---

*Last updated: 2026-05-13*
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2-rev.28
2.2-rev.31
9 changes: 9 additions & 0 deletions catalog/releases/release-2.2-official.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
"deploy_models": ["terraform", "helm", "kubernetes_manifest"]
}
},
{
"path": "k8s/bnk-cert-issuer",
"version": "1.0.0",
"state": "active",
"execution": {
"engine": "kubernetes",
"deploy_models": ["kubernetes_manifest"]
}
},
{
"path": "k8s/network-setup",
"version": "2.0.0",
Expand Down
172 changes: 172 additions & 0 deletions k8s/bnk-cert-issuer/module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
{
"module": {
"name": "BNK Cert Issuer",
"path": "k8s/bnk-cert-issuer",
"version": "1.0.0",
"layer": "kubernetes",
"category": "security",
"description": "Creates Forge-managed self-signed CA and ClusterIssuer resources for BNK cert-manager flows. Pure-manifest module rendered by the backend Python engine — no Terraform code.",
"cloud_specific": false,
"supported_platforms": ["any"]
},
"source": {
"kind": "official",
"channel": "release/2.2"
},
"execution": {
"engine": "kubernetes",
"deploy_models": ["kubernetes_manifest"]
},
"contract": {
"metadata_version": "module-metadata/v2alpha1"
},
"dependencies": {
"required": [
{
"module": "k8s/cert-manager",
"reason": "Cert-manager CRDs must exist before ClusterIssuer/Certificate resources can be created"
},
{
"module": "k8s/bnk-prerequisites",
"reason": "BNK namespaces must exist"
}
],
"optional": []
},
"inputs": {
"required": [],
"optional": [
{
"name": "namespace",
"type": "string",
"description": "Namespace where cert-manager resources are managed",
"default": "cert-manager",
"source": "user"
},
{
"name": "self_signed_cluster_issuer_name",
"type": "string",
"description": "Name of the bootstrap self-signed ClusterIssuer",
"default": "bnk-selfsigned-cluster-issuer",
"source": "user"
},
{
"name": "ca_certificate_name",
"type": "string",
"description": "Name of the CA Certificate resource",
"default": "bnk-ca",
"source": "user"
},
{
"name": "ca_secret_name",
"type": "string",
"description": "Secret name that stores the generated CA keypair",
"default": "bnk-ca-secret",
"source": "user"
},
{
"name": "cluster_issuer_name",
"type": "string",
"description": "Name of the CA-backed ClusterIssuer for BNK components",
"default": "bnk-ca-cluster-issuer",
"source": "user"
},
{
"name": "instance_namespace",
"type": "string",
"description": "Namespace where CNEInstance and OTEL certificates are created",
"default": "f5-operator",
"source": "module",
"from_module": "k8s/bnk-prerequisites",
"from_output": "operator_namespace"
},
{
"name": "otel_server_certificate_name",
"type": "string",
"description": "Name of OTEL server certificate resource",
"default": "external-otelsvr",
"source": "user"
},
{
"name": "otel_server_secret_name",
"type": "string",
"description": "Secret name generated by OTEL server certificate",
"default": "external-otelsvr-secret",
"source": "user"
},
{
"name": "otel_f5ing_server_certificate_name",
"type": "string",
"description": "Name of F5 ingestion OTEL certificate resource",
"default": "external-f5ingotelsvr",
"source": "user"
},
{
"name": "otel_f5ing_server_secret_name",
"type": "string",
"description": "Secret name generated by F5 ingestion OTEL certificate",
"default": "external-f5ingotelsvr-secret",
"source": "user"
},
{
"name": "ca_duration",
"type": "string",
"description": "Requested CA certificate duration",
"default": "87600h",
"source": "user"
},
{
"name": "ca_renew_before",
"type": "string",
"description": "Renewal window before CA certificate expiry",
"default": "720h",
"source": "user"
},
{
"name": "otel_duration",
"type": "string",
"description": "Requested OTEL certificate duration",
"default": "8640h",
"source": "user"
},
{
"name": "otel_renew_before",
"type": "string",
"description": "Renewal window before OTEL certificate expiry",
"default": "720h",
"source": "user"
}
]
},
"outputs": {
"key_outputs": [
{
"name": "cluster_issuer_name",
"type": "string",
"description": "CA-backed ClusterIssuer name for BNK components",
"used_by": ["bnk/cneinstance"],
"sensitive": false
},
{
"name": "ca_secret_name",
"type": "string",
"description": "Secret name with CA keypair",
"used_by": [],
"sensitive": false
},
{
"name": "cert_issuer_ready",
"type": "boolean",
"description": "Whether the issuer chain is ready",
"used_by": [],
"sensitive": false
}
]
},
"deployment": {
"order": 38,
"estimated_time": "30 seconds",
"requires_user_input": false,
"sensitive_inputs": []
}
}
Loading
Loading