Fuzzball Documentation
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Deploying with External cert-manager

By default, the Fuzzball operator installs and manages its own cert-manager instance. If your cluster already has cert-manager (and optionally trust-manager) installed, you can configure Fuzzball to use those existing installations instead.

Prerequisites

Before deploying the FuzzballOrchestrate CR, ensure the cluster has:

  1. cert-manager installed and running
  2. At least one ClusterIssuer for internal service-to-service TLS
  3. At least one ClusterIssuer for external-facing ingress TLS (can be the same issuer)
  4. trust-manager installed and running, or omit it to have the operator deploy it

You can list available ClusterIssuers with:

$ kubectl get clusterissuer

Configuration

The key difference from a standard deployment is in the tls section of your fuzzball.yaml. Omit certManager.create and reference your existing ClusterIssuers using issuerName.

Standard deployment (operator-managed cert-manager)

This is the default configuration, shown here for comparison:

tls:
  certManager:
    create: {}
  trustManager:
    create: {}
  ingressIssuer:
    create:
      letsEncrypt:
        email: admin@example.com
        issuer: letsencrypt-prod

Deployment with external cert-manager

tls:
  # Omit certManager entirely -- the operator uses the cluster's existing installation.
  # If trust-manager is also pre-installed, omit trustManager too.
  # If trust-manager is NOT installed, keep this to have the operator deploy it:
  trustManager:
    create: {}
  internalIssuer:
    external:
      issuerName: fuzzball-ca-issuer    # ClusterIssuer for internal service TLS
  ingressIssuer:
    external:
      issuerName: letsencrypt-prod      # ClusterIssuer for external ingress TLS
The internal issuer handles service-to-service communication (gRPC between Fuzzball components, JetStream TLS, etc.) and must be a CA issuer. The ingress issuer handles external-facing endpoints (API, UI, OpenAPI) and can be Let’s Encrypt or another public CA.

What the Operator Does with External Issuers

When external issuers are configured, the operator:

  1. Skips cert-manager deployment and uses the cluster’s existing installation
  2. Deploys trust-manager if trustManager.create is set, otherwise assumes it is running
  3. Fetches each ClusterIssuer to extract its CA certificate
  4. Adds the CA to the trust bundle so all Fuzzball services trust issued certificates
  5. Annotates ingress and service resources with cert-manager.io/cluster-issuer so cert-manager issues certificates automatically
CA bundle extraction and distribution happen automatically. You do not need to manually create a trusted-ca-certs-bundle ConfigMap.

Example: Self-Signed CA Issuer

For development or air-gapped environments without Let’s Encrypt access, you can create a self-signed CA issuer:

# Bootstrap a self-signed issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-issuer
spec:
  selfSigned: {}
---
# Create a root CA certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: root-ca-cert
  namespace: cert-manager
spec:
  isCA: true
  commonName: "Fuzzball Root CA"
  secretName: root-ca-cert
  duration: 87600h
  issuerRef:
    name: selfsigned-issuer
    kind: ClusterIssuer
  privateKey:
    algorithm: ECDSA
    size: 256
---
# CA issuer that Fuzzball will reference
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: fuzzball-ca-issuer
spec:
  ca:
    secretName: root-ca-cert

Then reference it in both issuer fields:

tls:
  internalIssuer:
    external:
      issuerName: fuzzball-ca-issuer
  ingressIssuer:
    external:
      issuerName: fuzzball-ca-issuer

Migrating from internalCAIssuerName

If you have an existing deployment using the deprecated internalCAIssuerName field, update your configuration to use issuerName instead. Both fields work, but issuerName is preferred:

# Deprecated -- still works but should be updated
internalIssuer:
  external:
    internalCAIssuerName: my-issuer

# Preferred
internalIssuer:
  external:
    issuerName: my-issuer

For more details on TLS configuration parameters, see the CRD reference.