> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/installation/rpm/cloud/managed-databases.md).

# Managed databases

Which managed database services OpenIAM runs against on AWS and Azure, the parameters to set before you install, and how to answer the installation's prompts.

The database is the one component of an RPM deployment worth handing to your cloud provider. OpenIAM supports it directly: the installation asks whether the database is a managed service and adapts what it does — the account permissions it requests, and the connection it builds.

**Set the parameters on this page before you run the installation.** Two of them cannot be changed while the schema migration is running, and getting them wrong means starting the database step again.

## What this covers, and how long it takes

<table><thead><tr><th width="162"></th><th></th></tr></thead><tbody><tr><td><strong>You get</strong></td><td>A managed database instance OpenIAM can install into</td></tr><tr><td><strong>Time</strong></td><td>30–45 minutes, plus the provider's provisioning time</td></tr><tr><td><strong>Hosts</strong></td><td>Your database instance, and the platform host you install from</td></tr><tr><td><strong>Downtime</strong></td><td>None</td></tr><tr><td><strong>Reversible</strong></td><td>Yes, until the installation has created the schemas</td></tr></tbody></table>

## Supported services

### AWS

<table><thead><tr><th width="243.60000610351562">Engine on RDS</th><th>For an RPM deployment</th></tr></thead><tbody><tr><td><strong>MariaDB</strong></td><td>Supported, and the smoothest path — the installation has specific handling for it</td></tr><tr><td><strong>PostgreSQL</strong></td><td>Supported. Create the schemas and accounts yourself, from the SQL the installation generates</td></tr><tr><td><strong>Oracle Standard Edition 2</strong></td><td>Supported. Create the schemas and accounts yourself, before you install</td></tr><tr><td><strong>Oracle Enterprise Edition</strong></td><td>Bring your own licence. <strong>Not tested</strong> — Standard Edition 2 is the tested and supported Oracle on RDS</td></tr><tr><td><strong>Microsoft SQL Server</strong></td><td>Run SQL Server on your own instance or on-premises rather than on RDS</td></tr></tbody></table>

Oracle Standard Edition 1 and the older Standard Edition are not usable: they cap at Oracle 11, which the schema migration tool does not support.

### Azure

<table><thead><tr><th width="265.20001220703125">Service</th><th>For an RPM deployment</th></tr></thead><tbody><tr><td><strong>Azure Database for MySQL — Flexible Server</strong></td><td>Supported, and the smoothest path — the installation has specific handling for it</td></tr><tr><td><strong>Azure Database for PostgreSQL — Flexible Server</strong></td><td>Supported. Create the schemas and accounts yourself, from the SQL the installation generates</td></tr><tr><td><strong>Azure SQL Database</strong></td><td>Create the eight databases and their accounts yourself first. The SQL the installation generates uses server-level roles that Azure SQL Database does not provide, so answer <code>n</code> when it offers to create them. SQL Server on a virtual machine or on-premises needs no such step</td></tr><tr><td><strong>Oracle</strong></td><td>Run Oracle on your own virtual machine</td></tr></tbody></table>

## Before you start

* The engine chosen. **It is fixed for the life of the deployment** — see [*Use a remote database*](/installation/rpm/rpm-single-node/use-a-remote-database.md).
* Network access from the platform hosts to the database, and from nothing else: a security group rule on AWS, a private endpoint on Azure.
* An administrative account on the instance. The installation uses it once to create the schemas and their application accounts, and does not store it.

## Set these first

{% code overflow="wrap" %}

```bash
export DB_HOST=<your database endpoint>
export DB_PORT=<3306, 5432, or 1433>
export DB_ADMIN=<the administrative account on the instance>
```

{% endcode %}

***

## Set it up

### 1. Provision the instance

Size it from the [Solution Architecture and Design Guide](/solution-architecture/deployment/sizing.md). Two settings are worth deciding now rather than later:

