diff --git a/assemblies/assembly-install-rhdh-orchestrator-helm.adoc b/assemblies/assembly-install-rhdh-orchestrator-helm.adoc index 1c25fb1bc13..e5f2fe447dd 100644 --- a/assemblies/assembly-install-rhdh-orchestrator-helm.adoc +++ b/assemblies/assembly-install-rhdh-orchestrator-helm.adoc @@ -15,6 +15,8 @@ include::modules/orchestrator/proc-install-rhdh-with-orchestrator-helm-cli.adoc[ include::modules/orchestrator/proc-install-rhdh-with-orchestrator-helm-webui.adoc[leveloffset=+1] +include::modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure-using-helm.adoc[leveloffset=+1] + include::modules/orchestrator/ref-orchestrator-resource-limits.adoc[leveloffset=+1] // manual installation diff --git a/assemblies/assembly-install-rhdh-orchestrator-operator.adoc b/assemblies/assembly-install-rhdh-orchestrator-operator.adoc index 3d7d0f4af02..d1afea362df 100644 --- a/assemblies/assembly-install-rhdh-orchestrator-operator.adoc +++ b/assemblies/assembly-install-rhdh-orchestrator-operator.adoc @@ -13,6 +13,8 @@ You can install {product} with Orchestrator by using the {product} Operator. include::modules/orchestrator/proc-enable-orchestrator-plugin.adoc[leveloffset=+1] +include::modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure.adoc[leveloffset=+1] + include::modules/orchestrator/proc-upgrading-the-orchestrator-plugin.adoc[leveloffset=+1] include::modules/orchestrator/proc-troubleshoot-orchestrator-upgrade.adoc[leveloffset=+1] diff --git a/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-helm.adoc b/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-helm.adoc index f16d0315df5..811785da6fe 100644 --- a/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-helm.adoc +++ b/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-helm.adoc @@ -76,7 +76,8 @@ EOF <2> Provide credential data to connect with your PostgreSQL instance. <3> Optional: Provide the value based on the required link:https://www.postgresql.org/docs/15/libpq-connect.html#LIBPQ-CONNECT-SSLMODE[Secure Sockets Layer (SSL) mode]. <4> Optional: Provide the value only if you need a TLS connection for your PostgreSQL instance. - ++ +include::../shared/snip-create-kubernetes-service-for-external-postgresql.adoc[] . Configure your PostgreSQL instance in the Helm configuration file named `values.yaml`: + [source,yaml,subs="+quotes,+attributes"] diff --git a/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-the-operator.adoc b/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-the-operator.adoc index 6afdbc0a463..90bca7171dd 100644 --- a/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-the-operator.adoc +++ b/modules/configuring-external-databases/proc-configuring-postgresql-instance-using-the-operator.adoc @@ -76,6 +76,11 @@ EOF <2> Provide credential data to connect with your PostgreSQL instance. <3> Optional: Provide the value based on the required link:https://www.postgresql.org/docs/15/libpq-connect.html#LIBPQ-CONNECT-SSLMODE[Secure Sockets Layer (SSL) mode]. <4> Optional: Provide the value only if you need a TLS connection for your PostgreSQL instance. ++ +include::../shared/snip-create-kubernetes-service-for-external-postgresql.adoc[] +. Optional: Ensure your external PostgreSQL instance is configured with recommended performance tuning parameters. ++ +Set `shared_buffers` to approximately 1/4 and `effective_cache_size` to approximately 1/2 of the allocated database memory. . Create your `{product-custom-resource-type}` custom resource (CR): + diff --git a/modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure-using-helm.adoc b/modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure-using-helm.adoc new file mode 100644 index 00000000000..4c7c2c160d6 --- /dev/null +++ b/modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure-using-helm.adoc @@ -0,0 +1,62 @@ +:_mod-docs-content-type: PROCEDURE + +[id="configure-orchestrator-to-connect-to-existing-postgresql-infrastructure-using-helm_{context}"] += Configure Orchestrator to connect to existing PostgreSQL infrastructure using Helm + +[role="_abstract"] +Connect the Orchestrator plugins to your existing PostgreSQL database when deploying with the Helm chart to leverage centralized database management and meet compliance requirements. + +By default, when you enable the Orchestrator plugin by using the Helm chart with `orchestrator.enabled=true`, the chart automatically provisions a `SonataFlowPlatform` custom resource (CR) and creates the required PostgreSQL database resources. The chart uses the `orchestrator.sonataflowPlatform` values to configure these resources. + +However, when you use an external PostgreSQL database that the Helm chart does not manage, you must explicitly configure the `orchestrator.sonataflowPlatform` values to reference your external database resources. + +.Prerequisites +* You have installed {product-very-short} by using the Helm chart. +* You have {configuring-book-link}#proc-configuring-postgresql-instance-using-helm_configuring-external-postgresql-databases[configured {product-short} to use an external PostgreSQL database]. +* You have access to create jobs, secrets, services, and custom resources in the namespace where you deploy {product-very-short}. + +.Procedure +include::../shared/snip-create-orchestrator-database.adoc[] +. Configure your external PostgreSQL database for Orchestrator in your Helm configuration file `values.yaml`: ++ +[source,yaml,subs="+quotes,+attributes"] +---- +orchestrator: + enabled: true + sonataflowPlatform: + externalDBsecretRef: ____ + externalDBName: backstage_plugin_orchestrator + externalDBHost: ____ + externalDBPort: "5432" +---- ++ +Where: + +`orchestrator.enabled`:: Set to `true` to enable the Orchestrator plugin. +`orchestrator.sonataflowPlatform.externalDBsecretRef`:: The secret name containing database credentials with `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_HOST`, and `POSTGRES_PORT` keys. +`orchestrator.sonataflowPlatform.externalDBName`:: The database name for Orchestrator data (must be `backstage_plugin_orchestrator`). +`orchestrator.sonataflowPlatform.externalDBHost`:: The Kubernetes Service name pointing to your external database. +`orchestrator.sonataflowPlatform.externalDBPort`:: The PostgreSQL port (typically `5432`). ++ +[IMPORTANT] +==== +Unlike the default configuration where the Helm chart automatically provisions database resources, this configuration explicitly references your external database Service and Secret. The `SonataFlowPlatform` CR will use these resources to connect to your external database instead of creating new database resources. +==== ++ +. Apply the configuration changes in your Helm configuration file `values.yaml`: ++ +[source,terminal,subs="+attributes"] +---- +$ helm upgrade -n openshift-helm-charts/redhat-developer-hub -f values.yaml --version {product-chart-version} +---- + +.Verification +. Verify that the `SonataFlowPlatform` CR is running: ++ +[source,terminal] +---- +$ oc get sonataflowplatform sonataflow-platform -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' +True +---- ++ +. In the {product-very-short} console, confirm that the Orchestrator frontend and backend features are available and can connect to your external database. diff --git a/modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure.adoc b/modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure.adoc new file mode 100644 index 00000000000..d2a5262ba16 --- /dev/null +++ b/modules/orchestrator/proc-configure-orchestrator-to-connect-to-existing-postgresql-infrastructure.adoc @@ -0,0 +1,125 @@ +:_mod-docs-content-type: PROCEDURE + +[id="configure-orchestrator-to-connect-to-existing-postgresql-infrastructure_{context}"] += Configure Orchestrator to connect to existing PostgreSQL infrastructure + +[role="_abstract"] +Connect the Orchestrator plugins to your existing PostgreSQL database to leverage centralized database management and meet compliance requirements. + +By default, when you enable the Orchestrator plugin by using the Operator, the `dependencies: - ref: sonataflow` field automatically provisions a `SonataFlowPlatform` custom resource (CR) and creates the required PostgreSQL database resources. The Operator uses specific naming patterns for these resources (such as `backstage-psql-{{backstage-name}}` for the service and `backstage-psql-secret-{{backstage-name}}` for the secret). + +However, when you use an external PostgreSQL database that the Operator does not manage, these default resources and naming patterns do not exist. You must explicitly configure the `SonataFlowPlatform` CR to reference your external database resources and remove the automatic dependency provisioning. + +.Prerequisites +* You have installed {product-very-short} by using the Operator. +* You have {configuring-book-link}#proc-configuring-postgresql-instance-using-operator_configuring-external-postgresql-databases[configured {product-short} to use an external PostgreSQL database]. +* You have access to create jobs, secrets, config maps, and custom resources in the namespace where you deploy the {product-custom-resource-type} CR. + +.Procedure +include::../shared/snip-create-orchestrator-database.adoc[] +. Create a `SonataFlowPlatform` CR that references your external PostgreSQL service: ++ +[source,yaml,subs="+attributes,+quotes"] +---- +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowPlatform +metadata: + name: sonataflow-platform +spec: + monitoring: + enabled: true + services: + dataIndex: + enabled: true + persistence: + postgresql: + secretRef: + name: ____ + userKey: POSTGRES_USER + passwordKey: POSTGRES_PASSWORD + serviceRef: + name: ____ + namespace: __<{product-very-short}-NAMESPACE>__ + databaseName: backstage_plugin_orchestrator + jobService: + enabled: true + persistence: + postgresql: + secretRef: + name: ____ + userKey: POSTGRES_USER + passwordKey: POSTGRES_PASSWORD + serviceRef: + name: ____ + namespace: __<{product-very-short}-NAMESPACE>__ + databaseName: backstage_plugin_orchestrator +---- ++ +[IMPORTANT] +==== +Unlike the default configuration that uses the `dependencies: - ref: sonataflow` field to automatically provision database resources with specific naming patterns, this configuration explicitly references your external database Service and Secret. The `SonataFlowPlatform` CR will use these resources to connect to your external database instead of creating new database resources. +==== ++ +. Configure the Orchestrator plugins in your dynamic plugins config map to remove the default `sonataflow` dependency and explicitly reference the SonataFlowPlatform services: ++ +[source,yaml,subs="+attributes,+quotes"] +---- +apiVersion: v1 +kind: ConfigMap +metadata: + name: orchestrator-plugin +data: + dynamic-plugins.yaml: | + includes: + - dynamic-plugins.default.yaml + plugins: + # Orchestrator plugins + - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}" + disabled: false + - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend:{{inherit}}" + disabled: false + pluginConfig: + orchestrator: + dataIndexService: + url: http://____ + dependencies: [{}] # Empty array removes default 'ref: sonataflow' to prevent automatic database provisioning + - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:{{inherit}}" + disabled: false + pluginConfig: + orchestrator: + dataIndexService: + url: http://____ + dependencies: [{}] # Empty array removes default 'ref: sonataflow' to prevent automatic database provisioning + - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:{{inherit}}" + disabled: false +---- ++ +. Update your {product-custom-resource-type} CR to reference the orchestrator plugin config map and inject the database credentials secret: ++ +[source,yaml,subs="+attributes,+quotes"] +---- +apiVersion: rhdh.redhat.com/v1alpha5 +kind: {product-custom-resource-type} +metadata: + name: orchestrator +spec: + application: + appConfig: + configMaps: + - name: app-config-rhdh + dynamicPluginsConfigMapName: orchestrator-plugin + extraEnvs: + secrets: + - name: ____ +---- + +.Verification +. Verify that the `SonataFlowPlatform` CR is running: ++ +[source,terminal] +---- +$ oc get sonataflowplatform sonataflow-platform -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' +True +---- ++ +. In the {product-very-short} console, confirm that the Orchestrator frontend and backend features are available and can connect to your external database. diff --git a/modules/orchestrator/proc-install-rhdh-with-orchestrator-helm-cli.adoc b/modules/orchestrator/proc-install-rhdh-with-orchestrator-helm-cli.adoc index bd3209ac4aa..71222eea295 100644 --- a/modules/orchestrator/proc-install-rhdh-with-orchestrator-helm-cli.adoc +++ b/modules/orchestrator/proc-install-rhdh-with-orchestrator-helm-cli.adoc @@ -70,21 +70,11 @@ $ helm install openshift-helm-charts/redhat-developer-hub \ --set orchestrator.serverlessLogicOperator=false ---- -. (Optional) If you are using an external database, add the following configuration under `orchestrator.sonataflowPlatform` in your `values.yaml` file: -+ -[source,yaml] ----- -orchestrator: - sonataflowPlatform: - externalDBsecretRef: "" - externalDBName: "" # The name of the user-configured existing database (Not the database that the orchestrator and sonataflow resources use). - externalDBHost: "" - externalDBPort: "" ----- +. (Optional) To configure Orchestrator to use an external PostgreSQL database, follow the detailed instructions in xref:configure-orchestrator-to-connect-to-existing-postgresql-infrastructure-using-helm_{context}[Configure Orchestrator to connect to existing PostgreSQL infrastructure using Helm]. + [NOTE] ==== -This step only configures the Orchestrators use of an external database. To configure {product} to use an external PostgreSQL instance, follow the steps in {configuring-book-link}#proc-configuring-postgresql-instance-using-helm_configuring-external-postgresql-databases[Configuring a PostgreSQL instance using Helm]. +Configuring an external database for Orchestrator requires additional steps beyond standard {product-very-short} external database configuration. You must create the `backstage_plugin_orchestrator` database, configure the `orchestrator.sonataflowPlatform` values, and ensure proper service connectivity. See the detailed procedure for complete instructions. ==== .Verification diff --git a/modules/shared/snip-create-kubernetes-service-for-external-postgresql.adoc b/modules/shared/snip-create-kubernetes-service-for-external-postgresql.adoc new file mode 100644 index 00000000000..637c67edca7 --- /dev/null +++ b/modules/shared/snip-create-kubernetes-service-for-external-postgresql.adoc @@ -0,0 +1,56 @@ +:_mod-docs-content-type: SNIPPET +. Create a Kubernetes service that points to your external PostgreSQL database: ++ +[source,yaml,subs="+attributes,+quotes"] +---- +apiVersion: v1 +kind: Service +metadata: + name: external-postgresql-service +spec: + type: ExternalName + externalName: ____ + ports: + - port: 5432 + targetPort: 5432 + protocol: TCP +---- ++ +Where: + +`external-postgresql-service`:: Name of the service to reference in plugin configurations. +`ExternalName`:: Service type that creates a CNAME record to the external database host name. +`____`:: FQDN of your external PostgreSQL server, for example, `postgres.example.com`. ++ +[NOTE] +==== +If your external database is outside the cluster or uses an IP address instead of a host name, create a service with endpoints: + +[source,yaml,subs="+attributes,+quotes"] +---- +apiVersion: v1 +kind: Service +metadata: + name: external-postgresql-service +spec: + ports: + - port: 5432 + targetPort: 5432 + protocol: TCP +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: external-postgresql-service +subsets: + - addresses: + - ip: ____ + ports: + - port: 5432 + protocol: TCP +---- + +Where: + +`____`:: IP address of your external PostgreSQL server. +==== \ No newline at end of file diff --git a/modules/shared/snip-create-orchestrator-database.adoc b/modules/shared/snip-create-orchestrator-database.adoc new file mode 100644 index 00000000000..e8d5187cf8d --- /dev/null +++ b/modules/shared/snip-create-orchestrator-database.adoc @@ -0,0 +1,46 @@ +:_mod-docs-content-type: SNIPPET +. Create the `backstage_plugin_orchestrator` database on your external PostgreSQL server by applying the following job: ++ +[source,yaml,subs="+attributes,+quotes"] +---- +apiVersion: batch/v1 +kind: Job +metadata: + name: create-sonataflow-database-developer-hub +spec: + ttlSecondsAfterFinished: 30 + activeDeadlineSeconds: 120 + template: + spec: + containers: + - name: psql + image: quay.io/fedora/postgresql-15:latest + resources: + limits: + cpu: "100m" + memory: "128Mi" + requests: + cpu: "100m" + memory: "64Mi" + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + envFrom: + - secretRef: + name: ____ + command: [ "sh", "-c" ] + args: + - | + set -e + # Check if the backstage_plugin_orchestrator database exists + DB_EXISTS=$(PGPASSWORD=${POSTGRES_PASSWORD} psql -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} -tAc "SELECT 1 FROM pg_database WHERE datname='backstage_plugin_orchestrator'" postgres) + if [ -z "$DB_EXISTS" ]; then + # Create the database if it does not exist + PGPASSWORD=${POSTGRES_PASSWORD} psql -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} -c "CREATE DATABASE backstage_plugin_orchestrator;" postgres + fi + restartPolicy: Never +---- \ No newline at end of file