Настройка ротации паролей Aurora Serverless с использованием CloudFormation (и шаблоны ротации Lambda)
AWS имеет полностью настроенную и готовую к использованию поддержку ротации для некоторых поддерживаемых движков RDS, включая Amazon Aurora (также без сервера?)
Я пытаюсь настроить ротацию пароля в моем шаблоне CloudFormation с помощью AWS::SecretsManager::RotationSchedule
(обратите внимание, что это не полностью функциональный шаблон, а только иллюстрация):
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 не работает со следующим сообщением:
"Движок базы данных должен быть установлен на" mysql ", чтобы использовать эту лямбду вращения": KeyError
Похоже, что Aurora Serverless не поддерживается функцией ротации AWS Lambda, предоставляемой AWS.
Есть ли простой способ настроить секретную ротацию Aurora Server с использованием существующих шаблонов ротации Lambda?
Любой пример, доступный, чтобы написать мою собственную функцию вращения для Aurora Serverless?
PS: Этот вопрос как бы связан с созданием Aurora Serverless Cluster from cloudformation?
1 ответ
Ресурс RotationSchedule зависит от ресурса SecretTargetAttachment. Ресурс вложения обновляет ваше значение секретной строки, чтобы оно содержало информацию о соединении, такую как механизм БД, порт и конечная точка.
К сожалению, CloudFormation не может узнать об этой неявной зависимости между двумя ресурсами. Вам необходимо поместить DependsOn в ресурс RotationSchedule с логическим идентификатором ресурса вложения.
Посмотрите ресурс RotationSchedule в этом примере - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-rotationschedule.html
Я не использовал бессерверную версию, но получил ту же самую ошибку.
"Ядро базы данных должно быть установлено на mysql, чтобы использовать эту лямбду вращения": KeyError
Решение
Для меня проблема заключалась в том, что мне нужно было предоставить подсети и группу безопасности для лямбда-выражения ротации.
Набросок шаблона CloudFormation будет выглядеть так (обратите внимание на параметры, переданные в лямбду):
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 просто не может подключиться к базе данных. Предыдущий секрет - это секрет, который вы изначально указываете в шаблоне CloudFormation выше.
{
"username": "XXXXXXXXXX",
"password": "XXXXXXXXXX"
}
В AWS::SecretsManager::SecretTargetAttachment
изменяет его на правильный формат (для RDS MySQL Single User):
{
"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.
Мне удалось настроить ротацию секретов для Aurora Serverless с помощью AWS Fully Configured and Ready-to-Use Rotation Support: 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"
}
Я столкнулся с аналогичной ошибкой при настройке параметров PostgreSQL "password_encryption: 'scram-sha-256'"
Решением было отказаться от воссоздания всего стека CloudFormation с помощью MD5. (Обновление значения не устранило ошибку)
Кроме того, если у Lambdalog есть тайм-аут без других ошибок, увеличьте таймаут лямбда-функции по умолчанию с 30 секунд до 60 секунд, чтобы решить проблему.