使用 CloudFormation(和 Lambda 轮换模板)设置 Aurora 无服务器密码轮换



AWS 对某些受支持的 RDS 引擎(包括 Amazon Aurora(提供了完全配置和即用型轮换支持(也是无服务器?(

我正在尝试使用 AWS::SecretsManager::RotationSchedule 在我的 CloudFormation 模板中设置密码轮换(请注意,这不是一个功能齐全的模板,只是一个插图(:

  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      Engine        : aurora
      EngineMode    : serverless
      EngineVersion : 5.6.10a
  Secret:
    Type: AWS::SecretsManager::Secret
    Properties:
      GenerateSecretString:
        SecretStringTemplate: '{"username": "admin"}'
        GenerateStringKey: password
        PasswordLength: 20
        ExcludeCharacters: '"@/'
  SecretTargetAttachment:
    Type: AWS::SecretsManager::SecretTargetAttachment
    Properties:
      SecretId: !Ref Secret
      TargetId: !Ref DBCluster
      TargetType: AWS::RDS::DBCluster
  SecretRotation:
    Type: AWS::SecretsManager::RotationSchedule
    Properties:
      SecretId: !Ref UserAdminSecret
      RotationLambdaARN: <ARN_GET_FROM_SERVERLESS_APPLICATION_REPOSITORY>
      RotationRules:
        AutomaticallyAfterDays: 1

但 AWS Lambda 轮换函数失败并显示以下消息:

"数据库引擎必须设置为'mysql'才能使用此轮换 lambda":键错误

看起来 AWS 提供的 AWS Lambda 轮换函数不支持 Aurora Serverless。

有没有一种简单的方法可以使用现有的 Lambda 轮换模板设置 Aurora 无服务器密钥轮换?

有什么示例可以为 Aurora Serverless 编写我自己的轮换函数吗?

PS:这个问题有点与从云形成创建极光无服务器集群有关?

RotationSchedule 资源依赖于 SecretTargetAttachment 资源。附件资源更新您的密钥字符串值以包含连接信息,例如数据库引擎、端口和终端节点。

不幸的是,CloudFormation 无法知道这两种资源之间的这种隐式依赖关系。您需要在具有附件资源的逻辑 ID 的轮换计划资源上放置一个依赖。

请参阅此示例中的轮换计划资源 - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-rotationschedule.html#aws-resource-secretsmanager-rotationschedule--examples

我没有使用无服务器,但我得到了同样的错误。

"数据库引擎必须设置为'mysql'才能使用此轮换 lambda":键错误

<小时 />

解决方案

对我来说,问题是我需要为轮换 lambda 提供子网和安全组。

CloudFormation 模板的草图如下所示(请注意传递到 lambda 中的参数(:

DBSecrets:
  Type: AWS::SecretsManager::Secret
  Properties:
    GenerateSecretString:
      SecretStringTemplate: '{"username": "XXXXXXXXXX"}'
      GenerateStringKey: password
      PasswordLength: 24
      ExcludeCharacters: '"@/'
DBSecretsRDSAttachment:
  Type: AWS::SecretsManager::SecretTargetAttachment
  Properties:
    SecretId: !Ref DBSecrets
    TargetId: !Ref RDSDatabase
    TargetType: AWS::RDS::DBInstance
SecretRotationSchedule:
  Type: AWS::SecretsManager::RotationSchedule
  DependsOn: DBSecretsRDSAttachment
  Properties:
    SecretId: !Ref DBSecrets
    RotationLambdaARN: !GetAtt MySQLRotationLambda.Outputs.RotationLambdaARN
    RotationRules:
      AutomaticallyAfterDays: 30
MySQLRotationLambda:
  Type: AWS::Serverless::Application
  Properties:
    Location:
      ApplicationId: <ARN_GET_FROM_SERVERLESS_APPLICATION_REPOSITORY>
      SemanticVersion: 1.1.0
    Parameters:
      endpoint: !Sub 'https://secretsmanager.${AWS::Region}.amazonaws.com'
      functionName: <Function Name>
      vpcSubnetIds: <Comma delimited List of VPC subnet IDs>
      vpcSecurityGroupIds: <Comma delimited List of VPC security grouop IDs>
RDSDatabase:
  Type: AWS::RDS::DBInstance
  Properties:
    MasterUsername: !Sub '{{resolve:secretsmanager:${DBSecrets}::username}}'
    MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBSecrets}::password}}'
    Engine: mysql
    DBSubnetGroupName: <Your Subnet Group>
    VPCSecurityGroups: <Your Security Group>

为什么显示此错误?

轮换 Lambda 将执行以下步骤:

  • 首先尝试使用挂起的密钥登录,如果成功,则返回
  • 现在尝试当前密码
  • 如果当前和挂起都不起作用,请尝试以前的

它无法使用挂起的密钥和当前密钥登录,然后在尝试上一个密钥时失败并出现此错误。挂起的密钥和当前密钥有效,Lambda 无法连接到数据库。上一个密钥是您最初在上面的 CloudFormation 模板中提供的密钥。

{
  "username": "XXXXXXXXXX", 
  "password": "XXXXXXXXXX"
}

AWS::SecretsManager::SecretTargetAttachment将其更改为正确的格式(对于 RDS MySQL 单用户(:

{
  "engine": "mysql",
  "host": "<required: instance host name/resolvable DNS name>",
  "username": "<required: username>",
  "password": "<required: password>",
  "dbname": "<optional: database name. If not specified, defaults to None>",
  "port": "<optional: TCP port number. If not specified, defaults to 3306>"
}

轮换 Lambda 嵌套堆栈有更多参数可供您传入,只需在 CloudFormation 控制面板中查看其模板即可。

我在设置 PostgreSQL 参数时遇到了类似的错误"password_encryption: 'scram-sha-256'"

解决方案是使用 MD5 重新创建整个 CloudFormation 堆栈。(更新值未解决错误(

此外,如果 Lambdalog 超时且没有其他错误,请将 Lambda 函数超时默认值 30 秒增加到 60 秒应该可以解决问题。

我能够使用 AWS 完全配置和即用型轮换支持为 Aurora 无服务器设置密钥轮换:aws-secrets-manager-rotation-lambdas/SecretsManagerRDSPostgreSQLRotationSingleUser/

我遇到了上面Q中提到的相同错误,我发现在我的秘密设置中缺少"engine": "postgres"设置。添加如下设置后,它开始工作

{
  "username": "XXXX",
  "password": "XXXXXXXXXX",
  "engine": "postgres",
  "host": "db.cluster-XXXX.us-XXXX-X.rds.amazonaws.com",
  "port": 5432,
  "dbClusterIdentifier": "XXXXX"
}

最新更新