Maybe this is a genral javascript question but i am strugling to find a way to get the datasource connection option from aws parameter store instead of storing them into enviroment variables, and maybe what i want to achieve is impossible but i want to get more expertise advises here.
This is my datasource class
let options = {
type: "mssql" as any,
host: AwsParameterStore.getParameter("DATABASE_HOST").then(
async (secretKey) => {
return secretKey;
}
),
database: process.env.DATABASE_NAME,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
options: { encrypt: false },
synchronize: false
};
export const VcsDatabase = new DataSource((options = options));
and this is my AwsParameterStore class
@Injectable()
export class AwsParameterStore {
constructor(private eventLogger: LoggingService) {}
static async getParameter(parameterName: string): Promise<any> {
let ssm = new SSM({ region: "eu-west-1" });
let options = {
Name: parameterName
};
let parameter = ssm.getParameter(options).promise();
return parameter.then((response) => {
let token: string = response.Parameter.Value;
return token;
});
}
}
Obviously this does not work because i am trying to pass the host value as promise when apparently typorm datasource only accept it as a string based on the error i am getting
connection error TypeError: The "config.server" property is required and must be of type string.
So i have 2 questions :
I am more seeking to secure the credentials and as far as i know there in no other better way then storing those in ssm and retrieve it at runtime
You need to await
the promise or put things into a then
clause so it can finish before options gets passed in. You can then export an async
function which will need to be await
ed where you use it. It could look something like this
async function provideDataSource() {
let options = {
type: "mssql" as any,
host: await AwsParameterStore.getParameter("DATABASE_HOST"),
database: process.env.DATABASE_NAME,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
options: { encrypt: false },
synchronize: false
};
return new DataSource(options); // I don't think your code here was syntactically correct
}
export const provideVcsDatabase = provideDataSource;
and then you would import it and use it like
const db = await provideVcsDatabase();
or
provideVcsDatabase().then(db => {
// whatever
}