Platform installation
To install OpenLM Platform on Kubernetes with Helm, configure and install the API gateway and the OpenLM Platform Helm chart. These steps are common across the three manual Kubernetes deployment paths: on-premises machines, AWS, and Azure. On Red Hat OpenShift, also apply the settings in Red Hat OpenShift.
This page covers the current openlm_mono chart. A new chart, openlm-platform 1.0, is available as a release candidate. To install it, follow the preview guide Kubernetes and OpenShift (Helm).
If you are deploying Platform as VM, skip this page. That path installs the gateway and platform charts for you through its bundled installer. Running the Helm commands on this page on top of it creates a second, conflicting set of services. Use Configuration and Deployment instead.
Before you begin
Confirm that you completed the prerequisites checklist for your deployment path.
Install the API gateway
To route external traffic to OpenLM Platform, install the API gateway first. The API gateway is the single entry point for all external traffic.
Configure
To configure the gateway, edit the gateway values.yaml:
- Set
tyk-oss.tyk-gateway.gateway.hostNameto your domain (for example,openlm.yourcompany.com). - Set the same domain in
tyk-oss.tyk-gateway.gateway.ingress.hostsandtyk-oss.tyk-gateway.gateway.ingress.tls. - Set the Redis address in
tyk-oss.global.redis.addrs. - Set the Redis password in
tyk-oss.global.redis.pass. - If Redis uses TLS, also set
tyk-oss.global.redis.useSSL: true. - Set
tyk-oss.global.secrets.APISecretto a random value, for example the output ofopenssl rand -hex 24. - Set
storageClassNameto your cluster's storage class. - Turn off the Tyk pump with
tyk-oss.global.components.pump: false.
Install
Run this command:
helm install openlm-gateway openlm-gateway-<version>.tgz \
-f values.yaml \
-n openlm
Keep the release name openlm-gateway: OpenLM Platform sends /api traffic to the service this name creates, gateway-svc-openlm-gateway-tyk-gateway. Use the gateway chart package from OpenLM. A chart named openlm-gateway in OpenLM's Helm repository is a different component.
Verify
Run these commands:
kubectl exec -it <any-pod> -n openlm -- /bin/sh
curl https://<your-domain>/api/homepage/.security
A "host not reachable" response is expected at this stage. It confirms the gateway routing is configured. If you see other errors, check the gateway logs and verify the Redis address.
Configure the OpenLM Platform Helm chart
You deploy OpenLM Platform with a single umbrella Helm chart, openlm_mono, with a sub-chart for each component. The chart turns every component off by default and leaves every connection empty. You supply them in two places: Kubernetes secrets hold the credentials and connection strings, and your values file holds everything else.
OpenLM gives you the version of the OpenLM Platform chart to install, together with the API gateway chart and the reporting SQL scripts. Install the chart version you were given, and don't override the image tags it pins.
Create the secrets
The components read their credentials from secrets in the openlm namespace. Create the secrets before you install OpenLM Platform: a component whose secret is missing doesn't start.
Password encoding is per-field, not global. Base64-encode the password in these values:
INFRASTRUCTURE__ServerConnectionStringTemplateIDENTITY_DATABASE_CONNECTIONSTRINGDbPasswordinopenlm-dss-db-credentialsREPORTING_DATABASE_CONNECTIONSTRINGConnectionStringin thevars_listof theidentitycomponent
Use the plain-text password in PASSWORD of openlm-generic-reporting-mssql-credentials.
The following commands create the database secrets for SQL Server. Replace the placeholders. For a SQL Server without TLS, set Encrypt=False in TAIL.
NS=openlm; H='<sql-host>'; U='<sql-user>'; P='<sql-password>'
PB64=$(printf '%s' "$P" | base64 | tr -d '\n')
TAIL='Min Pool Size=0;Max Pool Size=100;Encrypt=True;TrustServerCertificate=True'
kubectl -n $NS create secret generic openlm-generic-identity-db-credentials \
--from-literal="IDENTITY_DATABASE_CONNECTIONSTRING=Data Source=$H;Initial Catalog=openlm_identity;User ID=$U;Password=$PB64;$TAIL"
kubectl -n $NS create secret generic openlm-generic-server-db-credentials \
--from-literal="INFRASTRUCTURE__ServerConnectionStringTemplate=Data Source=$H;Initial Catalog={0};User ID=$U;Password=$PB64;$TAIL"
kubectl -n $NS create secret generic openlm-generic-reporting-db-credentials \
--from-literal="REPORTING_DATABASE_CONNECTIONSTRING=Data Source=$H;Initial Catalog=openlm_reporting;User ID=$U;Password=$PB64;$TAIL"
kubectl -n $NS create secret generic openlm-generic-reporting-mssql-credentials \
--from-literal=HOST_NAME=$H --from-literal=PORT=1433 --from-literal=USERNAME=$U --from-literal=PASSWORD="$P"
kubectl -n $NS create secret generic openlm-dss-db-credentials \
--from-literal=DbType=2 --from-literal=DbServer=$H --from-literal=DbPort=1433 \
--from-literal=DbName=openlm_dss --from-literal=DbUser=$U --from-literal=DbPassword=$PB64
{0} in INFRASTRUCTURE__ServerConnectionStringTemplate is a placeholder the services substitute per database. Leave it in place. The operational database itself carries a _none suffix: if INFRASTRUCTURE__ServerDbPrefix in your values file is openlm_operational, the database must be named openlm_operational_none. On an external SQL Server, your database administrator must pre-create the database under the suffixed name.
To build the template with the password already Base64-encoded, use the Database Configuration Tool and enter {0} as Database Name. Its output follows the format of the following examples.
For MariaDB or MySQL, use a ServerConnectionStringTemplate like this one, with a Base64-encoded password:
Server=mariadb.openlm-infrastructure.svc.cluster.local;Port=3306;User ID=root;Password=<base64-password>;Database={0};Connection Lifetime=0;Minimum Pool Size=0;Maximum Pool Size=100;Default Command Timeout=30
For SQL Server, use a ServerConnectionStringTemplate like this one, with a Base64-encoded password:
Data Source=<host>;Initial Catalog={0};User ID=<user>;Password=<base64-password>;Min Pool Size=0;Max Pool Size=100;Encrypt=False;TrustServerCertificate=False
The DbType value in openlm-dss-db-credentials sets the DSS database engine:
| Value | Engine |
|---|---|
2 | SQL Server |
3 | MySQL |
4 | MariaDB |
Next, create the secrets for MongoDB, Kafka, and Redis. For Redis over TLS, write the connection string as <redis-host>:<port>,ssl=True,password=<redis-password>.
kubectl -n $NS create secret generic openlm-generic-mongo-db-credentials \
--from-literal="MONGODB__CONNECTIONSTRING=mongodb://<user>:<password>@<mongodb-host>:27017/"
kubectl -n $NS create secret generic openlm-generic-kafka-bootstrap-credentials \
--from-literal="INFRASTRUCTURE__KAFKABOOTSTRAPSERVERS=<kafka-host>:9092"
kubectl -n $NS create secret generic openlm-generic-redis-connection-credentials \
--from-literal="REDIS__CONNECTIONSTRING=<redis-host>:6379,password=<redis-password>,abortConnect=false"
OpenLM Platform connects to Kafka with the bootstrap address only. This fits the in-cluster Kafka of every deployment path, whose client listener has no authentication. A Kafka that requires SASL authentication, such as Amazon MSK with SASL/SCRAM or Confluent Cloud, needs additional connection settings that this guide doesn't cover. Ask OpenLM for them when you install.
The following integration secrets are needed by components of the full on-premises set. Create them even if you don't use the integration, and fill in their keys only if you do:
| Secret | Keys |
|---|---|
openlm-auditservice-aws-credentials | ACCESSKEY, SECRETKEY |
openlm-licensefilecomparator-aws-credentials | AWS_SQS_ACCESS_KEY, AWS_SQS_SECRET_KEY |
openlm-licensefilecomparator-servicenow-credentials | SERVICENOW_CLIENTID, SERVICENOW_CLIENTSECRET, SERVICENOW_USERNAME, SERVICENOW_PASSWORD, SERVICENOW_INSTANCE_URL, AWS_SQS_QUEUE_URL, AWS_SQS_REGION, BROKERHUBAPI_DELAY_IN_MILLISECONDS, BROKERHUBAPI_MAX_RETRY_COUNT, AWS_SQS_MAX_MESSAGES, AWS_SQS_QUEUE_WORKER_COUNT, AWS_SQS_WAIT_TIME_SECONDS |
openlm-pushnotification-alertservice-credentials, openlm-pushnotification-identityservice-credentials, openlm-pushnotification-identityalignment-credentials | Google service-account fields |
openlm-sam-apikeys | Exchange-rate API keys |
Give the integer keys of the ServiceNow secret a value even when you don't use the integration, for example BROKERHUBAPI_DELAY_IN_MILLISECONDS=10000, BROKERHUBAPI_MAX_RETRY_COUNT=5, AWS_SQS_MAX_MESSAGES=5, AWS_SQS_QUEUE_WORKER_COUNT=3, and AWS_SQS_WAIT_TIME_SECONDS=10. With an empty integer key, the service crashes. The push notification secrets can stay empty.
Write the values file
Your values file sets the routing, the OpenLM Platform URLs, and the database type. Start from the following example, and replace openlm.example.com with your FQDN:
global:
masterIngress:
enabled: true
hostname: openlm.example.com
ingressClassName: traefik # or nginx
secretName: openlm-lb-cert
apiBackendService: gateway-svc-openlm-gateway-tyk-gateway
affinity:
enabled: true # false if your nodes carry no openlm.com/role labels
taints:
enabled: true # false if your nodes carry no openlm.com/role labels
openlm_config_generic:
configmap:
vars_list:
AUTHORITY_URL: https://openlm.example.com/identity
INFRASTRUCTURE__AUTHORITYURL: https://openlm.example.com/identity
IssuerUri: https://openlm.example.com/identity
UI_BASE_HREF_URL: https://openlm.example.com/identity
UI_OAUTH_ISSUER_URL: https://openlm.example.com/identity
LB_FQDN: openlm.example.com
INFRASTRUCTURE__LBFQDN: openlm.example.com
LdapServiceHost: https://openlm.example.com
PERSONAL_DASHBOARD_ADDRESS: https://openlm.example.com/personal-dashboard
general__personalDashboardAddress: https://openlm.example.com/personal-dashboard
INFRASTRUCTURE__ServerDbPrefix: openlm_operational
INFRASTRUCTURE__USESECURITY: 'true'
The identity component carries its own copies of several settings, and its copies override the values in openlm_config_generic. The chart ships them with placeholders, so set them on identity too: its database connection string with the Base64-encoded password, the database type, and the three issuer URLs.
identity:
enabled: true
configmap:
vars_list:
ConnectionString: Data Source=<sql-host>;Initial Catalog=openlm_identity;User ID=<sql-user>;Password=<base64-password>;Min Pool Size=0;Max Pool Size=100;Encrypt=True;TrustServerCertificate=True
DbType: SqlServer_SQLServerAuth
IssuerUri: https://openlm.example.com/identity
UI_BASE_HREF_URL: https://openlm.example.com/identity
UI_OAUTH_ISSUER_URL: https://openlm.example.com/identity
Check these points as you adapt the examples:
masterIngresspublishes OpenLM Platform through one Ingress object with a path for each component, and sends/apito the API gateway. On Red Hat OpenShift, leave it off and setglobal.useOpenShift: trueinstead, as described in Red Hat OpenShift.- Write every public URL with
https://. A URL withhttp://breaks single sign-on. - For node affinity and the tolerations, see Node affinity.
- The examples use SQL Server for the operational and identity databases, the default
DB_TYPEofSqlServer_SQLServerAuth. - For MariaDB or MySQL, add
DB_TYPE: MariaDBorDB_TYPE: MySQLto thevars_listofopenlm_config_generic, and set the identityDbTypetoMySql, the other value its placeholder lists.
PostgreSQL is not a valid operational or identity database type. PostgreSQL is supported only for the reporting database.
The secrets in Create the secrets set up a SQL Server reporting database. For a PostgreSQL reporting database, the chart has separate reporting settings, the sparkpgdb component and the openlm-generic-reporting-pgdb-credentials secret. Ask OpenLM for them.
Choose the components
Every component is off by default. Turn on each one you use with enabled: true:
homepageui:
enabled: true
The full on-premises set has these components:
agentactivitymanager agentactivitymanagerui agentshub agentshubui alertsservice alertsserviceui
alldbupgradeapi allocationservice anonymization anonymizationui auditservice auditserviceui
brokerhub brokerhubconnector brokerhubui cloudbroker cloudbrokerui complianceservice
complianceserviceui denialsaggregation denialservice denialsui disposabletokens donglemonitoring
donglemonitoringui dsconnector dss dssui emailnotification enduserservices featureservice
flexlmcompare homepage homepageui identity identityapi identitydiscovery identityui integrationui
kafkainitpod licenseaccesscontrol licenseaccesscontrolui licenseallocationsui licenseautomationtool
licenseconcurency licensefilecomparatormiddleware licensefilesmanagement licensefilesui
licenseharvester licensemanager licensemanagerui licenseserversui licensesui navigationservice
navigationui notificationgateway notificationui officetimecalculation openlm_config_generic
openlm_logging_config_generic openlm_telemetry_config_generic operationalapi personaldashboard
processmanager processmanagerui productservice productsserviceui projectsserviceapi
projectsserviceui pushnotification reportingdataapi samcatalog samcatalogenrichment samcatalogui
server servicenowconnectoretl servicenowcreds sessioncreator softwareassetmanagement
softwareassetmanagementui sparkmongo sparkmssql subscriptionoptimizer ticketingnotification
uiconfigurationservice uiconfigurationserviceui usageservice usageui useravailibility
usersandgroupsservice usersandgroupsserviceui vlm vlmui
Follow these rules when you pick from the set:
- Leave out the components of products your license doesn't cover. OpenLM can give you the components of each product.
servicenowconnectoretl,servicenowcreds, andintegrationuiare needed only for the ServiceNow SAM Pro integration.- Don't turn on
apigateway,mlprediction,router,catalogenrichment, orservicenowalertintegrationunless OpenLM asks you to.
Set the storage class
Three components of the on-premises set keep data on a persistent volume claim: licenseconcurency, officetimecalculation, and sparkmongo. Their claims default to the harvester storage class and the ebs.csi.aws.com provisioner annotation. Set both on each of the three components:
sparkmongo:
pvc:
storageClassName: <your-storage-class>
annotations:
storageProvisioner: <your-provisioner>
Trust a private certificate authority
If your certificate comes from a private certificate authority (CA), the components must trust it too. Add global.deploymentCerts to the values file as described in Trust a private CA inside the cluster.
Install OpenLM Platform
Install the chart with your values file, and give Helm 45 minutes to finish:
helm upgrade --install monohelm openlm_mono-<version>.tgz \
-f mono-values.yaml \
-n openlm \
--timeout 45m
The chart archive is named openlm_mono-<version>.tgz. The installation takes about 20 minutes. Most of that time goes to the kafkainitpod component, which creates the Kafka topics after the installation and again after every upgrade. Two components take long to become ready the first time because they run migrations and seeding at startup: identity (up to 15 minutes) and usersandgroupsservice (up to 60 minutes). Let them run.
Node affinity
By default, the chart schedules the main workloads only on nodes labeled openlm.com/role=main and the Spark reporting workloads only on nodes labeled openlm.com/role=spark. It also gives these workloads tolerations for openlm.com/role taints with the same values. Label your main and reporting nodes to match, as shown in the environment setup of your deployment path.
If your nodes don't carry these labels, turn node affinity and the tolerations off. Otherwise the pods never get a node and stay Pending:
global:
affinity:
enabled: false
taints:
enabled: false
The workloads then run on any node.
Verify deployment
Check the pods until all are running:
kubectl get pods -n openlm -w
If pods are crashing, run these commands:
# Check pod logs
kubectl logs <pod-name> -n openlm
# Check pod events (image pull failures, resource limits, scheduling issues)
kubectl describe pod <pod-name> -n openlm
Your domain serves the OpenLM Platform homepage.
To confirm that OpenLM Platform answers, run these requests against your FQDN. The comment on each line shows the expected status code:
H=https://openlm.example.com
curl -sk -o /dev/null -w '%{http_code}\n' $H/ # 200
curl -sk -o /dev/null -w '%{http_code}\n' $H/identity/.well-known/openid-configuration # 200
curl -sk -o /dev/null -w '%{http_code}\n' $H/api/licensemanager/bff/user # 401
curl -sk -o /dev/null -w '%{http_code}\n' $H/api/agents-hub/announce # 200
A 404 instead of 401 on the third request means that the services started before identity was healthy and run without security. Fix identity, then restart the back-end components.
Post-installation
This section covers restarting identity, creating the reporting views, uploading the license, and the Apache Superset and SMTP setup.
Restart identity once
When all pods are running, restart identity once. Components that registered after identity seeded its data otherwise keep failing secret validation. Run these commands:
kubectl -n openlm rollout restart deploy/openlm-identity
kubectl -n openlm rollout status deploy/openlm-identity
Create the reporting views
The Spark extract, transform, load (ETL) process creates the tables of the reporting database, but none of its views. Run the reporting SQL scripts from OpenLM against the reporting database, in numeric order, and skip the rollback scripts. Don't use sqlcmd -b: several scripts print expected warnings that -b turns into failures. Run this loop:
for f in $(ls 0*_openlm_sqlserver_*.sql | grep -v rollback | sort); do
sqlcmd -S <sql-host> -d openlm_reporting -U <sql-user> -C -i "$f"
done
Upload the license before you activate products
Upload your OpenLM license file first, as described in Upload a license file, and then activate the products. A product that you activate before the license is in place stays marked as not licensed for about 12 hours.
(Optional) Deploy Apache Superset
To deploy Apache Superset for reporting dashboards:
-
Create a dedicated namespace:
kubectl create namespace apache-superset -
Create the TLS secret:
kubectl create secret tls openlm-lb-cert \--key <your-domain>.key \--cert <your-domain>.crt \-n apache-supersetReplace
<your-domain>with the name of your certificate files. -
Configure
values.yaml:- Set
lbfqdnto a separate subdomain (for example,superset-openlm.yourcompany.com). - Configure
supersetNode.connectionsfor Redis and PostgreSQL. - If PostgreSQL is not available externally, turn on the bundled instance with
postgresql.enabled: true.
- Set
-
Install Apache Superset:
helm install superset superset.tgz \-f values.yaml \-n apache-superset
Configure SMTP
OpenLM Platform sends alert and notification emails through your Simple Mail Transfer Protocol (SMTP) server. In a self-hosted installation, you set the SMTP server in the OpenLM Platform UI after the installation, not in the Helm values:
- In the Navigation menu (the grid icon in the header), select Platform Administration, then Notifications, then Email Notifications.
- Enter the Sender Email, Host, and Port of your SMTP server.
- If the server requires authentication, turn on Security, and then enter the SMTP Username and SMTP Password.
- To encrypt the connection, turn on SSL. OpenLM Platform then uses STARTTLS, usually on port 587. Servers that accept only implicit TLS, usually on port 465, aren't supported.
- Add an address under Test Email Recipients.
- Select Send Sample Email. When the message is sent, you see "Email was sent, check inbox please."
- Select Save.
Ticketing notifications have their own sender account on the Ticketing Notifications page. For both pages, see Notifications.
Why does the sample email fail?
OpenLM Platform tries to send the sample email 3 times, 20 seconds apart, so a failure can take about 2 minutes to show "Unable to send emails." Then:
-
Find the email notification pod and read its log. Look for lines that start with
SMTP error on attempt.kubectl get pods -n openlm | grep -i notifkubectl logs -n openlm <email-notification-pod> -
Test the connection from inside the pod. The cluster's outbound network access can differ from your workstation's.
kubectl exec -it -n openlm <email-notification-pod> -- shnslookup <smtp-host>nc -vz <smtp-host> 587openssl s_client -starttls smtp -connect <smtp-host>:587 -crlf -
If the host name resolves but the connection times out, a firewall or an egress proxy blocks outbound SMTP from the cluster. Ask your network team to allow it. You can't fix that from OpenLM Platform.
-
If the connection works but the sample email still fails, check the port, the SSL setting, and the credentials.
Monitor the pods
Verify that all pods are healthy:
kubectl get pods -n openlm
Investigate any pods that are in a restart loop by checking logs and events.
The documentation team might draft this page using a large language model. A technical writer reviews every page and verifies it against the product before publishing it. A human makes the final decision.