The Keycloak team that they were going to move to a new Operator framework that will effectively manage Keycloak installations on a cluster. announced Kubernetes So what is an Operator in the Kubernetes context? Let’s simplify it a bit here... It’s basically a component that takes over the operational aspects of your application. So rather than managing all of the lifecycle and state in scripts and in our minds, they are coded into an operator. For us, the Keycloak Operator does exactly that and in this blog, I will cover how to set up a very simple Keycloak installation and get ready for development. If you are interested in knowing more about Operators you will likely find some good info . here If you aren’t familiar with Keycloak; it’s an identity and access management software. Its current version, 22, is used a lot in the wild already. It provides single sign-on capability with OAuth/OIDC, AD, LDAP, and SAML v2 as well. open source If you aren't very familiar with Keycloak, I have also written a small self-paced that goes through all the basics, as well as some advanced configs. Keycloak tutorial Let's get to installing a basic keycloak instance backed by a database. PostgreSQL Here’s the plan of action: Install Operator on cluster (a distribution of Kubernetes by Red Hat) OpenShift Install database for the Keycloak backend. Create an SSL certificate for use with the keycloak backend. Install the first Keycloak instance. Import a realm Installing the Operator I am choosing to install the keycloak operator via the webconsole which is an easy way to do it. It’s also possible to do it via CLI. Simply search for and press install: keycloak Once you press install the installer will ask which namespace you would like to install to. In my case it is the . rhbk This could take a couple of seconds or minutes depending on your cluster. Installing the database For the Keycloak server to store its state and data it should have a database. For this, I will use Crunchy. apiVersion: apps/v1 kind: StatefulSet metadata: name: postgresql-db spec: serviceName: postgresql-db-service selector: matchLabels: app: postgresql-db replicas: 1 template: metadata: labels: app: postgresql-db spec: containers: - name: postgresql-db image: postgres:latest volumeMounts: - mountPath: /data name: cache-volume env: - name: POSTGRES_PASSWORD value: testpassword - name: PGDATA value: /data/pgdata - name: POSTGRES_DB value: keycloak volumes: - name: cache-volume emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: postgres-db spec: selector: app: postgresql-db type: LoadBalancer ports: - port: 5432 targetPort: 5432 Create an SSL certificate for use with the keycloak backend Next, let's generate a self-signed certificate. In a production environment, you'd typically obtain a certificate from a certificate authority. However, for testing purposes, we can use a self-signed certificate. On a Linux machine, you can create a self-signed certificate like this. In this example, represents the address of your Keycloak instance, and "O" stands for . You can replace with any organization identifier you prefer; in my case, it's denoting a test organization. keycloak.rhbk.apps.green.demoshift.com test demoshift test demoshift openssl req -subj '/CN=keycloak.rhbk.apps.green.demoshift.com/O=Test demoshift./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem Generating a 2048 bit RSA private key .....................+++++ .....................+++++ writing new private key to 'key.pem' Let’s load this certificate into our Kubernetes environment by using the following command. Make sure the path for the cert is correct, in my case, I am in the same dir as my cert. kubectl create secret tls example-tls-secret --cert certificate.pem --key key.pem Also a good practice is to load the database password as a secret rather than having it littered around different yaml files. kubectl create secret generic keycloak-db-secret \ --from-literal=username=postgres \ --from-literal=password=testpassword Install the first Keycloak instance apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: instances: 1 db: vendor: postgres host: postgres-db usernameSecret: name: keycloak-db-secret key: username passwordSecret: name: keycloak-db-secret key: password http: tlsSecret: example-tls-secret hostname: hostname: keycloak.rhbk.apps.green.demoshift.com Now, if we go back to the webconsole you should be able to see: Keycloak operator pod PG database pod Keycloak server pod. OpenShift has this nice feature that you can see the route once you click your application. also visible in the image below. Head over to your instance and login. To login, obviously, one needs the admin password which in this case has been autogenerated by the operator. Let’s get that by running the following command: kubectl get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode Assuming we have the password, let’s go back to the route and click on . The username is and password should be what we retrieved from the command above. Adminstration console admin Login and we have landed on our freshly installed Keycloak server. Viola! Importing a realm Currently, we have only the master realm. Generally, it's advisable to keep the master realm as is, making minimal changes, to avoid potential lockout situations. Now, let's explore importing a realm. This is where the Operator's capabilities shine. We'll create a RealmImportCR (Custom Resource), and it will facilitate the addition of a new realm to Keycloak. Consider this scenario: if the Keycloak pod experiences downtime at any point, the Operator will ensure that it's restored to the exact state it was in. Where is this state stored? It's stored within the Custom Resources and the database, providing a robust system for maintaining and recovering configurations. Okay let’s test this out further. How about adding a new realm via the KCImportRealmCR? Let's go back to the Operator view Click on KeycloakRealmImport -> Create instance I had a file. Obviously, operators and most K8s use cases expect yaml so I had to make a conversion. I used the following for conversion. There are also online tools available, but given the sensitive nature of realms, I wouldn’t suggest using a random online tool to convert to Yaml. realm json yq Load the yaml and press create: It can take a couple of seconds to come up. As soon as we create the CR, the Keycloak Operator will pick it up and add it to the running Keycloak instance. If you log back into the admin console it should look like this: If we explore further and look into the clients there is a . It’s a Client config for a Quarkus-based REST service written in Java. That’s for another post. backend-service There is a lot more that can be done with Operators. If you are looking for more in-depth details the Keycloak is a great resource. If you are looking to explore more and try this installation. docs More to come on Keycloak in later posts. Also published . here