UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

2 lines (1 loc) 17.1 kB
"use strict";var _a,_b,_c;Object.defineProperty(exports,"__esModule",{value:!0}),exports.DatabaseClusterFromSnapshot=exports.DatabaseCluster=exports.DatabaseClusterBase=exports.InstanceUpdateBehaviour=void 0;const jsiiDeprecationWarnings=require("../../.warnings.jsii.js"),JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti"),ec2=require("../../aws-ec2"),aws_iam_1=require("../../aws-iam"),logs=require("../../aws-logs"),secretsmanager=require("../../aws-secretsmanager"),core_1=require("../../core"),cxapi=require("../../cx-api"),database_secret_1=require("./database-secret"),endpoint_1=require("./endpoint"),parameter_group_1=require("./parameter-group"),util_1=require("./private/util"),props_1=require("./props"),proxy_1=require("./proxy"),rds_generated_1=require("./rds.generated"),subnet_group_1=require("./subnet-group");var InstanceUpdateBehaviour;(function(InstanceUpdateBehaviour2){InstanceUpdateBehaviour2.BULK="BULK",InstanceUpdateBehaviour2.ROLLING="ROLLING"})(InstanceUpdateBehaviour=exports.InstanceUpdateBehaviour||(exports.InstanceUpdateBehaviour={}));class DatabaseClusterBase extends core_1.Resource{addProxy(id,options){try{jsiiDeprecationWarnings.aws_cdk_lib_aws_rds_DatabaseProxyOptions(options)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addProxy),error}return new proxy_1.DatabaseProxy(this,id,{proxyTarget:proxy_1.ProxyTarget.fromCluster(this),...options})}asSecretAttachmentTarget(){return{targetId:this.clusterIdentifier,targetType:secretsmanager.AttachmentTargetType.RDS_DB_CLUSTER}}}exports.DatabaseClusterBase=DatabaseClusterBase,_a=JSII_RTTI_SYMBOL_1,DatabaseClusterBase[_a]={fqn:"aws-cdk-lib.aws_rds.DatabaseClusterBase",version:"2.70.0"};class DatabaseClusterNew extends DatabaseClusterBase{constructor(scope,id,props){super(scope,id),this.vpc=props.instanceProps.vpc,this.vpcSubnets=props.instanceProps.vpcSubnets,this.singleUserRotationApplication=props.engine.singleUserRotationApplication,this.multiUserRotationApplication=props.engine.multiUserRotationApplication;const{subnetIds}=props.instanceProps.vpc.selectSubnets(props.instanceProps.vpcSubnets);subnetIds.length<2&&core_1.Annotations.of(this).addError(`Cluster requires at least 2 subnets, got ${subnetIds.length}`),this.subnetGroup=props.subnetGroup??new subnet_group_1.SubnetGroup(this,"Subnets",{description:`Subnets for ${id} database`,vpc:props.instanceProps.vpc,vpcSubnets:props.instanceProps.vpcSubnets,removalPolicy:util_1.renderUnless(util_1.helperRemovalPolicy(props.removalPolicy),core_1.RemovalPolicy.DESTROY)}),this.securityGroups=props.instanceProps.securityGroups??[new ec2.SecurityGroup(this,"SecurityGroup",{description:"RDS security group",vpc:props.instanceProps.vpc})];const combineRoles=props.engine.combineImportAndExportRoles??!1;let{s3ImportRole,s3ExportRole}=util_1.setupS3ImportExport(this,props,combineRoles);if(props.parameterGroup&&props.parameters)throw new Error("You cannot specify both parameterGroup and parameters");const parameterGroup=props.parameterGroup??(props.parameters?new parameter_group_1.ParameterGroup(this,"ParameterGroup",{engine:props.engine,parameters:props.parameters}):void 0),clusterEngineBindConfig=props.engine.bindToCluster(this,{s3ImportRole,s3ExportRole,parameterGroup}),clusterAssociatedRoles=[];s3ImportRole&&clusterAssociatedRoles.push({roleArn:s3ImportRole.roleArn,featureName:clusterEngineBindConfig.features?.s3Import}),s3ExportRole&&(s3ExportRole!==s3ImportRole||clusterEngineBindConfig.features?.s3Import!==clusterEngineBindConfig.features?.s3Export)&&clusterAssociatedRoles.push({roleArn:s3ExportRole.roleArn,featureName:clusterEngineBindConfig.features?.s3Export});const clusterParameterGroupConfig=(props.parameterGroup??clusterEngineBindConfig.parameterGroup)?.bindToCluster({});this.engine=props.engine;const clusterIdentifier=core_1.FeatureFlags.of(this).isEnabled(cxapi.RDS_LOWERCASE_DB_IDENTIFIER)&&!core_1.Token.isUnresolved(props.clusterIdentifier)?props.clusterIdentifier?.toLowerCase():props.clusterIdentifier;this.newCfnProps={engine:props.engine.engineType,engineVersion:props.engine.engineVersion?.fullVersion,dbClusterIdentifier:clusterIdentifier,dbSubnetGroupName:this.subnetGroup.subnetGroupName,vpcSecurityGroupIds:this.securityGroups.map(sg=>sg.securityGroupId),port:props.port??clusterEngineBindConfig.port,dbClusterParameterGroupName:clusterParameterGroupConfig?.parameterGroupName,associatedRoles:clusterAssociatedRoles.length>0?clusterAssociatedRoles:void 0,deletionProtection:util_1.defaultDeletionProtection(props.deletionProtection,props.removalPolicy),enableIamDatabaseAuthentication:props.iamAuthentication,networkType:props.networkType,backtrackWindow:props.backtrackWindow?.toSeconds(),backupRetentionPeriod:props.backup?.retention?.toDays(),preferredBackupWindow:props.backup?.preferredWindow,preferredMaintenanceWindow:props.preferredMaintenanceWindow,databaseName:props.defaultDatabaseName,enableCloudwatchLogsExports:props.cloudwatchLogsExports,kmsKeyId:props.storageEncryptionKey?.keyArn,storageEncrypted:props.storageEncryptionKey?!0:props.storageEncrypted,copyTagsToSnapshot:props.copyTagsToSnapshot??!0}}addRotationSingleUser(options={}){if(!this.secret)throw new Error("Cannot add a single user rotation for a cluster without a secret.");const id="RotationSingleUser";if(this.node.tryFindChild(id))throw new Error("A single user rotation was already added to this cluster.");return new secretsmanager.SecretRotation(this,id,{...util_1.applyDefaultRotationOptions(options,this.vpcSubnets),secret:this.secret,application:this.singleUserRotationApplication,vpc:this.vpc,target:this})}addRotationMultiUser(id,options){if(!this.secret)throw new Error("Cannot add a multi user rotation for a cluster without a secret.");return new secretsmanager.SecretRotation(this,id,{...util_1.applyDefaultRotationOptions(options,this.vpcSubnets),secret:options.secret,masterSecret:this.secret,application:this.multiUserRotationApplication,vpc:this.vpc,target:this})}}class ImportedDatabaseCluster extends DatabaseClusterBase{constructor(scope,id,attrs){super(scope,id),this.clusterIdentifier=attrs.clusterIdentifier,this._clusterResourceIdentifier=attrs.clusterResourceIdentifier;const defaultPort=attrs.port?ec2.Port.tcp(attrs.port):void 0;this.connections=new ec2.Connections({securityGroups:attrs.securityGroups,defaultPort}),this.engine=attrs.engine,this._clusterEndpoint=attrs.clusterEndpointAddress&&attrs.port?new endpoint_1.Endpoint(attrs.clusterEndpointAddress,attrs.port):void 0,this._clusterReadEndpoint=attrs.readerEndpointAddress&&attrs.port?new endpoint_1.Endpoint(attrs.readerEndpointAddress,attrs.port):void 0,this._instanceIdentifiers=attrs.instanceIdentifiers,this._instanceEndpoints=attrs.instanceEndpointAddresses&&attrs.port?attrs.instanceEndpointAddresses.map(addr=>new endpoint_1.Endpoint(addr,attrs.port)):void 0}get clusterResourceIdentifier(){if(!this._clusterResourceIdentifier)throw new Error("Cannot access `clusterResourceIdentifier` of an imported cluster without a clusterResourceIdentifier");return this._clusterResourceIdentifier}get clusterEndpoint(){if(!this._clusterEndpoint)throw new Error("Cannot access `clusterEndpoint` of an imported cluster without an endpoint address and port");return this._clusterEndpoint}get clusterReadEndpoint(){if(!this._clusterReadEndpoint)throw new Error("Cannot access `clusterReadEndpoint` of an imported cluster without a readerEndpointAddress and port");return this._clusterReadEndpoint}get instanceIdentifiers(){if(!this._instanceIdentifiers)throw new Error("Cannot access `instanceIdentifiers` of an imported cluster without provided instanceIdentifiers");return this._instanceIdentifiers}get instanceEndpoints(){if(!this._instanceEndpoints)throw new Error("Cannot access `instanceEndpoints` of an imported cluster without instanceEndpointAddresses and port");return this._instanceEndpoints}}class DatabaseCluster extends DatabaseClusterNew{constructor(scope,id,props){super(scope,id,props);try{jsiiDeprecationWarnings.aws_cdk_lib_aws_rds_DatabaseClusterProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,DatabaseCluster),error}const credentials=util_1.renderCredentials(this,props.engine,props.credentials),secret=credentials.secret,cluster=new rds_generated_1.CfnDBCluster(this,"Resource",{...this.newCfnProps,masterUsername:credentials.username,masterUserPassword:credentials.password?.unsafeUnwrap()});this.clusterIdentifier=cluster.ref,this.clusterResourceIdentifier=cluster.attrDbClusterResourceId,secret&&(this.secret=secret.attach(this));const portAttribute=core_1.Token.asNumber(cluster.attrEndpointPort);this.clusterEndpoint=new endpoint_1.Endpoint(cluster.attrEndpointAddress,portAttribute),this.clusterReadEndpoint=new endpoint_1.Endpoint(cluster.attrReadEndpointAddress,portAttribute),this.connections=new ec2.Connections({securityGroups:this.securityGroups,defaultPort:ec2.Port.tcp(this.clusterEndpoint.port)}),cluster.applyRemovalPolicy(props.removalPolicy??core_1.RemovalPolicy.SNAPSHOT),setLogRetention(this,props);const createdInstances=createInstances(this,props,this.subnetGroup);this.instanceIdentifiers=createdInstances.instanceIdentifiers,this.instanceEndpoints=createdInstances.instanceEndpoints}static fromDatabaseClusterAttributes(scope,id,attrs){try{jsiiDeprecationWarnings.aws_cdk_lib_aws_rds_DatabaseClusterAttributes(attrs)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.fromDatabaseClusterAttributes),error}return new ImportedDatabaseCluster(scope,id,attrs)}}exports.DatabaseCluster=DatabaseCluster,_b=JSII_RTTI_SYMBOL_1,DatabaseCluster[_b]={fqn:"aws-cdk-lib.aws_rds.DatabaseCluster",version:"2.70.0"};class DatabaseClusterFromSnapshot extends DatabaseClusterNew{constructor(scope,id,props){super(scope,id,props);try{jsiiDeprecationWarnings.aws_cdk_lib_aws_rds_DatabaseClusterFromSnapshotProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,DatabaseClusterFromSnapshot),error}props.credentials&&!props.credentials.password&&!props.credentials.secret&&core_1.Annotations.of(this).addWarning("Use `snapshotCredentials` to modify password of a cluster created from a snapshot."),!props.credentials&&!props.snapshotCredentials&&core_1.Annotations.of(this).addWarning("Generated credentials will not be applied to cluster. Use `snapshotCredentials` instead. `addRotationSingleUser()` and `addRotationMultiUser()` cannot be used on this cluster.");const deprecatedCredentials=util_1.renderCredentials(this,props.engine,props.credentials);let credentials=props.snapshotCredentials,secret=credentials?.secret;if(!secret&&credentials?.generatePassword){if(!credentials.username)throw new Error("`snapshotCredentials` `username` must be specified when `generatePassword` is set to true");secret=new database_secret_1.DatabaseSecret(this,"SnapshotSecret",{username:credentials.username,encryptionKey:credentials.encryptionKey,excludeCharacters:credentials.excludeCharacters,replaceOnPasswordCriteriaChanges:credentials.replaceOnPasswordCriteriaChanges,replicaRegions:credentials.replicaRegions})}const cluster=new rds_generated_1.CfnDBCluster(this,"Resource",{...this.newCfnProps,snapshotIdentifier:props.snapshotIdentifier,masterUserPassword:secret?.secretValueFromJson("password")?.unsafeUnwrap()??credentials?.password?.unsafeUnwrap()});if(this.clusterIdentifier=cluster.ref,this.clusterResourceIdentifier=cluster.attrDbClusterResourceId,secret&&(this.secret=secret.attach(this)),deprecatedCredentials.secret){const deprecatedSecret=deprecatedCredentials.secret.attach(this);this.secret||(this.secret=deprecatedSecret)}const portAttribute=core_1.Token.asNumber(cluster.attrEndpointPort);this.clusterEndpoint=new endpoint_1.Endpoint(cluster.attrEndpointAddress,portAttribute),this.clusterReadEndpoint=new endpoint_1.Endpoint(cluster.attrReadEndpointAddress,portAttribute),this.connections=new ec2.Connections({securityGroups:this.securityGroups,defaultPort:ec2.Port.tcp(this.clusterEndpoint.port)}),cluster.applyRemovalPolicy(props.removalPolicy??core_1.RemovalPolicy.SNAPSHOT),setLogRetention(this,props);const createdInstances=createInstances(this,props,this.subnetGroup);this.instanceIdentifiers=createdInstances.instanceIdentifiers,this.instanceEndpoints=createdInstances.instanceEndpoints}}exports.DatabaseClusterFromSnapshot=DatabaseClusterFromSnapshot,_c=JSII_RTTI_SYMBOL_1,DatabaseClusterFromSnapshot[_c]={fqn:"aws-cdk-lib.aws_rds.DatabaseClusterFromSnapshot",version:"2.70.0"};function setLogRetention(cluster,props){if(props.cloudwatchLogsExports){const unsupportedLogTypes=props.cloudwatchLogsExports.filter(logType=>!props.engine.supportedLogTypes.includes(logType));if(unsupportedLogTypes.length>0)throw new Error(`Unsupported logs for the current engine type: ${unsupportedLogTypes.join(",")}`);if(props.cloudwatchLogsRetention)for(const log of props.cloudwatchLogsExports)new logs.LogRetention(cluster,`LogRetention${log}`,{logGroupName:`/aws/rds/cluster/${cluster.clusterIdentifier}/${log}`,retention:props.cloudwatchLogsRetention,role:props.cloudwatchLogsRetentionRole})}}function createInstances(cluster,props,subnetGroup){const instanceCount=props.instances!=null?props.instances:2,instanceUpdateBehaviour=props.instanceUpdateBehaviour??InstanceUpdateBehaviour.BULK;if(core_1.Token.isUnresolved(instanceCount))throw new Error("The number of instances an RDS Cluster consists of cannot be provided as a deploy-time only value!");if(instanceCount<1)throw new Error("At least one instance is required");const instanceIdentifiers=[],instanceEndpoints=[],portAttribute=cluster.clusterEndpoint.port,instanceProps=props.instanceProps,internetConnected=instanceProps.vpc.selectSubnets(instanceProps.vpcSubnets).internetConnectivityEstablished;let monitoringRole;props.monitoringInterval&&props.monitoringInterval.toSeconds()&&(monitoringRole=props.monitoringRole||new aws_iam_1.Role(cluster,"MonitoringRole",{assumedBy:new aws_iam_1.ServicePrincipal("monitoring.rds.amazonaws.com"),managedPolicies:[aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonRDSEnhancedMonitoringRole")]}));const enablePerformanceInsights=instanceProps.enablePerformanceInsights||instanceProps.performanceInsightRetention!==void 0||instanceProps.performanceInsightEncryptionKey!==void 0;if(enablePerformanceInsights&&instanceProps.enablePerformanceInsights===!1)throw new Error("`enablePerformanceInsights` disabled, but `performanceInsightRetention` or `performanceInsightEncryptionKey` was set");const instanceType=instanceProps.instanceType??ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM);if(instanceProps.parameterGroup&&instanceProps.parameters)throw new Error("You cannot specify both parameterGroup and parameters");const instanceParameterGroupConfig=(instanceProps.parameterGroup??(instanceProps.parameters?new parameter_group_1.ParameterGroup(cluster,"InstanceParameterGroup",{engine:props.engine,parameters:instanceProps.parameters}):void 0))?.bindToInstance({}),instances=[];for(let i=0;i<instanceCount;i++){const instanceIndex=i+1,instanceIdentifier=props.instanceIdentifierBase!=null?`${props.instanceIdentifierBase}${instanceIndex}`:props.clusterIdentifier!=null?`${props.clusterIdentifier}instance${instanceIndex}`:void 0,instance=new rds_generated_1.CfnDBInstance(cluster,`Instance${instanceIndex}`,{engine:props.engine.engineType,dbClusterIdentifier:cluster.clusterIdentifier,dbInstanceIdentifier:instanceIdentifier,dbInstanceClass:databaseInstanceType(instanceType),publiclyAccessible:instanceProps.publiclyAccessible??(instanceProps.vpcSubnets&&instanceProps.vpcSubnets.subnetType===ec2.SubnetType.PUBLIC),enablePerformanceInsights:enablePerformanceInsights||instanceProps.enablePerformanceInsights,performanceInsightsKmsKeyId:instanceProps.performanceInsightEncryptionKey?.keyArn,performanceInsightsRetentionPeriod:enablePerformanceInsights?instanceProps.performanceInsightRetention||props_1.PerformanceInsightRetention.DEFAULT:void 0,dbSubnetGroupName:subnetGroup.subnetGroupName,dbParameterGroupName:instanceParameterGroupConfig?.parameterGroupName,monitoringInterval:props.monitoringInterval&&props.monitoringInterval.toSeconds(),monitoringRoleArn:monitoringRole&&monitoringRole.roleArn,autoMinorVersionUpgrade:props.instanceProps.autoMinorVersionUpgrade,allowMajorVersionUpgrade:props.instanceProps.allowMajorVersionUpgrade,deleteAutomatedBackups:props.instanceProps.deleteAutomatedBackups});instance.applyRemovalPolicy(util_1.helperRemovalPolicy(props.removalPolicy)),instance.node.addDependency(internetConnected),instanceIdentifiers.push(instance.ref),instanceEndpoints.push(new endpoint_1.Endpoint(instance.attrEndpointAddress,portAttribute)),instances.push(instance)}if(instanceUpdateBehaviour===InstanceUpdateBehaviour.ROLLING)for(let i=1;i<instanceCount;i++)instances[i].node.addDependency(instances[i-1]);return{instanceEndpoints,instanceIdentifiers}}function databaseInstanceType(instanceType){return"db."+instanceType.toString()}