使用 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 密码轮换设置的主要内容,如果未能解决你的问题,请参考以下文章
AWS CloudFormation:Cognito LambdaTrigger CustomEmailSender - 属性“AWS CloudFormation 目前不支持。”和 CDK 的使用