<table><thead><tr><th width="173.1999969482422">Setting</th><th>Recommendation</th></tr></thead><tbody><tr><td><strong>Backup retention</strong></td><td>Set it deliberately. Cloud providers default some engines to short retention or none, and this is the copy your recovery plan rests on</td></tr><tr><td><strong>High availability</strong></td><td>Your database platform's own option, set to your organisation's standard. This is a property of the database, not of the OpenIAM deployment in front of it — a three-node OpenIAM deployment makes the platform's own tiers redundant, and a single database instance behind it remains a single point of failure</td></tr></tbody></table>

### 2. Set the connection limit

**This is the setting most likely to bite later, under load rather than at install time.**

Allow **35 connections for each instance of the service bus, the workflow service and the authentication service**, plus headroom for your own tooling.

<table><thead><tr><th width="230.79998779296875">Shape</th><th>Starting point</th></tr></thead><tbody><tr><td>Single node</td><td>3 services × 35 = <strong>105</strong>, plus headroom</td></tr><tr><td>Three nodes</td><td>9 services × 35 = <strong>315</strong>, plus headroom</td></tr></tbody></table>

On RDS this is `max_connections` in the parameter group; on Azure it is a server parameter. Managed services often derive a default from instance size — check the derived value against the table rather than assuming it is generous.

**This is a provisioning figure, not a pool setting**, so treat the numbers as a floor and add headroom for your own tooling and for the platform's other services.

### 3. Set the engine parameters

**On MySQL and MariaDB, on both providers:**

<table><thead><tr><th width="228.20001220703125">Parameter</th><th width="146.99996948242188">Value</th><th>Why</th></tr></thead><tbody><tr><td><code>log_bin_trust_function_creators</code></td><td><code>1</code> on RDS, <code>ON</code> on Azure</td><td>The schema migration creates stored functions. Without this it fails partway through</td></tr></tbody></table>

**On Azure Database for MySQL, additionally** — `require_secure_transport` set to `OFF`. The platform pins its own connection to TLS 1.2 when you tell the installation the database is a managed service, in step 5.

**On PostgreSQL, on both providers** — `max_connections` from step 2. On RDS this takes effect at the next restart, so set it before you install.

**Character sets are set differently on the two providers.** OpenIAM's schemas are UTF-8:

<table><thead><tr><th width="132.39999389648438">Provider</th><th>How</th></tr></thead><tbody><tr><td><strong>RDS</strong></td><td>Set <code>character_set_server</code> and <code>character_set_client</code> to <code>utf8</code> in the parameter group, or <code>client_encoding</code> to <code>utf8</code> on PostgreSQL</td></tr><tr><td><strong>Azure</strong></td><td>Set it per database when the eight are created: charset <code>utf8</code> with collation <code>utf8_general_ci</code> on MySQL, <code>UTF8</code> with <code>en_US.utf8</code> on PostgreSQL</td></tr></tbody></table>

**On Azure SQL Database**, the collation is set when the database is created and cannot be changed afterwards. Use `SQL_Latin1_General_CP1_CI_AS` unless you have a specific reason not to.

**Apply the parameter group and confirm it is in effect before continuing.** On RDS a pending-reboot parameter is not an applied one.

### 4. Prepare the administrative account

The installation creates eight schemas and an application account for each.

**On MySQL, MariaDB and PostgreSQL**, the instance's master account is enough. A managed service does not grant its master account full superuser rights, so the installation requests an explicit set of privileges rather than `ALL` — you do not need to do anything, but this is why the account it creates looks more specific than on a self-managed server.

**On Azure SQL Database**, the account must:

* **not** be a Windows-authenticated account,
* be able to create a database,
* be able to create and modify tables, indexes, views and procedures,
* be able to run schema migrations.

**On Oracle**, create the schemas and their accounts yourself before you install. The installation does not offer to create them and asks only for the SID or the service name.

