Nest JS 微服务 (lambda) 中的 AWS Secrets 管理器定期失败
AWS Secrets manager in Nest JS microservice (lambda) fails periodically
我有一个用 NestJS 的微服务制作的 lambda 函数。它使用数据库连接,我正在使用秘密服务为其获取连接详细信息。
这是我的应用程序模块:
@Module({
imports: [
ConfigModule,
TypeOrmModule.forRootAsync({
useClass: SecretsService,
inject: [],
imports: [ConfigModule],
}),
PropertyModule,
],
})
export class AppModule {}
这是特勤局(ConfigModule
的一部分):
import { Injectable } from '@nestjs/common';
import { SecretsManager } from 'aws-sdk';
import { GetSecretValueResponse } from 'aws-sdk/clients/secretsmanager';
import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions';
@Injectable()
export class SecretsService /* */ {
private secretsManager: SecretsManager;
constructor() {
this.secretsManager = new SecretsManager();
}
async createTypeOrmOptions(): Promise<MysqlConnectionOptions> {
console.log('before getting secret');
const { SecretString }: GetSecretValueResponse =
await this.secretsManager.getSecretValue({ SecretId: 'rds/prod' }).promise();
const secret = JSON.parse(SecretString);
console.log('after getting a secret', SecretString);
return {
/* database config */
};
}
}
事实证明,代码并不总是到达“获得秘密之后”的部分。以下是部分案例
我更改了代码并部署了新版本的 lambda,但它一直挂在“获取秘密之前”。我等了 5 分钟,然后再次触发该功能,然后我等了 10 分钟。
结果相同。
然后我等了大约 20 分钟,请求就通过了。之后,我可以连续多次触发相同的功能,每次都看到“获得秘密后”。
所以它实际上不是周期性失败,而是周期性工作。似乎有某种限制 and/or 缓存,但我没有在代码中看到它。
请帮我解决这个问题。我怎样才能每次都得到我的秘密?
从 AWS Lambda 访问 Secrets Manager 时,您应该使用客户端缓存和 backoff/retry。
有关更多信息,请参阅 Secrets Manager Best Practices。
lambda 属于三个子网,其中一个是 public,另外两个是私有的。最后,它只适用于一个子网,因为其余的都是我们的集群架构师配置不当。
我花了很长时间才找到问题的根源。仔细检查您的网络是如何配置的。
我有一个用 NestJS 的微服务制作的 lambda 函数。它使用数据库连接,我正在使用秘密服务为其获取连接详细信息。
这是我的应用程序模块:
@Module({
imports: [
ConfigModule,
TypeOrmModule.forRootAsync({
useClass: SecretsService,
inject: [],
imports: [ConfigModule],
}),
PropertyModule,
],
})
export class AppModule {}
这是特勤局(ConfigModule
的一部分):
import { Injectable } from '@nestjs/common';
import { SecretsManager } from 'aws-sdk';
import { GetSecretValueResponse } from 'aws-sdk/clients/secretsmanager';
import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions';
@Injectable()
export class SecretsService /* */ {
private secretsManager: SecretsManager;
constructor() {
this.secretsManager = new SecretsManager();
}
async createTypeOrmOptions(): Promise<MysqlConnectionOptions> {
console.log('before getting secret');
const { SecretString }: GetSecretValueResponse =
await this.secretsManager.getSecretValue({ SecretId: 'rds/prod' }).promise();
const secret = JSON.parse(SecretString);
console.log('after getting a secret', SecretString);
return {
/* database config */
};
}
}
事实证明,代码并不总是到达“获得秘密之后”的部分。以下是部分案例
我更改了代码并部署了新版本的 lambda,但它一直挂在“获取秘密之前”。我等了 5 分钟,然后再次触发该功能,然后我等了 10 分钟。 结果相同。
然后我等了大约 20 分钟,请求就通过了。之后,我可以连续多次触发相同的功能,每次都看到“获得秘密后”。
所以它实际上不是周期性失败,而是周期性工作。似乎有某种限制 and/or 缓存,但我没有在代码中看到它。
请帮我解决这个问题。我怎样才能每次都得到我的秘密?
从 AWS Lambda 访问 Secrets Manager 时,您应该使用客户端缓存和 backoff/retry。
有关更多信息,请参阅 Secrets Manager Best Practices。
lambda 属于三个子网,其中一个是 public,另外两个是私有的。最后,它只适用于一个子网,因为其余的都是我们的集群架构师配置不当。
我花了很长时间才找到问题的根源。仔细检查您的网络是如何配置的。