The workload controller converges the resources needed to run OpenBao. First boot is deliberately different from steady state: the operator starts one pod, confirms initialization, and only then applies the requested replica count.
Reconcile in dependency order
The application layer runs the workload reconcilers in this order:
- Reconcile certificate material or verify its readiness.
- Reconcile infrastructure. This step validates the version and image, computes safe StatefulSet intent, renders bootstrap configuration, and then reconciles networking, identity, and voter and read-replica workloads.
- Reconcile storage expansion and any restart needed to observe it.
- Reconcile initialization while the cluster is uninitialized.
- Reconcile Day 2 Autopilot settings after initialization, when no upgrade blocks the change.
The infrastructure step is an application-level sequence, not six independent top-level reconcilers. That ordering keeps configuration and resource identity aligned before the workload is applied.
Keep service write surfaces narrow
| Service | Primary responsibility |
|---|---|
| Certificates | Create or observe TLS material and signal in-pod reload when active leaf content changes |
| Bootstrap and configuration | Render config.hcl, self-init requests, seal prerequisites, ACME cache storage, and managed audit-file storage |
| Networking | Reconcile Services, Ingress or Gateway resources, backend trust, and NetworkPolicies |
| Identity | Reconcile the workload ServiceAccount and namespaced RBAC |
| Workload | Reconcile voter and read-replica StatefulSets, PodDisruptionBudgets, revision resources, and rollout triggers |
| Storage | Reconcile volume expansion and controlled restart progress |
| Initialization | Detect or perform initialization, persist the appropriate status, and make the first Autopilot attempt |
The services share three contracts:
internal/service/configurationkeepsconfig.hclsemantics consistent between normal bootstrap and blue-green startup;internal/platform/resourceidentitykeeps names, labels, and selectors consistent;internal/platform/resourceapplyprovides owner-aware server-side apply behavior while service-specific exceptions stay with the owning service.
Apply the TLS ownership model
| Mode | Certificate owner | Certificate service behavior |
|---|---|---|
OperatorManaged | Operator | Create and rotate the CA and server Secrets; signal reload after leaf content changes |
External | User or external controller | Wait for the required Secrets, validate them, and signal reload after their content changes |
ACME | OpenBao | Do not create or watch certificate Secrets; OpenBao and the rendered listener configuration own issuance and cache lifecycle |
Certificate changes do not require a StatefulSet rollout. The certificate service computes the active certificate hash and signals the ready workload to reload only when the hash changes.
Initialize one pod, then scale
The workload specification is capped at one voter until status.initialized is true. This prevents multiple fresh pods
from racing to form the first Raft cluster.
Self-initialization
OpenBao performs its own initialization. The initialization service observes readiness, health, and registration state,
then sets status.initialized and status.selfInitialized. It does not create a root-token Secret. After success, it
makes the self-init request ConfigMap inert so a later restart cannot replay the bootstrap request.
Operator initialization
The initialization service waits for the first pod and required TLS material, checks whether the cluster is already initialized, and calls the init API only when needed. It stores the returned root token in the cluster root-token Secret without logging the init response, then marks the cluster initialized.
Detecting an already initialized cluster is a recovery path for an operator-managed cluster. It does not turn the CRD into an import API for unmanaged clusters.
Autopilot and scale-out
Initialization makes an initial attempt to configure Raft Autopilot. A separate Day 2 reconciler retries and applies later Autopilot changes after initialization. It yields while an upgrade owns the relevant lifecycle state.
Once initialization status is durable, the infrastructure path removes the one-pod cap. Additional voter and read replica pods join through the rendered Raft configuration. Safe scale-down and restart ordering are computed before the StatefulSets are applied.
Preserve the handoff
| Boundary | Required outcome |
|---|---|
| Before the first pod | TLS or ACME prerequisites, configuration, networking, identity, and storage are ready enough for startup |
| Before initialization | Pod 0 is reachable through the configured trust path |
| Before scale-out | Initialization is confirmed in status; self-init bootstrap requests cannot replay |
| During steady state | Generated resources remain operator-owned and changes route through the custom resource |
| During an upgrade | Workload repair continues, but Autopilot and rollout changes respect upgrade ordering |
For user-facing configuration choices, see Configure a cluster.