RDS returns the Oracle database name — the SID — in capitals. Create it in capitals so your own records match, and note that if you manage the instance with Terraform, a lower-case SID makes every plan want to replace it.

### 5. Answer the installation's prompts

During `openiam-cli init`, or the cluster build:

| Prompt                                                    | Answer                                                                                                                                                                                            |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *Would you like to install MariaDB RDBMS locally?*        | **`n`**                                                                                                                                                                                           |
| Engine                                                    | Type it — `mysql`, `postgres`, `mssql` or `oracle`. The prompt offers `mysql`; do not press Enter past it                                                                                         |
| *Do you want to initialize OpenIAM Schema and Users?*     | **`y`** on MySQL, MariaDB and PostgreSQL, if the schemas do not exist yet. It then asks for the administrative account from step 4. **`n`** on Azure SQL Database, where you create them yourself |
| *Are you going to use external DB service like AWS RDS…?* | **`y` on MySQL and MariaDB only** — see below                                                                                                                                                     |
| Schema names                                              | **Use the defaults on MySQL and MariaDB.** On PostgreSQL and SQL Server, custom names are honoured                                                                                                |
| Host and port                                             | Your instance's endpoint, **asked once per schema — eight times**                                                                                                                                 |

**The managed-service prompt applies to MySQL and MariaDB.** Answering `y` there changes two things, which is why it matters:

* the initialisation SQL grants a **narrower, explicit privilege set** instead of `GRANT ALL`, which is what a managed service's administrative account can actually issue;
* **TLS 1.2 is pinned** on the platform's connection to the database.

On PostgreSQL, SQL Server and Oracle, answer **`n`** — the managed-service handling exists for the MySQL/MariaDB path, and those engines take the manual route in step 6 instead. Where you create the schemas yourself on MySQL or MariaDB, you are not offered the question at all; set the TLS parameter on the connection by hand afterwards.

**On MySQL and MariaDB, keep the default schema names.** The generated runtime configuration uses them, so custom names migrate cleanly and then fail when the platform starts.

**Set all sixteen host and port values in `env.conf` before you start** and each prompt arrives pre-filled with the right answer. You still press Enter through them, but you cannot mistype an endpoint — [*Use a remote database*](/installation/rpm/rpm-single-node/use-a-remote-database.md) has the list.

### 6. Run the initialisation SQL where the installation asks you to

The installation generates the statements that create the eight schemas and their accounts. Who runs them depends on the shape and the engine:

<table><thead><tr><th width="169.8000030517578"></th><th>MySQL and MariaDB</th><th>PostgreSQL and SQL Server</th></tr></thead><tbody><tr><td><strong>Single node</strong></td><td>The installation applies them</td><td>It writes <code>/tmp/init.sql</code> and pauses for you</td></tr><tr><td><strong>Three nodes</strong></td><td>It writes <code>/tmp/init.sql</code> and pauses for you</td><td>It writes <code>/tmp/init.sql</code> and pauses for you</td></tr></tbody></table>

**On a three-node build the installation always pauses**, on every engine. Run `/tmp/init.sql` against your instance with the administrative account from step 4, then press Enter to continue.

**On Oracle**, nothing is generated — create the schemas and accounts before you begin.

[*Use a remote database*](/installation/rpm/rpm-single-node/use-a-remote-database.md) covers the sequence in full.

***

## Verify it

**Before installing**, from the platform host:

{% code overflow="wrap" %}

```bash
# MySQL or MariaDB
mysql -h "$DB_HOST" -u "$DB_ADMIN" -p -e "SELECT VERSION(); SHOW VARIABLES LIKE 'log_bin_trust_function_creators'; SHOW VARIABLES LIKE 'max_connections';"
```

{% endcode %}

{% code overflow="wrap" %}

```bash
# PostgreSQL
psql -h "$DB_HOST" -U "$DB_ADMIN" -c "SELECT version(); SHOW client_encoding; SHOW max_connections;"
```

