0

I am trying to retrieve secrets from an Azure Key Vault. I have this module called retrieveSecrets.js that accepts a secretName to look up the value and return it

const { SecretClient } = require('@azure/keyvault-secrets')
const {
  DefaultAzureCredential,
  ManagedIdentityCredential,
} = require('@azure/identity')

module.exports = async (secretName) => {
  const credential = new DefaultAzureCredential()
  const vaultName = 'some-vault-name'
  const vaultURL = `https://${vaultName}.vault.azure.net/`
  const client = new SecretClient(vaultURL, credential)
  const secretValue = await client.getSecret(secretName)
  return secretValue.value
}

I have a queue.js file that creates the queue in redis which is called when the nodejs server starts up but is failing to connect to redis as the queue attempts to create before the redis secrets are retrieved from the key vault

const { watchCircleProcess } = require('./watch-circle-queue-consumer')
const retrieveSecrets = require('../cloud/azure/retrieveSecrets')
const Queue = require('bull')

const rdHost = retrieveSecrets('REDISHOST')
const rdPort = retrieveSecrets('REDISPORT')
const rdPass = retrieveSecrets('REDISPASSWORD')

const Queue = new Queue('queue-name', {redis: {port: rdPort, host: rdHost, password: rdPass})
Queue.process(watchCircleProcess)

module.exports = {
  Queue
}

I want to get the secret keys from the vault and then once that has been resolved I want them accessible to the new queue call. how can I stop the new queue call and the process line from being called until the port, host, and password have been retrieved? I have tried wrapping it into a promise but then the Queue isn't available to the module exports. Suggestions, help code examples. I can't seem to find a solution that doesn't run the queue build before the secrets have been resolved

nerdherdwa
  • 19
  • 1
  • 5

1 Answers1

0
  • Here I have a work around where instead of importing required secrets set the secrets as environment variables and then you can the modules one after the other.

  • here is my Keyvault.js which is just retrieving the secret and setting up the value of the secret to the environment variable. Keyvault.js : -

const { DefaultAzureCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");

  

const  vaultName = "<KEYVAULT NAME>";

const  url = `https://${vaultName}.vault.azure.net`;

const  secretName = "MySecretName";

const  tests = async  function() {

    const  credential = new  DefaultAzureCredential();
    
    const  client = new  SecretClient(url, credential);
    
    const  latestSecret = await  client.getSecret(secretName);
    
    process.env.SecretFromAzure = latestSecret.value;
}

module.exports = tests;
  • The following is a different module which is called redis.js it just prints the enviorment variable set by the keyvault.js

redis.js : -

const  tests = function() {
    console.log("redis.js is executing ");
    console.log("Secret from keyvault ", process.env.SecretFromAzure);
}

module.exports = tests;
  • Now here is the main part where we execute the keyvault.js before redis,js using the .then() function where we pass the redis as an argument to it so that it will execute after keyvault

index.js :-

const  key = require('./keyvault');
const  redis = require('./redis');
key().then(redis);

Here I have changed the secret value twice that's why executing it twice.

enter image description here

Mohit Ganorkar
  • 1,917
  • 2
  • 6
  • 11