2

我有一个在 AWS Lambda 上运行的简单 NestJS 应用程序。我正在使用 AWS SSM 参数存储来保存数据库连接信息和凭证。当我导入 TypeORM 时,我使用已从商店中检索到的参数。

现在我只是在导入 TypeORM 的 AppModule 中检索参数。我确信有更好的方法可以做到这一点,但我不确定它会是什么。自定义提供者?某种设置服务?我不认为我当前的解决方案非常健壮,也没有很好的错误处理。

唯一的要求是我在运行时而不是在构建或部署时检索 SSM 参数。任何建议

这就是我目前正在做的事情:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ThingyModule } from 'thingy/thingy.module';
import * as awsParamStore from 'aws-param-store';

const ssmParams = awsParamStore.getParametersByPathSync('/myapp/prod', {region: (process.env['AWS_DEFAULT_REGION'] ? process.env['AWS_DEFAULT_REGION'] : 'us-east-2')}); 
const ssmMap = ssmParams.reduce(function(map, obj) {
  map[obj.Name] = obj.Value;
  return map;
}, {});

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: ssmMap['/myapp/prod/db/host'],
      port: 5432,
      username: ssmMap['/myapp/prod/db/username'],
      password: ssmMap['/myapp/prod/db/password'],
      database: 'postgres',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
    ThingyModule
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

这些参数之前已使用 AWS CLI 创建:

// aws ssm put-parameter --type String --name /myapp/prod/db/username --value postgres --region us-east-2
// aws ssm put-parameter --type String --name /myapp/prod/db/password --value supRCkrit --region us-east-2
// aws ssm put-parameter --type String --name /myapp/prod/db/host --value localhost --region us-east-2
4

1 回答 1

0

我们可以使用异步提供者来做到这一点。

来自工作项目的样本:

创建异步提供者:

import * as AWS from 'aws-sdk';
import { Parameter } from 'aws-sdk/clients/ssm';

export const ssmProvider = {
  provide: 'AWS_SSM',
  useFactory: async (): Promise<Parameter[]> => {
    const ssmClient = new AWS.SSM({
      endpoint: 'endpoint',
      region: 'us-west-2',
    });
    const result = await ssmClient
      .getParametersByPath({
        Path: '/ssm/path',
        Recursive: true,
      })
      .promise();
    return result?.Parameters;
  },
};

然后我们可以使用这个提供者来注入值。

例如在配置服务中注入 AWS SSM 参数:

export class ConfigModule {
  static register(options: ConfigModuleOptions): DynamicModule {
    return {
      global: true,
      module: ConfigModule,
      providers: [
        ssmProvider,
        {
          provide: CONFIG_OPTIONS,
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}

在配置服务构造函数中:

constructor(
    @Inject(CONFIG_OPTIONS) options: ConfigOptions,
    @Inject('AWS_SSM') awsParameters: Parameter[],
  ) {}

编辑:提供服务的 NPM 包在应用程序启动时加载 aws 参数存储参数:

参数存储服务

于 2021-08-07T00:45:15.807 回答