{% endcode %}

**Expected:** a version, the parameters from step 3 at their required values, and a connection limit at or above the figure from step 2.

**After installing:**

{% code overflow="wrap" %}

```bash
# MySQL or MariaDB
mysql -h "$DB_HOST" -u "$DB_ADMIN" -p -e "SHOW DATABASES;"
```

{% endcode %}

**Expected:** all eight schemas — `openiam`, `activiti`, `groovy`, `auditlog`, `batchtasks`, `pbac`, `certification` and `privacy`.

## Backups

**The provider's automated backup covers the database. It does not cover the deployment.** Two other things are needed for a restore, and neither is in the database:

* **The secret store's data**, taken as a snapshot,
* **the unseal keys and root token**, which are not held on any host.

[*Back up and restore*](/installation/rpm/rpm-single-node/back-up-and-restore.md) has the full set and the restore order. Enable point-in-time recovery on the instance, and keep the retention period aligned with the rest of that set — a database you can restore to a moment the secret store snapshot does not match is not a recovery plan.

## If it goes wrong

| What you see                                                                                             | What it means                                                                     | What to do                                                                                                      |
| -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| The schema migration fails partway on MySQL or MariaDB                                                   | `log_bin_trust_function_creators` is not set                                      | Set it, confirm it is applied, and run the database step again                                                  |
| A permissions error creating schemas or accounts on MySQL or MariaDB                                     | The managed-service prompt was answered `n`, so the SQL asked for `GRANT ALL`     | Re-run the database step and answer `y` — the privileges requested are different                                |
| The database step stops immediately after the managed-service prompt on PostgreSQL, SQL Server or Oracle | The prompt was answered `y` on an engine it does not apply to                     | Re-run the database step and answer `n`                                                                         |
| `sp_addsrvrolemember` or `sysadmin` errors on Azure SQL Database                                         | The generated SQL uses server-level roles Azure SQL Database does not provide     | Create the eight databases and their accounts yourself, and answer `n` to *initialize OpenIAM Schema and Users* |
| The connection is refused                                                                                | Security group, private endpoint, or the DNS zone is not linked                   | Test with the engine's own client from the platform host before looking at OpenIAM                              |
| TLS or protocol errors on Azure MySQL                                                                    | `require_secure_transport` is `ON`                                                | Set it to `OFF`; the platform brings its own TLS 1.2                                                            |
| Connection-pool exhaustion under load                                                                    | `max_connections` is below the figure in step 2                                   | Raise it, restart if the engine requires it, and restart the platform                                           |
| The migration fails on the second schema                                                                 | The host was answered once and the remaining seven kept their `localhost` default | Set the sixteen `env.conf` values, or answer all eight prompts, and run the database step again                 |
| The platform starts but cannot reach a schema, on MySQL or MariaDB                                       | A non-default schema name was used                                                | The generated runtime configuration uses the default names; rebuild with the defaults                           |
| A Terraform plan wants to replace the Oracle RDS instance every time                                     | The SID was created in lower case, and RDS returns it capitalised                 | Recreate with a capitalised SID, or normalise the case in your configuration                                    |

## What this procedure does not cover

Sizing the instance, and your organisation's database standards for encryption at rest, key management, auditing and access review. The [Solution Architecture and Design Guide](/solution-architecture/deployment/sizing.md) covers sizing.

## Related

* [*Use a remote database*](/installation/rpm/rpm-single-node/use-a-remote-database.md) — the engine-by-engine detail
* [*AWS*](/installation/rpm/cloud/aws.md) and [*Azure*](/installation/rpm/cloud/azure.md) — provisioning the instances
* [*Back up and restore*](/installation/rpm/rpm-single-node/back-up-and-restore.md)
* [*System requirements*](/installation/system-requirements.md) — supported platforms and versions

*Applies to OpenIAM 2026.8.1.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/installation/rpm/cloud/managed-databases.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
