2019-12-03 10:22:58 +00:00
2020-05-09 01:16:38 +00:00
[[_external_database]]
=== Connecting to an external database
2019-12-03 10:22:58 +00:00
2021-11-10 10:55:15 +00:00
You can use the Operator to connect to an external PostgreSQL database by creating a `keycloak-db-secret` YAML file and setting Keycloak CR externalDatabase property to enabled. Note that values are Base64 encoded.
2019-12-03 10:22:58 +00:00
2020-05-09 01:16:38 +00:00
.Example YAML file for `keycloak-db-secret`
2019-12-03 10:22:58 +00:00
```yaml
apiVersion: v1
kind: Secret
metadata:
name: keycloak-db-secret
namespace: keycloak
stringData:
POSTGRES_DATABASE: <Database Name>
POSTGRES_EXTERNAL_ADDRESS: <External Database IP or URL (resolvable by K8s)>
POSTGRES_EXTERNAL_PORT: <External Database Port>
POSTGRES_PASSWORD: <Database Password>
# Required for AWS Backup functionality
POSTGRES_SUPERUSER: true
POSTGRES_USERNAME: <Database Username>
type: Opaque
```
2020-05-09 01:16:38 +00:00
The following properties set the hostname or IP address and port of the database.
2019-12-03 10:22:58 +00:00
2020-05-09 01:16:38 +00:00
* `POSTGRES_EXTERNAL_ADDRESS` - an IP address or a hostname of the external database.
ifeval::[{project_community}==true]
This address needs be resolvable in a Kubernetes cluster.
endif::[]
* `POSTGRES_EXTERNAL_PORT` - (Optional) A database port.
2019-12-03 10:22:58 +00:00
2020-05-09 01:16:38 +00:00
The other properties work in the same way for a hosted or external database. Set them as follows:
2019-12-03 10:22:58 +00:00
* `POSTGRES_DATABASE` - Database name to be used.
* `POSTGRES_USERNAME` - Database username
* `POSTGRES_PASSWORD` - Database password
2020-05-09 01:16:38 +00:00
* `POSTGRES_SUPERUSER` - Indicates, whether backups should run as super user. Typically `true`.
2019-12-03 10:22:58 +00:00
2021-11-10 07:23:33 +00:00
The Operator will create a Service named `keycloak-postgresql`. This Service is configured by the Operator to expose the external database based on the content of `POSTGRES_EXTERNAL_ADDRESS`. {project_name} uses this Service to connect to the Database, which means it does not connect to the Database directly but rather through this Service.
2020-05-09 01:16:38 +00:00
The Keycloak custom resource requires updates to enable external database support.
2019-12-03 10:22:58 +00:00
2020-05-09 01:16:38 +00:00
.Example YAML file for `Keycloak` custom resource that supports an external database
2019-12-03 10:22:58 +00:00
```yaml
apiVersion: keycloak.org/v1alpha1
kind: Keycloak
metadata:
labels:
2020-06-08 21:53:30 +00:00
ifeval::[{project_community}==true]
app: example-keycloak
endif::[]
ifeval::[{project_product}==true]
app: sso
endif::[]
2019-12-03 10:22:58 +00:00
name: example-keycloak
namespace: keycloak
spec:
externalDatabase:
enabled: true
instances: 1
```
2020-05-09 01:16:38 +00:00
.Prerequisites
* You have a YAML file for `keycloak-db-secret`.
* You have modified the Keycloak custom resource to set `externalDatabase` to `true`.
* You have cluster-admin permission or an equivalent level of permissions granted by an administrator.
.Procedure
. Locate the secret for your PostgreSQL database: `{create_cmd_brief} get secret <secret_for_db> -o yaml`. For example:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get secret keycloak-db-secret -o yaml
apiVersion: v1
data
POSTGRES_DATABASE: cm9vdA==
POSTGRES_EXTERNAL_ADDRESS: MTcyLjE3LjAuMw==
POSTGRES_EXTERNAL_PORT: NTQzMg==
----
+
The `POSTGRES_EXTERNAL_ADDRESS` is in Base64 format.
. Decode the value for the secret: `echo "<encoded_secret>" | base64 -decode`. For example:
+
[source,bash,subs=+attributes]
----
$ echo "MTcyLjE3LjAuMw==" | base64 -decode
192.0.2.3
----
. Confirm that the decoded value matches the IP address for your database:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get pods -o wide
NAME READY STATUS RESTARTS AGE IP
keycloak-0 1/1 Running 0 13m 192.0.2.0
keycloak-postgresql-c8vv27m 1/1 Running 0 24m 192.0.2.3
----
. Confirm that `keycloak-postgresql` appears in a list of running services:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
keycloak ClusterIP 203.0.113.0 <none> 8443/TCP 27m
keycloak-discovery ClusterIP None <none> 8080/TCP 27m
keycloak-postgresql ClusterIP 203.0.113.1 <none> 5432/TCP 27m
----
+
The `keycloak-postgresql` service sends requests to a set of IP addresses in the backend. These IP addresses are called endpoints.
. View the endpoints used by the `keycloak-postgresql` service to confirm that they use the IP addresses for your database:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get endpoints keycloak-postgresql
NAME ENDPOINTS AGE
keycloak-postgresql 192.0.2.3.5432 27m
----
. Confirm that {project_name} is running with the external database. This example shows that everything is running:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get pods
NAME READY STATUS RESTARTS AGE IP
keycloak-0 1/1 Running 0 26m 192.0.2.0
keycloak-postgresql-c8vv27m 1/1 Running 0 36m 192.0.2.3
----
ifeval::[{project_community}==true]
.Additional Resources
* To back up your database using custom resources, see xref:_backup-cr[Scheduling database backups].
2019-12-03 10:22:58 +00:00
2020-05-09 01:16:38 +00:00
* For more information on Base64 encoding, see the https://kubernetes.io/docs/concepts/configuration/secret/[Kubernetes Secrets manual].
endif::[]