使用dotnet核心从Lambda的AWS Secrets访问Db连接参数

问题描述

我正在尝试使用API​​网关和lambda函数开发一个AWS Serverless API项目。 我正在使用由AWS提供的SAM模型以及Visual Studio的AWSless Serverless项目模板,其中也包括cloudformation模板。

出于安全原因,我不想在配置文件中存储数据库信息, 我想知道如何在运行时使用AWS Secrets Manager在lambda函数获取数据库连接信息。

代码示例将提供很大的帮助,因为我只能使用Boto3,.net核心示例或无服务器API的解释找到python示例,而我想Internet上没有lmbda的解释。 任何帮助或线索,将不胜感激。

谢谢。

解决方法

[方法1]

您可以按以下方式在Cloudformation中使用dynamic referencing

  • 在Secret Manager中创建数据库凭据。
  • (可选)在通过Cloudformation创建数据库时将这些凭据传递给数据库。
  • 将这些凭据传递到Cloudformation中的Lambda函数的environment variables
  • 在Lambda代码中,简单地读取引用的环境变量:
Console.WriteLine(Environment.GetEnvironmentVariable("DB_USERNAME"));

使用DB进行动态引用的示例:

{
    "MyRDSInstance": {
        "Type": "AWS::RDS::DBInstance","Properties": {
            "DBName": "MyRDSInstance","AllocatedStorage": "20","DBInstanceClass": "db.t2.micro","Engine": "mysql","MasterUsername": "{{resolve:secretsmanager:MyRDSSecret:SecretString:username}}","MasterUserPassword": "{{resolve:secretsmanager:MyRDSSecret:SecretString:password}}"
        }
    }
}

这种方法很简单,但需要重新部署凭据更新。

[方法2]

或者,您可以在环境变量中传递Secret Manager变量名称,然后使用这些名称来检索值。

SecretsManager添加nuget包。编写查询类:

public class SecretManager : ISecretManager
{
  public string Get(string secretName)
  {
    var config = new AmazonSecretsManagerConfig {RegionEndpoint = RegionEndpoint.EUWest1};
    var client = new AmazonSecretsManagerClient(config);

    var request = new GetSecretValueRequest
    {
      SecretId = secretName
    };

    GetSecretValueResponse response = null;
    try
    {
      response = Task.Run(async () => await client.GetSecretValueAsync(request)).Result;
    }
    catch (ResourceNotFoundException)
    {
      Console.WriteLine("The requested secret " + secretName + " was not found");
    }
    catch (InvalidRequestException e)
    {
      Console.WriteLine("The request was invalid due to: " + e.Message);
    }
    catch (InvalidParameterException e)
    {
      Console.WriteLine("The request had invalid params: " + e.Message);
    }

    return response?.SecretString;
  }
}

使用以下类:

var secretManager = new SecretManager();
var mongoDb = JsonConvert.DeserializeObject<MongoConnectionString>(secretManager.Get(Environment.GetEnvironmentVariable("SECRET_NAME")));
var database = new MongoClient(mongoDb.ConnectionString);

有关更多详细信息,请参阅this article