创建自动轮换的 Amazon Secrets Manager 密钥,然后使用 Amazon CloudFormation 创建 Amazon RDS MySQL 数据库实例 - Amazon Secrets Manager
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

创建自动轮换的 Amazon Secrets Manager 密钥,然后使用 Amazon CloudFormation 创建 Amazon RDS MySQL 数据库实例

此示例将创建一个秘密,并使用该秘密中的凭证作为用户和密码,创建一个 Amazon RDS MySQL 数据库实例。Secrets Manager 会生成一个包含 32 个字符的密码。该模板还可以从 轮换函数模板 创建 Lambda 轮换函数,并将秘密配置为协调世界时每月第一天上午 8:00 到 10:00 之间自动轮换。作为安全最佳实践,该数据库实例位于 Amazon VPC 中。

要查看不自动轮换的示例,请参阅 使用 Amazon RDS 凭证创建秘密

此示例将以下 CloudFormation 资源用于 Secrets Manager:

有关使用 Amazon CloudFormation 创建资源的信息,请参阅《Amazon CloudFormation 用户指南》中的了解模板基础知识

JSON

{ "Transform": "AWS::SecretsManager-2020-07-23", "Description": "This is an example template to demonstrate CloudFormation resources for Secrets Manager", "Resources": { "TestVPC": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/16", "EnableDnsHostnames": true, "EnableDnsSupport": true } }, "TestSubnet01": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.96.0/19", "AvailabilityZone": { "Fn::Select": [ "0", { "Fn::GetAZs": { "Ref": "AWS::Region" } } ] }, "VpcId": { "Ref": "TestVPC" } } }, "TestSubnet02": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.128.0/19", "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } } ] }, "VpcId": { "Ref": "TestVPC" } } }, "SecretsManagerVPCEndpoint": { "Type": "AWS::EC2::VPCEndpoint", "Properties": { "SubnetIds": [ { "Ref": "TestSubnet01" }, { "Ref": "TestSubnet02" } ], "SecurityGroupIds": [ { "Fn::GetAtt": [ "TestVPC", "DefaultSecurityGroup" ] } ], "VpcEndpointType": "Interface", "ServiceName": { "Fn::Sub": "com.amazonaws.${AWS::Region}.secretsmanager" }, "PrivateDnsEnabled": true, "VpcId": { "Ref": "TestVPC" } } }, "MyRDSInstanceRotationSecret": { "Type": "AWS::SecretsManager::Secret", "Properties": { "Description": "This is my rds instance secret", "GenerateSecretString": { "SecretStringTemplate": "{\"username\": \"admin\"}", "GenerateStringKey": "password", "PasswordLength": 32, "ExcludeCharacters": "/@\"'\\" }, "Tags": [ { "Key": "AppName", "Value": "MyApp" } ] } }, "MyDBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "AllocatedStorage": 20, "DBInstanceClass": "db.t2.micro", "Engine": "mysql", "DBSubnetGroupName": { "Ref": "MyDBSubnetGroup" }, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${MyRDSInstanceRotationSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${MyRDSInstanceRotationSecret}::password}}" }, "BackupRetentionPeriod": 0, "VPCSecurityGroups": [ { "Fn::GetAtt": [ "TestVPC", "DefaultSecurityGroup" ] } ] } }, "MyDBSubnetGroup": { "Type": "AWS::RDS::DBSubnetGroup", "Properties": { "DBSubnetGroupDescription": "Test Group", "SubnetIds": [ { "Ref": "TestSubnet01" }, { "Ref": "TestSubnet02" } ] } }, "SecretRDSInstanceAttachment": { "Type": "AWS::SecretsManager::SecretTargetAttachment", "Properties": { "SecretId": { "Ref": "MyRDSInstanceRotationSecret" }, "TargetId": { "Ref": "MyDBInstance" }, "TargetType": "AWS::RDS::DBInstance" } }, "MySecretRotationSchedule": { "Type": "AWS::SecretsManager::RotationSchedule", "DependsOn": "SecretRDSInstanceAttachment", "Properties": { "SecretId": { "Ref": "MyRDSInstanceRotationSecret" }, "HostedRotationLambda": { "RotationType": "MySQLSingleUser", "RotationLambdaName": "SecretsManagerRotation", "VpcSecurityGroupIds": { "Fn::GetAtt": [ "TestVPC", "DefaultSecurityGroup" ] }, "VpcSubnetIds": { "Fn::Join": [ ",", [ { "Ref": "TestSubnet01" }, { "Ref": "TestSubnet02" } ] ] } }, "RotationRules": { "Duration": 2h, "ScheduleExpression": "cron(0 8 1 * ? *)" } } } } }

