Chapter 2. Basic Red Hat build of Keycloak deployment 2.1. Performing a basic Red Hat build of Keycloak deployment This chapter describes how to perform a basic Red Hat build of Keycloak Deployment on OpenShift using the Operator. 2.1.1. Preparing for deployment Once the Red Hat build of Keycloak Operator is installed and running in the cluster namespace, you can set up the other deployment prerequisites. Database Hostname TLS Certificate and associated keys 2.1.1.1. Database A database should be available and accessible from the cluster namespace where Red Hat build of Keycloak is installed. For a list of supported databases, see Configuring the database . The Red Hat build of Keycloak Operator does not manage the database and you need to provision it yourself. Consider verifying your cloud provider offering or using a database operator. For development purposes, you can use an ephemeral PostgreSQL pod installation. To provision it, follow the approach below: Create YAML file example-postgres.yaml : 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 Apply the changes: oc apply -f example-postgres.yaml 2.1.1.2. Hostname For a production ready installation, you need a hostname that can be used to contact Red Hat build of Keycloak. See Configuring the hostname for the available configurations. For development purposes, this chapter will use test.keycloak.org . 2.1.1.3. TLS Certificate and key See your Certification Authority to obtain the certificate and the key. For development purposes, you can enter this command to obtain a self-signed certificate: openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem You should install it in the cluster namespace as a Secret by entering this command: oc create secret tls example-tls-secret --cert certificate.pem --key key.pem 2.1.2. Deploying Red Hat build of Keycloak To deploy Red Hat build of Keycloak, you create a Custom Resource (CR) based on the Keycloak Custom Resource Definition (CRD). Consider storing the Database credentials in a separate Secret. Enter the following commands: oc create secret generic keycloak-db-secret \ --from-literal=username=[your_database_username] \ --from-literal=password=[your_database_password] You can customize several fields using the Keycloak CRD. For a basic deployment, you can stick to the following approach: Create YAML file example-kc.yaml : 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: test.keycloak.org Apply the changes: oc apply -f example-kc.yaml To check that the Red Hat build of Keycloak instance has been provisioned in the cluster, check the status of the created CR by entering the following command: oc get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}' When the deployment is ready, look for output similar to the following: CONDITION: Ready STATUS: true MESSAGE: CONDITION: HasErrors STATUS: false MESSAGE: CONDITION: RollingUpdate STATUS: false MESSAGE: 2.1.3. Accessing the Red Hat build of Keycloak deployment The Red Hat build of Keycloak deployment is exposed through a basic Ingress and is accessible through the provided hostname. On installations with multiple default IngressClass instances or when running on OpenShift 4.12+ you should provide an ingressClassName by setting ingress spec with className property to the desired class name: Edit YAML file example-kc.yaml : apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... ingress: className: openshift-default If the default ingress does not fit your use case, disable it by setting ingress spec with enabled property to false value: Edit YAML file example-kc.yaml : apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... ingress: enabled: false Apply the changes: oc apply -f example-kc.yaml You can provide an alternative ingress resource pointing to the service <keycloak-cr-name>-service . For debugging and development purposes, consider directly connecting to the Red Hat build of Keycloak service using a port forward. For example, enter this command: oc port-forward service/example-kc-service 8443:8443 2.1.4. Accessing the Admin Console When deploying Red Hat build of Keycloak, the operator generates an arbitrary initial admin username and password and stores those credentials as a basic-auth Secret object in the same namespace as the CR. Warning Change the default admin credentials and enable MFA in Red Hat build of Keycloak before going to production. To fetch the initial admin credentials, you have to read and decode the Secret. The Secret name is derived from the Keycloak CR name plus the fixed suffix -initial-admin . To get the username and password for the example-kc CR, enter the following commands: oc get secret example-kc-initial-admin -o jsonpath='{.data.username}' | base64 --decode oc get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode You can use those credentials to access the Admin Console or the Admin REST API.

Commands:
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
apply -f example-postgres.yaml
openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
create secret tls example-tls-secret --cert certificate.pem --key key.pem
create secret generic keycloak-db-secret --from-literal=username=[your_database_username] --from-literal=password=[your_database_password]
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: test.keycloak.org
apply -f example-kc.yaml
get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
CONDITION: Ready STATUS: true MESSAGE: CONDITION: HasErrors STATUS: false MESSAGE: CONDITION: RollingUpdate STATUS: false MESSAGE:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ingress: className: openshift-default
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ingress: enabled: false
apply -f example-kc.yaml
port-forward service/example-kc-service 8443:8443
get secret example-kc-initial-admin -o jsonpath='{.data.username}' | base64 --decode get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode