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

创建自动轮换的 Amazon Secrets Manager 密钥,然后使用 Amazon CloudFormation 创建 Amazon Redshift 集群

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

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

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

JSON

{ "AWSTemplateFormatVersion":"2010-09-09", "Transform":"AWS::SecretsManager-2020-07-23", "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" } } }, "MyRedshiftSecret":{ "Type":"AWS::SecretsManager::Secret", "Properties":{ "Description":"This is my rds instance secret", "GenerateSecretString":{ "SecretStringTemplate":"{\"username\": \"admin\"}", "GenerateStringKey":"password", "PasswordLength":16, "ExcludeCharacters":"\"@/\\" }, "Tags":[ { "Key":"AppName", "Value":"MyApp" } ] } }, "MyRedshiftCluster":{ "Type":"AWS::Redshift::Cluster", "Properties":{ "DBName":"myyamldb", "NodeType":"ds2.xlarge", "ClusterType":"single-node", "ClusterSubnetGroupName":{ "Ref":"ResdshiftSubnetGroup" }, "MasterUsername":{ "Fn::Sub":"{{resolve:secretsmanager:${MyRedshiftSecret}::username}}" }, "MasterUserPassword":{ "Fn::Sub":"{{resolve:secretsmanager:${MyRedshiftSecret}::password}}" }, "PubliclyAccessible":false, "VpcSecurityGroupIds":[ { "Fn::GetAtt":[ "TestVPC", "DefaultSecurityGroup" ] } ] } }, "ResdshiftSubnetGroup":{ "Type":"AWS::Redshift::ClusterSubnetGroup", "Properties":{ "Description":"Test Group", "SubnetIds":[ { "Ref":"TestSubnet01" }, { "Ref":"TestSubnet02" } ] } }, "SecretRedshiftAttachment":{ "Type":"AWS::SecretsManager::SecretTargetAttachment", "Properties":{ "SecretId":{ "Ref":"MyRedshiftSecret" }, "TargetId":{ "Ref":"MyRedshiftCluster" }, "TargetType":"AWS::Redshift::Cluster" } }, "MySecretRotationSchedule":{ "Type":"AWS::SecretsManager::RotationSchedule", "DependsOn":"SecretRedshiftAttachment", "Properties":{ "SecretId":{ "Ref":"MyRedshiftSecret" }, "HostedRotationLambda":{ "RotationType":"RedshiftSingleUser", "RotationLambdaName":"SecretsManagerRotationRedshift", "VpcSecurityGroupIds":{ "Fn::GetAtt":[ "TestVPC", "DefaultSecurityGroup" ] }, "VpcSubnetIds":{ "Fn::Join":[ ",", [ { "Ref":"TestSubnet01" }, { "Ref":"TestSubnet02" } ] ] } }, "RotationRules":{ "Duration": "2h", "ScheduleExpression": "cron(0 8 1 * ? *)" } } } } }

YAML

AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::SecretsManager-2020-07-23 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 MyRedshiftSecret: Type: AWS::SecretsManager::Secret Properties: Description: This is my rds instance secret GenerateSecretString: SecretStringTemplate: '{"username": "admin"}' GenerateStringKey: password PasswordLength: 16 ExcludeCharacters: "\"@/\\" Tags: - Key: AppName Value: MyApp MyRedshiftCluster: Type: AWS::Redshift::Cluster Properties: DBName: myyamldb NodeType: ds2.xlarge ClusterType: single-node ClusterSubnetGroupName: Ref: ResdshiftSubnetGroup MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${MyRedshiftSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${MyRedshiftSecret}::password}}" PubliclyAccessible: false VpcSecurityGroupIds: - Fn::GetAtt: - TestVPC - DefaultSecurityGroup ResdshiftSubnetGroup: Type: AWS::Redshift::ClusterSubnetGroup Properties: Description: Test Group SubnetIds: - Ref: TestSubnet01 - Ref: TestSubnet02 SecretRedshiftAttachment: Type: AWS::SecretsManager::SecretTargetAttachment Properties: SecretId: Ref: MyRedshiftSecret TargetId: Ref: MyRedshiftCluster TargetType: AWS::Redshift::Cluster MySecretRotationSchedule: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretRedshiftAttachment Properties: SecretId: Ref: MyRedshiftSecret HostedRotationLambda: RotationType: RedshiftSingleUser RotationLambdaName: SecretsManagerRotationRedshift VpcSecurityGroupIds: Fn::GetAtt: - TestVPC - DefaultSecurityGroup VpcSubnetIds: Fn::Join: - "," - - Ref: TestSubnet01 - Ref: TestSubnet02 RotationRules: Duration: 2h ScheduleExpression: 'cron(0 8 1 * ? *)'