diff --git a/.changeset/angry-ghosts-report.md b/.changeset/angry-ghosts-report.md new file mode 100644 index 0000000000..dfa83663a9 --- /dev/null +++ b/.changeset/angry-ghosts-report.md @@ -0,0 +1,16 @@ +--- +'@backstage/backend-common': patch +--- + +Support a `ensureExists` config option to skip ensuring a configured database exists. This allows deployment scenarios where +limited permissions are given for provisioned databases without privileges to create new databases. If set to `false`, the +database connection will not be validated prior to use which means the backend will not attempt to create the database if it +doesn't exist. You can configure this in your app-config.yaml: + +```yaml +backend: + database: + ensureExists: false +``` + +This defaults to `true` if unspecified. You can also configure this per plugin connection and will override the base option. diff --git a/packages/backend-common/config.d.ts b/packages/backend-common/config.d.ts index 4de4631982..bc5e026375 100644 --- a/packages/backend-common/config.d.ts +++ b/packages/backend-common/config.d.ts @@ -64,6 +64,11 @@ export interface Config { connection: string | object; /** Database name prefix override */ prefix?: string; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to true if unspecified. + */ + ensureExists?: boolean; /** Plugin specific database configuration and client override */ plugin?: { [pluginId: string]: { @@ -74,6 +79,11 @@ export interface Config { * @secret */ connection?: string | object; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to base config if unspecified. + */ + ensureExists?: boolean; }; }; }; diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index 55869e221d..f3a3f218b0 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -128,6 +128,14 @@ export class DatabaseManager { }; } + private getEnsureExistsConfig(pluginId: string): boolean { + const baseConfig = this.config.getOptionalBoolean('ensureExists') ?? true; + return ( + this.config.getOptionalBoolean(`${pluginPath(pluginId)}.ensureExists`) ?? + baseConfig + ); + } + /** * Provides a Knex connection plugin config by combining base and plugin config. * @@ -203,13 +211,15 @@ export class DatabaseManager { this.getConfigForPlugin(pluginId) as JsonObject, ); - const databaseName = this.getDatabaseName(pluginId); - try { - await ensureDatabaseExists(pluginConfig, databaseName); - } catch (error) { - throw new Error( - `Failed to connect to the database to make sure that '${databaseName}' exists, ${error}`, - ); + if (this.getEnsureExistsConfig(pluginId)) { + const databaseName = this.getDatabaseName(pluginId); + try { + await ensureDatabaseExists(pluginConfig, databaseName); + } catch (error) { + throw new Error( + `Failed to connect to the database to make sure that '${databaseName}' exists, ${error}`, + ); + } } return createDatabaseClient(