javascriptasynchronoussequelize.jssequelize-cli

Asynchronously load configuration for Sequelize CLI


I am using Sequelize CLI to run migrations against out database and I have the following .sequelizerc file

// .sequelizerc
const path = require('path');

module.exports = {
  "config": path.resolve('src', 'database', 'config.js'),
  "models-path": path.resolve('src', 'models'),
  "seeders-path": path.resolve('src', 'database', 'seeders'),
  "migrations-path": path.resolve('src',  'database', 'migrations'),
};

The credentials for our database are kept in a secrets manager so they can be easily rotated and never stored within our repository or someone's computer. Thus, our config.js file looks like:

// src/database/config.js
const { AsyncObtainDBCredentials } = require("../utilities");
async function setupDBCreds() {
  const dbConfig = await AsyncObtainDBCredentials();
  return dbConfig;
}
module.export = setupDBCreds(); // exports a promise and does not work

Sequelize CLI is expecting a configuration JSON like

const dotenv = require('dotenv')
dotenv.config()

const dbConfig = {
    host: process.env.DB_HOST ?? 'localhost',
    username: process.env.DB_USER ?? 'postgres',
    port: process.env.DB_PORT ?? '5432',
    database: process.env.DB_NAME ?? 'myDBName',
    password: process.env.DB_PASSWORD ?? 'SuperSecretPasswd',
    dialect: "postgres"
};

module.exports = dbConfig;

Is there a way to make this work so we can avoid users having write credentials in to an .env file?


Solution

  • This is an old question, but I happened across it while trying to figure out how to pull the connection info out of Secret Manager. I got it to work by doing something like this:

    const getSettings = async() => {
      const client = new SecretsManagerClient({
        region: AWS_REGION
      });
    
      const response = await client.send(
        new GetSecretValueCommand({
          SecretId: AWS_SECRET
        }),
      );
      const settings = JSON.parse(response.SecretString);
    
      return {
        username: settings.DATABASE_USERNAME,
        password: settings.DATABASE_PASSWORD,
        database: settings.DATABASE_NAME,
        host: settings.DATABASE_HOST,
        port: settings.DATABASE_PORT,
        dialect: 'postgres',
      };
    };
    
    module.exports = async() => ({
      development: {
        // local settings
      },
      production: await getSettings(),
    });

    The key is you can use async() in your module.exports.