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 :
- Can we and if yes how to pass the connection parameters from another service (in my case from the AwsParameterStore)
- If this is not doable is it ok if i store the database credentials in the gitlab ci/cd variables and call it when runing the pipeline ?
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
CodePudding user response:
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
}