Registering an existing database
Audience: operator · Profile:
demo· Read this when: you already run a database, in a cloud or on-premises, and want the dashboard to manage access to it.
Part of Databases.
Registration records a database the dashboard didn't create, so it can be a
Configuration Management target. It is the database sibling of
registering a Kubernetes cluster from a kubeconfig (Kubernetes): the
dashboard builds nothing, changes nothing, and stores no credential. cloud = local is
the on-premises case.
The registerable set is deliberately wider than the provisionable one — provisioning
needs a Terraform module, registering needs only somewhere to reach. Any of local,
aws, azure, gcp or oci may be registered, and engines are postgres / mysql /
sqlserver / oracle / mongodb, and Configuration Management runs cover all five — the
ansible-cloud runner image carries python-oracledb (thin mode) and community.mongodb
over pymongo; see the database samples.
No Ansible runner resolves for oci at all, so an OCI row registers and lists but can't be
a run target.
How to register. Databases page → Register existing, or
POST /api/databases/register (permission cloud_database:write). To register several
at once from what Password Safe already knows, use
Import from Password Safe instead. The button only
renders when the Password Safe integration is on (password_safe_enabled), because the admin
login has to be a Password Safe managed account. The cloud_database_enabled feature
toggle gates registration and provisioning alike.
| Field | Notes |
|---|---|
| Engine | postgres / mysql / sqlserver / oracle / mongodb |
| Location | local (on-premises) / aws / azure / gcp / oci |
| Host | Required — it is how the runner reaches the database. One row per engine + host; a duplicate is refused. |
| Port | Optional; defaults per engine (5432 / 3306 / 1433 / 1521 / 27017). |
| Database name | Optional. SQL Server falls back to master. |
| Admin account | A Password Safe managed system + account, looked up live by host — the same lookup the Configuration Management run form uses. Onboard the database in Password Safe first; the list is empty until you do. |
The credential is never stored. The row keeps the managed system id, account id and account name — nothing else. At run time the dashboard checks the credential out and lets the request expire on its duration rather than checking it back in, matching what the inline runners already do for VMs. Contrast the provisioned path, which reads its admin credential from the provisioning job's Terraform variables and the encrypted config store.
The account must be requestable by the dashboard's Password Safe API identity — onboarding it is necessary but not sufficient. The checkout goes through a Password Safe request, so that identity's group needs the Requestor role, with an access policy granting View (API-only is fine), on a Smart Rule containing the account. Without it the row registers and lists happily and the run fails in the worker with
Password Safe checkout failed for database …: 4031, statuscode: 403. Two things make this easy to misdiagnose: a database Smart Rule needs its own grant — the ones covering Linux/SSM/Waagent accounts do not extend to it, so the VM path working tells you nothing — and Smart Rule membership is recomputed on a schedule, so a freshly created account is not requestable the instant it exists. Check withps-cli access-policies test -s-id <system> -a-id <account>; an empty list means no policy applies yet.The import catches this early. Because Import from Password Safe sources its account list from the requestable accounts, a managed system showing no requestable account there is this same problem, surfaced before the row is ever created rather than hours later in a worker log. If a database you know is onboarded shows that reason, it is the Requestor role or the Smart Rule — not the onboarding.
Where the run executes follows the database's location, exactly as it does for clusters — an on-premises database runs in a sibling container on the dashboard host, because nothing in a cloud has a route to your LAN; a cloud-hosted one runs on that cloud's transient in-subnet runner. See Ansible → Kubernetes-cluster and database targets.
Every runner takes the just-in-time credential, AWS and GCP included. A database run is
a localhost play, and its connection variables ride the runner's inline environment
channel as CONN_VARS_B64 — the ECS task override env, ACI secure_value, the Cloud Run
env, or a 0600 --env-file locally — decoded to a 0600 file and passed as -e @….
Nothing needs to pre-exist in a cloud secret store, so the ephemeral-store opt-in that
governs a VM SSH managed-account run (ansible_cloud_ephemeral_secrets_enabled, see
Secrets Management) does not apply
here. That opt-in exists only because the SSH path injects named/become secrets by
reference (valueFrom) on ECS and Cloud Run; the database path never does.
What registration does not give you. A registered row has no Terraform state and no provisioning job, so none of the three layers apply: no PRA protocol tunnel, no Layer-2 Password Safe onboarding of a rotated DB user, and no Layer-3 Entitle integration (Entitle onboarding reads the provisioning job's admin credential, which such a row doesn't have). Nothing is created in the cloud, and no gateway host is brokered on its behalf.
Delete deregisters. Removing a registered row drops it from the inventory and leaves the database running — the dashboard holds no Terraform state for someone else's database, and destroying it would be the wrong verb. The row's action button says Deregister rather than Decommission, and the confirm dialog says the database itself is untouched. The reverse is refused too: a provisioned database is decommissioned, never deregistered.