Using kubernetes certmanager.k8s.io with k8s.keycloak.org
TypeScriptTo integrate Kubernetes
cert-manager
withkeycloak
on Kubernetes, we will be using the Pulumi Kubernetes provider to deploy both components to a Kubernetes cluster. Thecert-manager
is a native Kubernetes certificate management controller which can help with issuing certificates from a variety of sources like Let's Encrypt, HashiCorp Vault, Venafi, self-signed, or from any private CA (Certificate Authority).After installing
cert-manager
, it will ensure certificates are valid and up to date and will attempt to renew certificates at a configured time before expiry. We can integrate it withkeycloak
by configuringkeycloak
to use a certificate issued bycert-manager
for secure communication.We will use the following resources in this setup:
CertManager
Custom Resource: This is the main controller forcert-manager
that will manage certificate provisioning, signing, and renewing.Secret
: It holds the TLS secrets containing the certificate and key which thecert-manager
will generate for us to use withkeycloak
.Deployment
: A standard KubernetesDeployment
to manage ourkeycloak
instances.Service
: A KubernetesService
to exposekeycloak
Pods to the network.Ingress
or similar resources: To exposekeycloak
outside of the cluster securely using the certificate maintained bycert-manager
.
Below is an explanatory Pulumi program in TypeScript for deploying
cert-manager
and configuring it to work withkeycloak
. This example assumes you have a Kubernetes cluster created and accessible viakubectl
and thatcert-manager
andkeycloak
Charts are available in your Helm chart repositories.import * as kubernetes from "@pulumi/kubernetes"; import * as pulumi from "@pulumi/pulumi"; const namespace = new kubernetes.core.v1.Namespace("cert-manager-namespace", { metadata: { name: "cert-manager" } }); // Deploy cert-manager to the cluster. // We leverage the Pulumi Kubernetes provider to deploy the cert-manager Helm Chart; more documentation // can be found here: https://www.pulumi.com/registry/packages/kubernetes-cert-manager/api-docs/certmanager/ const certManagerChart = new kubernetes.helm.v3.Chart("cert-manager", { namespace: namespace.metadata.name, chart: "cert-manager", version: "v1.6.1", // use the appropriate chart version fetchOpts: { repo: "https://charts.jetstack.io", // official cert-manager Helm chart repository }, values: { installCRDs: true, // Custom Resource Definitions will be installed by this Helm chart }, }); // Ensure to wait for cert-manager to be ready before moving on to deploy other resources. const certManagerDeployment = certManagerChart.getResource("apps/v1/Deployment", "cert-manager/cert-manager"); // Note: Creating an Issuer/ClusterIssuer and Certificate resources would follow here, but for brevity, // that code has been omitted. You would normally include details for your preferred CA or ACME server. // Example of creating a keycloak deployment. // You can find more details at https://www.keycloak.org/getting-started/getting-started-kube const keycloakDeployment = new kubernetes.apps.v1.Deployment("keycloak-deployment", { metadata: { namespace: certManagerDeployment.metadata.namespace, }, spec: { selector: { matchLabels: { app: "keycloak", }, }, replicas: 2, template: { metadata: { labels: { app: "keycloak", }, }, spec: { containers: [ { name: "keycloak", image: "quay.io/keycloak/keycloak:latest", env: [ // Environment variables for keycloak setup go here. ], ports: [{ containerPort: 8080 }], }, ], }, }, }, }); // Expose the keycloak deployment as a service within the cluster. const keycloakService = new kubernetes.core.v1.Service("keycloak-service", { metadata: { namespace: keycloakDeployment.metadata.namespace, }, spec: { selector: keycloakDeployment.spec.selector.matchLabels, ports: [{ port: 8080 }], type: "ClusterIP", }, }); // Assuming that a certificate has been created for keycloak and a Secret has been created containing the // TLS certificate and key. Here, using an `Ingress` to expose Keycloak securely using that Secret is demonstrated. // Note that the exact `Ingress` resource configuration will depend on your specific cluster setup, Ingress controller, // cert-manager setup, and DNS setup. const keycloakIngress = new kubernetes.networking.v1.Ingress("keycloak-ingress", { metadata: { namespace: keycloakService.metadata.namespace, // Annotation to ensure the cert-manager knows how to issue certificates for this Ingress. annotations: { "cert-manager.io/cluster-issuer": "letsencrypt-prod", // Name of your cluster issuer }, }, spec: { tls: [ // Include TLS configuration here. { hosts: ["keycloak.example.com"], // Substitute with your actual domain secretName: "keycloak-tls-secret", // Corresponding secret containing the TLS certificate }, ], rules: [ { host: "keycloak.example.com", // Substitute with your actual domain http: { paths: [ { path: "/", pathType: "Prefix", backend: { service: { name: keycloakService.metadata.name, port: { number: 8080 }, }, }, }, ], }, }, ], }, }); // Exports - useful if you need to access these resources externally, e.g. CI/CD pipelines or other services. export const keycloakExternalHostname = keycloakIngress.status.loadBalancer.ingress[0].hostname;
In this Pulumi program, we've set up
cert-manager
in its own namespace with theinstallCRDs
option set totrue
, which is crucial to ensure thatcert-manager
can create the necessary Custom Resource Definitions (CRDs) on the cluster. Then we are doing a typical Kubernetes deployment ofkeycloak
and exposing it using aService
. Lastly, we're creating anIngress
resource that uses TLS certificates provided bycert-manager
.Please make sure you replace placeholder values like
keycloak.example.com
andletsencrypt-prod
with actual values that apply to your case. After setting up the issuer and certificate resources forcert-manager
, it will manage the lifecycle of the certificates used bykeycloak
, and theIngress
resource will ensure they're used for secure communication.Remember to consult the official documentation of
cert-manager
andkeycloak
for the most up-to-date configurations and best practices.