openova/clusters/_template/bootstrap-kit/15-external-secrets.yaml
Hatice Yildiz dc4155c675 fix(bp-external-secrets): split ClusterSecretStore into bp-external-secrets-stores chart (resolves CRD ordering, closes #331)
bp-external-secrets@1.0.0 deadlocked on first install on otech.omani.works:

  Helm install failed for release external-secrets-system/external-secrets
  with chart bp-external-secrets@1.0.0:
  failed post-install: unable to build kubernetes object for deleting hook
  bp-external-secrets/templates/clustersecretstore-vault-region1.yaml:
  resource mapping not found for name: "vault-region1" namespace: ""
  no matches for kind "ClusterSecretStore" in version "external-secrets.io/v1beta1"

Root cause: Helm's `helm.sh/hook-delete-policy: before-hook-creation` ran
a kubectl-style lookup of the existing ClusterSecretStore CR before the
upstream `external-secrets` subchart's CRDs finished registration. The
in-line ClusterSecretStore template (templates/clustersecretstore-vault-
region1.yaml) and the upstream subchart's CRDs co-installed in the same
release; admission ordering wasn't deterministic enough to make the
post-install hook safe.

Fix — same pattern as PR #247 (bp-crossplane@1.1.3 ↔ bp-crossplane-claims@1.0.0):
split the chart into controller + stores. Flux dependsOn orders them.

  - bp-external-secrets@1.1.0 — controller-only (just upstream subchart
    + NetworkPolicy + ServiceMonitor toggle). CRDs register here.
  - bp-external-secrets-stores@1.0.0 (NEW) — the default
    ClusterSecretStore CR; depends on bp-external-secrets being Ready.
    No Helm hooks needed: by the time this chart's HelmRelease starts,
    Flux has already verified bp-external-secrets is Ready=True and
    therefore the CRDs are registered.

Files:
  NEW: platform/external-secrets-stores/blueprint.yaml             (1.0.0)
  NEW: platform/external-secrets-stores/chart/Chart.yaml           (1.0.0; no upstream subchart, annotation `catalyst.openova.io/no-upstream: "true"`)
  NEW: platform/external-secrets-stores/chart/values.yaml          (clusterSecretStore.* knobs moved from controller chart)
  MOVED: platform/external-secrets/chart/templates/clustersecretstore-vault-region1.yaml
       → platform/external-secrets-stores/chart/templates/clustersecretstore-vault-region1.yaml
       (Helm hook annotations removed — Flux dependsOn now handles ordering)
  TOUCHED: platform/external-secrets/chart/Chart.yaml              (1.0.0 → 1.1.0; description note appended)
  TOUCHED: platform/external-secrets/blueprint.yaml                (1.0.0 → 1.1.0)
  TOUCHED: platform/external-secrets/chart/values.yaml             (clusterSecretStore block removed; pointer comment added)
  NEW: clusters/_template/bootstrap-kit/15a-external-secrets-stores.yaml
       (Flux HelmRelease, dependsOn: [bp-external-secrets, bp-openbao])
  TOUCHED: clusters/_template/bootstrap-kit/15-external-secrets.yaml
       (chart version 1.0.0 → 1.1.0)
  TOUCHED: clusters/_template/bootstrap-kit/kustomization.yaml
       (slot 15a inserted after 15)

Out of scope for this PR (separate tickets):
  - blueprint-release.yaml CI fan-out: verify the path-matrix picks up
    the new platform/external-secrets-stores/ directory automatically;
    if not, add the directory to the matrix in a follow-up.
  - Per-Sovereign cluster directory edits (#257 will delete those).
  - Phase 0 minimum trim (#310 will renumber slots; this PR uses 15a as
    a non-disruptive sub-slot insertion that works with both the current
    35-slot kustomization and the eventual 15-slot canonical layout —
    when #310 renumbers, 15 + 15a become 08 + 09 in the canonical order).

Refs: #331 (this issue), #247 (pattern reference — bp-crossplane split),
#310 (Phase 0 trim — companion).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 21:24:15 +02:00

76 lines
2.5 KiB
YAML

# bp-external-secrets — Catalyst bootstrap-kit Blueprint, W2.K1 slot 15.
# External Secrets Operator (ESO). Day-2 secret pipeline from OpenBao →
# Kubernetes Secret materialization. Takes over from bp-sealed-secrets
# (slot 05, transient) once OpenBao is Ready and ESO is reconciling.
#
# Per docs/BOOTSTRAP-KIT-EXPANSION-PLAN.md §1.2 (Tier 0/3 — host-layer
# secret distribution) and §2.3 (W2.K1 dependency graph): ESO is sequenced
# at slot 15 (first slot in the W2.K1 contiguous range) but its
# dependsOn is [bp-openbao(08), bp-cert-manager(02)] — Flux gates install
# on Ready=True for both, regardless of slot order. ESO's webhook
# requests a TLS cert from the cluster's letsencrypt-prod / cluster-ca
# ClusterIssuer; without bp-cert-manager Ready, the Certificate stays
# Pending and the operator never reaches Running.
#
# Wrapper chart: platform/external-secrets/chart/
# Catalyst-curated values: platform/external-secrets/chart/values.yaml
# Reconciled by: Flux on the new Sovereign's k3s control plane.
---
apiVersion: v1
kind: Namespace
metadata:
name: external-secrets-system
labels:
catalyst.openova.io/sovereign: SOVEREIGN_FQDN_PLACEHOLDER
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: bp-external-secrets
namespace: flux-system
spec:
type: oci
interval: 15m
url: oci://ghcr.io/openova-io
secretRef:
name: ghcr-pull
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: bp-external-secrets
namespace: flux-system
spec:
interval: 15m
releaseName: external-secrets
targetNamespace: external-secrets-system
# ESO depends on:
# - bp-openbao(08): the secret backend ESO pulls from. ClusterSecretStore
# resources reference the in-cluster OpenBao service; without OpenBao
# Ready those CRs land but every ExternalSecret reconcile fails.
# - bp-cert-manager(02): ESO's admission webhook needs a TLS cert.
# bp-cert-manager provides the ClusterIssuer that signs it.
dependsOn:
- name: bp-openbao
- name: bp-cert-manager
chart:
spec:
chart: bp-external-secrets
version: 1.1.0
sourceRef:
kind: HelmRepository
name: bp-external-secrets
namespace: flux-system
# Event-driven install per docs/INVIOLABLE-PRINCIPLES.md #3 (Flux
# dependsOn is the gate, not Helm timeout). Replaces blanket
# spec.timeout: 15m band-aid pattern from PR #221, removed in PR #250.
install:
disableWait: true
remediation:
retries: 3
upgrade:
disableWait: true
remediation:
retries: 3