使用 CloudFormation(和 Lambda 轮换模板)的 Aurora Serverless 密码轮换设置

Posted

技术标签:

【中文标题】使用 CloudFormation(和 Lambda 轮换模板)的 Aurora Serverless 密码轮换设置【英文标题】:Aurora Serverless password rotation setup using CloudFormation (and Lambda rotation templates) 【发布时间】:2019-12-14 23:05:04 【问题描述】:

AWS 为 some supported RDS engines 提供完全配置且随时可用的轮换支持,包括 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": KeyError

AWS 提供的 AWS Lambda 轮换功能似乎不支持 Aurora Serverless。

有没有使用existing Lambda rotation templates 设置 Aurora Serverless 密钥轮换的简单方法?

有任何示例可用于为 Aurora Serverless 编写我自己的轮换函数吗?

PS:这个问题和Creating an Aurora Serverless Cluster from cloudformation?有点关系

【问题讨论】:

【参考方案1】:

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

不幸的是,CloudFormation 无法了解两种资源之间的这种隐式依赖关系。您需要将DependsOn 与附件资源的逻辑ID 放在RotationSchedule 资源上。

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

【讨论】:

我不知道为什么你会得到 +1 这不是在回答关于 Aurora Serverless 的问题 你所拥有的是正确的。将此行添加到您的 RotationSchedule 资源 - “DependsOn: SecretTargetAttachment” @YvesM。您好我现在也有类似的问题,我的数据库引擎也是Aurora MySQL,请问您解决了这个问题吗,可以分享一下函数模板吗?提前致谢。 @Cecilia 我还没有卖掉这个问题,我的密码轮换被禁用了。但我会在当天进行调查以制定解决方案。如果您找到现成的解决方案,请告诉我 @YvesM.我其实找到了一个潜在的解决方案,目前正在破解它,如果你也在使用Aurora MySQL引擎,它应该可以工作,我们可以使用MySQL db的旋转函数模板,所以我们可以不使用 CloudFormation,而是手动创建一个函数(查看此模板github.com/aws-samples/aws-secrets-manager-rotation-lambdas/…),然后告诉 Secretc Manager 调用此函数执行轮换,我先做一些实验。【参考方案2】:

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

解决方案是删除整个 CloudFormation 堆栈,使用 MD5 重新创建。 (更新值没有解决错误)

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

【讨论】:

看起来更像是评论而不是答案。一旦你有足够的reputation,你就可以comment on any post【参考方案3】:

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

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


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

【讨论】:

【参考方案4】:

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

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


解决方案

对我来说,问题是我需要为轮换 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 仪表板中查看其模板即可。

【讨论】:

以上是关于使用 CloudFormation(和 Lambda 轮换模板)的 Aurora Serverless 密码轮换设置的主要内容,如果未能解决你的问题,请参考以下文章

利用LinQ技术和lambd表达式进行增删改查

动态创建生成lambd表达式

AWS CloudFormation:Cognito LambdaTrigger CustomEmailSender - 属性“AWS CloudFormation 目前不支持。”和 CDK 的使用

使用 Auto Scaling 组、CloudFormation 和 CodeDeploy 的蓝/绿部署

VPC 内部的 CloudFormation?

AWS Lambda 和 Gateway API - 使用 cloudformation 的蓝/绿部署