новичок в NestJS и столкнулся с проблемой. Для наших развертываний нам необходимо получить нашу конфигурацию из AWS Parameter Store (Systems Manager), включая строку подключения к базе данных. У меня есть ConfigModule и ConfigService, который извлекает все записи хранилища параметров для моей среды на основе пути хранилища параметров:
Вот мой сервис конфигурации:
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import * as AWS from 'aws-sdk';
export class ConfigService {
private readonly envConfig: { [key: string]: string };
private awsParamStoreEntries: { [key: string]: string }[];
constructor(awsParamStorePath: string, filePath: string) {
this.envConfig = dotenv.parse(fs.readFileSync(filePath));
this.loadAwsParameterStoreEntries(awsParamStorePath).then((data) => {
this.awsParamStoreEntries = data;
});
}
loadAwsParameterStoreEntries(pathPrefix: string) {
const credentials = new AWS.SharedIniFileCredentials({ profile: 'grasshopper-parameter' });
AWS.config.credentials = credentials;
const ssm = new AWS.SSM({ region: 'us-west-2' });
var params: { [key: string]: string }[] = [];
return getParams({
Path: '/app/v3/development/',
Recursive: true,
WithDecryption: true,
MaxResults: 10,
}).then(() => {
return params;
});
function getParams(options) {
return new Promise((resolve, reject) => {
ssm.getParametersByPath(options, processParams(options, (err, data) => {
if (err) {
return reject(err);
}
resolve(data);
}));
});
}
function processParams(options, cb) {
return function (err, data) {
if (err) {
return cb(err)
};
data.Parameters.forEach(element => {
let key = element.Name.split('/').join(':')
params.push({ key: key, value: element.Value });
});
if (data.NextToken) {
const nextOptions = Object.assign({}, options);
nextOptions.NextToken = data.NextToken;
return ssm.getParametersByPath(nextOptions, processParams(options, cb));
}
return cb(null);
};
}
}
get(key: string): string {
return this.envConfig[key];
}
getParamStoreValue(key: string): string {
return this.awsParamStoreEntries.find(element => element.key === key)['value'];
}
getDatabase(): string {
return this.awsParamStoreEntries.find(element => element.key === 'ConnectionStrings:CoreDb')['value'];
}
}
Вот основной блок объявления модуля приложения:
@Module({
imports: [ConfigModule, TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
url: configService.getDatabase()
}),
inject: [ConfigService]
}),
CoreModule, AuthModule],
controllers: [AppController],
providers: [AppService],
})
Как вы можете видеть, я говорю TypeORM вызвать метод getDatabase () в ConfigService , но проблема в том, что для загрузки записей хранилища параметров требуется около 3-4 секунд, так что "undefined «ошибка возникает из-за того, что this.awsParamStoreEntries по-прежнему не определен, когда TypeORM пытается загрузить строку подключения.
Проверили в Интернете, чтобы убедиться, что это было сделано, но не смогли найти ничего, что использует хранилище параметров NestJS / TypeORM / AWS таким образом. Существует также (без ответа) вопрос здесь, на StackOverflow.
Спасибо!