Skip to content

Configure cert-manager issuers

This content is for the v0.1 version. Switch to the latest version for up-to-date documentation.

Kix separates the cert-manager controller from issuer configuration. Install cert-manager, then add one cluster-issuers instance to create the ClusterIssuer resources used throughout the cluster.

For public certificates, configure the ACME server, account email, the name of the account-key Secret that cert-manager will create, and Cloudflare DNS-01 credentials:

clusters/test-doc-how-tos.nix (L108–L130)
instances.cert-manager.cert-manager = {
package = packages.cert-manager;
};
instances.cert-manager.cluster-issuers = {
package = packages."cluster-issuers";
config = {
mainIssuer = "letsencrypt-production";
issuers = lib.mkForce {
letsencrypt-production = {
kind = "acme";
server = "https://acme-v02.api.letsencrypt.org/directory";
email = "[email protected]";
privateKeySecretName = "letsencrypt-production-account";
cloudflareSecret = {
name = "cloudflare-api-token";
key = "api-token";
};
dnsZones = [ "example.com" ];
};
};
};
};

View source on GitHub ↗

The example replaces the package defaults with one issuer. Keep lib.mkForce: issuers is an attrset option, so an ordinary assignment would merge with the default production and staging entries.

Before deployment, create the cloudflare-api-token Secret in the cert-manager namespace with an api-token key. The cert-manager controller uses its own namespace for Secrets referenced by a ClusterIssuer. The cluster-issuers package currently passes this Secret name to cert-manager; it does not create or verify the Secret.

Use a Kix-managed Secret, a SOPS-backed Secret, or an externally managed Secret. Restrict dnsZones to the zones this token may update.

mainIssuer must name one entry in issuers. Kix exports that issuer as the clusterIssuer dependency used by TLS-capable packages.

For a local cluster, replace the issuer set with a self-signed issuer:

ludo/variants/cluster-kind-tls.nix (L74–L87)
instances.cert-manager.cluster-issuers = {
package = packages."cluster-issuers";
config = {
mainIssuer = "selfsigned";
# mkForce replaces the ACME defaults (letsencrypt-production /
# letsencrypt-staging) which would otherwise merge in and fail
# to reconcile without a cloudflare token secret.
issuers = lib.mkForce {
selfsigned = {
kind = "selfSigned";
};
};
};
};

View source on GitHub ↗

A self-signed issuer tests certificate creation and TLS wiring without an ACME account or DNS provider. Clients will not trust its certificates unless you install the generated trust material, so do not use this configuration for a public service.

Evaluate the cluster before applying it:

❱ kix check doc-how-tos

Deploy cert-manager, its CRDs, and the ClusterIssuer:

❱ kix deploy doc-how-tos

After deployment, inspect issuer readiness:

❱ kubectl get clusterissuers
❱ kubectl describe clusterissuer letsencrypt-production

Do not proceed to application TLS until the selected issuer reports Ready. For ACME failures, check the credential key, zone restriction, DNS delegation, and cert-manager controller logs.

See Add TLS through cluster issuers to use the selected issuer from an application package.