kadet-hub logokadet-hub

cert-manager on Kubernetes without Helm, with Kapitan

The cert-manager controller, cainjector and webhook with their RBAC, and optionally the CRDs, rendered by the kadet-hub kubernetes generator 1.9.0.

What it deploys

Required parameters

No parameter has to be set.

Include

A target includes the recipe and its options as classes and can override anything the recipe sets:

classes:
  - recipes.cert-manager
  - recipes.cert-manager.crds   # the chart's crds.enabled
parameters:
  namespace: cert-manager
  kapitan:
    vars:
      target: cert-manager

Fetching it

A separate fetch inventory pins the recipe by version and digest. This is fetch/targets/recipes.yml for version 1.0.2:

parameters:
  kapitan:
    dependencies:
      - type: oci
        source: ghcr.io/kadet-hub/recipes/cert-manager:1.0.2@sha256:2ffb63ac054a0cfe5d3cb06892430908502908f194e5227c12df480803ec465a
        output_path: inventory/classes/recipes/cert-manager

The first command fetches the recipe into inventory/classes/recipes/cert-manager, the second the generators and compiles:

kapitan compile --inventory-path fetch --fetch --output-path .
kapitan compile --fetch

The first command exits with status 1 because the fetch target compiles nothing. Kapitan's --fetch checks neither the digest nor the attestation. This verifies the attestation of each recipe the fetch inventory pins:

gh attestation verify \
  oci://ghcr.io/kadet-hub/recipes/cert-manager@sha256:2ffb63ac054a0cfe5d3cb06892430908502908f194e5227c12df480803ec465a \
  --owner kadet-hub \
  --cert-identity https://github.com/kadet-hub/registry/.github/workflows/release.yml@refs/heads/main

The attested index must also list each digest under its recipe with the pinned version, and not as yanked. Verifying by hand shows how to read it.

The output rules found admission-webhook in the compiled output of the recipe's test target. The consumer workflow fails unless the policy .kapitan-sandbox.yaml accepts these capabilities for the target's output path:

output_capabilities:
  "compiled/<target>/*": [admission-webhook]

Settings

Chart value Inventory
namespace (release namespace) namespace
image.tag of all images the image lines and components.cert-manager.args.acme-http01-solver-image, tag and digest each
global.logLevel applications.cert-manager.log_level
global.leaderElection.namespace applications.cert-manager.leader_election_namespace
replicaCount, webhook.replicaCount, cainjector.replicaCount components.cert-manager.replicas, components.cert-manager-webhook.replicas, components.cert-manager-cainjector.replicas
resources components.<component>.resources
nodeSelector applications.cert-manager.component_defaults.node_selector
tolerations, affinity components.<component>.tolerations, components.<component>.affinity
podAnnotations applications.cert-manager.component_defaults.pod_annotations
extraArgs components.<component>.args.<key>, a new key for an extra argument or a recipe key such as verbosity to replace one
webhook.timeoutSeconds timeoutSeconds in components.cert-manager-webhook.webhooks and validating_webhooks

args is a mapping and renders in the recipe’s key order, with new keys after them. A string value is one argument, a list several, and ~ drops the entry, for example components.cert-manager.args.verbosity: --v=4.

Any other list set in the target is appended to the recipe’s list. To replace one, set the key to ~ in a class included after the recipe and the new list in the target.

Left out

The chart’s startupapicheck hook runs only inside helm install, where it waits until the webhook answers. tests/smoke checks the same on the installed recipe. These hook objects are not rendered: Job/cert-manager-startupapicheck, ServiceAccount/cert-manager-startupapicheck, Role/cert-manager-startupapicheck:create-cert and RoleBinding/cert-manager-startupapicheck:create-cert.

Renamed RBAC objects

The generator rejects : in names. Each role keeps its own entry and its binding.

Chart Recipe
cert-manager:leaderelection cert-manager-leaderelection
cert-manager-cainjector:leaderelection cert-manager-cainjector-leaderelection
cert-manager-controller-approve:cert-manager-io cert-manager-controller-approve-cert-manager-io
cert-manager-webhook:subjectaccessreviews cert-manager-webhook-subjectaccessreviews
cert-manager-webhook:dynamic-serving cert-manager-webhook-dynamic-serving

Proof

check cert-manager --level deploys with tests/values.yaml (crds.enabled: true) and tests/target.yml, on kind kindest/node:v1.37.0. The objects outside RBAC differ only in these classes:

All ServiceAccounts and users bound to view, edit and admin have the same permissions. aggregate-to-cluster-reader targets an OpenShift role and is not tested. tests/smoke has a self-signed ClusterIssuer issue a Certificate.

Versions

The recipe's files are in kadet-hub/recipes. All recipes