| Please refer to KubeRocketCI documentation to get the main concepts and guidelines. |
|---|
Get acquainted with the Keycloak Operator, the installation process, the quick start, and the local development guidelines.
Keycloak Operator is a KubeRocketCI operator responsible for configuring existing Keycloak instances. The operator runs both on OpenShift and Kubernetes.
NOTE: Operator is platform-independent, which is why there is a unified instruction for deployment.
- Kubernetes 1.32 or later, or OpenShift 4.19 or later;
- Linux machine or Windows Subsystem for Linux instance with Helm 3 installed;
- Cluster admin access to the cluster;
- cert-manager installed in the cluster (required for webhook functionality, can be disabled via
enableWebhooks: false);
To install the Keycloak Operator, follow the steps below:
-
To add the Helm EPAMEDP Charts for a local client, run "helm repo add":
helm repo add epamedp https://epam.github.io/edp-helm-charts/stable
-
Choose the available Helm chart version:
helm search repo epamedp/keycloak-operator -l NAME CHART VERSION APP VERSION DESCRIPTION epamedp/keycloak-operator 1.36.0 1.36.0 A Helm chart for KRCI Keycloak OperatorNOTE: It is highly recommended to use the latest stable version.
-
Full chart parameters available in deploy-templates/README.md.
-
Install the operator in the namespace with the helm command; find below the installation command example:
helm install keycloak-operator epamedp/keycloak-operator --version <chart_version> --namespace <edp-project> --set name=keycloak-operator
-
Check the namespace containing Deployment with your operator in running status.
-
Create a User in the Keycloak
Masterrealm, and assign acreate-realmrole.Supported Keycloak versions: 26.4 to 26.8. The user holds the realm-management roles on realms it created only. On other realms it needs
manage-clients,manage-identity-providersand, forallowAdminRoleMapping,manage-realm. -
Insert newly created user credentials into Kubernetes secret:
apiVersion: v1 kind: Secret metadata: name: keycloak-access type: Opaque data: username: dXNlcg== # base64-encoded value of "user" password: cGFzcw== # base64-encoded value of "pass"
-
Create Custom Resource
kind: Keycloakwith Keycloak instance URL and secret created on the previous step:apiVersion: v1.edp.epam.com/v1 kind: Keycloak metadata: name: keycloak-sample spec: secret: keycloak-access # Secret name url: https://keycloak.example.com # Keycloak URL
Wait for the
.statusfield withstatus.connected: true# Check the current status kubectl get keycloak keycloak-sample -n -o jsonpath='{.status.connected}' # Or wait automatically until connected kubectl wait --for=jsonpath='{.status.connected}'=true keycloak/keycloak-sample -n --timeout=300s
-
Create Keycloak realm and group using Custom Resources:
apiVersion: v1.edp.epam.com/v1 kind: KeycloakRealm metadata: name: keycloakrealm-sample spec: realmName: realm-sample keycloakRef: name: keycloak-sample kind: Keycloak
apiVersion: v1.edp.epam.com/v1 kind: KeycloakRealmGroup metadata: name: argocd-admins spec: name: ArgoCDAdmins realmRef: name: keycloakrealm-sample kind: KeycloakRealm
Inspect available custom resource and CR templates folder for more examples.
To prevent the operator from deleting resources from Keycloak, add the edp.epam.com/preserve-resources-on-deletion: "true" annotation to the resource.
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealm
metadata:
name: keycloakrealm-sample
annotations:
edp.epam.com/preserve-resources-on-deletion: "true"
spec:
realmName: realm-sample
keycloakRef:
name: keycloak-sample
kind: KeycloakTo avoid resources getting stuck during deletion, it is important to delete them in the correct order:
- First, remove realm resources
KeycloakClient,KeycloakRealmUser, etc. - Then, remove
KeycloakRealm/ClusterKeycloakRealm. - Finally, remove
Keycloak/ClusterKeycloak.
Keycloak: the operator does not watch the credential Secret. A connectedKeycloakis checked again only on a change of the resource, an operator restart or the cache resync (about 10 hours).status.connectedcan staytrueafter a Secret change. To check at once, change an annotation of the resource.ClusterKeycloakis checked every 30 minutes.KeycloakClient:spec.enabledis always managed. Omitted meanstrue. A client that you disable in Keycloak is enabled again on the next reconcile. To keep the client disabled, setenabled: false. With an emptysuccessReconcileTimeout(chart default), the next reconcile comes after a change of the resource, an operator restart or the cache resync.KeycloakClient,KeycloakRealmIdentityProvider: the resource is the source of truth for the boolean flags that the operator sends. An omitted flag, such aspublic,bearerOnlyortrustEmail, is written asfalse.standardFlowEnabledandfullScopeAllowedofKeycloakClientdefault totrue. Adopting an existing client or identity provider overwrites its flags. A flag changed in the Keycloak UI is overwritten on the next reconcile. Copy the Keycloak values into the resource before adoption and after a change in the Keycloak UI.KeycloakClient: when webhooks are enabled (chart default), the defaulting webhook storeswebOrigins: [<webUrl>]in a resource withwebUrland withoutwebOrigins. A later change ofwebUrldoes not change the storedwebOrigins. After you changewebUrl, setwebOriginsto the new value.KeycloakClient: realm roles that the deprecatedspec.realmRolescreated stay in Keycloak after you delete the resource. To manage such a role, create aKeycloakRealmRolewith the same name.KeycloakOrganization(Keycloak 26.8): only one organization can holdmembershipType: MANAGEDfor an identity provider. In a second organization withMANAGED, the link staysUNMANAGED. Its reconcile fails before the domain settings. The status shows the Keycloak message.KeycloakOrganization(Keycloak older than 26.8): a non-emptydomainsV2[].identityProviderAlias,domainsV2[].autoRedirect: true,identityProviders[].autoMembershipandidentityProviders[].membershipTypefail the reconcile before any write. The status names the field and the server version. If Keycloak does not report a version, or reports one the operator cannot parse, the check is skipped. A failed/admin/serverinforead fails the reconcile for such a resource on any Keycloak version.KeycloakRealmComponent: removing a key fromspec.configdoes not remove it in Keycloak. For some providers, such asrsa-generated, set the key to[], wait for the reconcile, then remove it from the spec.KeycloakRealmComponent: some providers, such asrsa-generated, dropspec.configkeys that they do not declare. The operator then updates such a component on each reconcile, every 10 minutes. Remove such keys from the spec.KeycloakRealmUser: a user disabled in Keycloak, also by permanent lockout, is enabled again whenspec.enabledistrue. Keycloak then clears its login failures.- Metrics (Helm chart): the operator serves
/metricson port 8443 with authentication and authorization. The endpoint uses a self-signed certificate. The chart does not grant the operatortokenreviewsandsubjectaccessreviews, and creates no metrics Service. A scrape fails. To scrape, bind the rules of config/rbac/metrics_auth_role.yaml to the operator service account, and bind config/rbac/metrics_reader_role.yaml to the scraper.
Secret references, who may author which resources, and the destination allowlist: docs/security.md.
Changes that need action when you upgrade Keycloak or the operator: docs/upgrade-notes.md.
For comprehensive local development setup, testing, debugging, and common development tasks, refer to the Development Guide.
Development versions are also available from the snapshot Helm Chart repository page.
The pkg/client/keycloakapi package is a standalone Go client for the Keycloak Admin REST API (Keycloak 25+, including Red Hat build of Keycloak) and can be imported independently of the operator. See the package documentation on pkg.go.dev for usage, supported authentication options, and the available sub-clients.