YAML

--- Transform: AWS::SecretsManager-2020-07-23 Description: This is an example template to demonstrate CloudFormation resources for Secrets Manager Resources: #This is the VPC that the rotation Lambda function and the RDS instance will be placed in TestVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true # Subnet that the rotation Lambda function and the RDS instance will be placed in TestSubnet01: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.96.0/19 AvailabilityZone: Fn::Select: - '0' - Fn::GetAZs: Ref: AWS::Region VpcId: Ref: TestVPC TestSubnet02: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.128.0/19 AvailabilityZone: Fn::Select: - '1' - Fn::GetAZs: Ref: AWS::Region VpcId: Ref: TestVPC #VPC endpoint that will enable the rotation Lambda function to make api calls to Secrets Manager SecretsManagerVPCEndpoint: Type: AWS::EC2::VPCEndpoint Properties: SubnetIds: - Ref: TestSubnet01 - Ref: TestSubnet02 SecurityGroupIds: - Fn::GetAtt: - TestVPC - DefaultSecurityGroup VpcEndpointType: Interface ServiceName: Fn::Sub: com.amazonaws.${AWS::Region}.secretsmanager PrivateDnsEnabled: true VpcId: Ref: TestVPC #This is a Secret resource with a randomly generated password in its SecretString JSON. MyRDSInstanceRotationSecret: Type: AWS::SecretsManager::Secret Properties: Description: This is my rds instance secret GenerateSecretString: SecretStringTemplate: '{"username": "admin"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" Tags: - Key: AppName Value: MyApp #This is an RDS instance resource. Its master username and password use dynamic references to resolve values from #SecretsManager. The dynamic reference guarantees that CloudFormation will not log or persist the resolved value #We sub the Secret resource's logical id in order to construct the dynamic reference, since the Secret's name is being #generated by CloudFormation MyDBInstance: Type: AWS::RDS::DBInstance Properties: AllocatedStorage: 20 DBInstanceClass: db.t2.micro Engine: mysql DBSubnetGroupName: Ref: MyDBSubnetGroup MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${MyRDSInstanceRotationSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${MyRDSInstanceRotationSecret}::password}}" BackupRetentionPeriod: 0 VPCSecurityGroups: - Fn::GetAtt: - TestVPC - DefaultSecurityGroup #Database subnet group for the RDS instance MyDBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Test Group SubnetIds: - Ref: TestSubnet01 - Ref: TestSubnet02 #This is a SecretTargetAttachment resource which updates the referenced Secret resource with properties about #the referenced RDS instance SecretRDSInstanceAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: Ref: MyRDSInstanceRotationSecret TargetId: Ref: MyDBInstance TargetType: AWS::RDS::DBInstance #This is a RotationSchedule resource. It configures rotation of password for the referenced secret using a rotation lambda function #The first rotation happens at resource creation time, with subsequent rotations scheduled according to the rotation rules #We explicitly depend on the SecretTargetAttachment resource being created to ensure that the secret contains all the #information necessary for rotation to succeed MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretRDSInstanceAttachment Properties: SecretId: Ref: MyRDSInstanceRotationSecret HostedRotationLambda: RotationType: MySQLSingleUser RotationLambdaName: SecretsManagerRotation VpcSecurityGroupIds: Fn::GetAtt: - TestVPC - DefaultSecurityGroup VpcSubnetIds: Fn::Join: - "," - - Ref: TestSubnet01 - Ref: TestSubnet02 RotationRules: Duration: 2h ScheduleExpression: 'cron(0 8 1 * ? *)'