Dynamic database Environment Variables

System Information
  • Strapi Version: 3.4.1
  • Operating System: Linux 18.08
  • Database: MySQL
  • Node Version: v12.20.1
  • NPM Version: 6.14.10
  • Yarn Version: 1.22.10

We’re using Hashicorp vault to manage environment variables. I have bootstrap function defined to update env variables as below.

bootstrap.js

const vault = require("node-vault");

const updateEnvFromVault = async () => {
  const { USE_VAULT, VAULT_ENDPOINT, VAULT_TOKEN, VAULT_PATH } = process.env;
  if (USE_VAULT !== "true") return;

  console.log("Updating credentials from vault");

  const options = {
    apiVersion: "v1",
    endpoint: VAULT_ENDPOINT,
    token: VAULT_TOKEN,
  };

  const response = await vault(options).read(VAULT_PATH);
  const data = response.data || {}
  
  if (Object.keys(data).length) {
    Object.keys(data).forEach((key) => {
      process.env[key] = data[key];
    });
  }

};

module.exports = () => {
  return updateEnvFromVault();
};

This enables us to fetch variables and update them in before the server starts. However this doesn’t work with database.js. Is database process run before bootstrap.js?

Any workarounds / suggestions?

I assume you are also using Terraform? Or something like Ansible to deploy?

Not really. It’s deployed on Kubernetes with a Jenkins CI / CD Pipeline in place.

You might be able to find a node package to pull from vault but can’t say I ever tried. Since I trust my infrastructure, the variables are written to a secured .env file when I use Ansible to deploy the application.

If you do find a working option though I would love to see it, massive fan of Hashicorp Consul and Vault

Hey @DMehaffy So the issue is not pulling env from vault. the actual issue is making the database.js use adapted env variables. Is there anyway we can make database.js to start after a promise has been resolved?

Most likely not in this case, you would likely need to use the bootstrap function to set the variables at the initial boot as before the application starts there is migration level that happens that checks the database.

I would have to do some testing, you might be able to perform some logic outside the exports object of the database.js file however I’m not sure if that will throw errors on boot since I believe it’s designed to pull from environment variables.


The alternative would be to have a custom start script that pulls the environment variables and sets them before Strapi even starts like a typical node server.js file

Thanks for the suggestion, that’s what I ended up doing @DMehaffy

I created a custom start_app.js file as below

function updateEnvFromVault(){
/* update logic... */
}

async function main(){
   await updateEnvFromVault()
   strapi().start();
}

main()
1 Like