constructor()

in packages/aws-cdk-lib/aws-rds/lib/instance.ts [845:978]


  constructor(scope: Construct, id: string, props: DatabaseInstanceNewProps) {
    // RDS always lower-cases the ID of the database, so use that for the physical name
    // (which is the name used for cross-environment access, so it needs to be correct,
    // regardless of the feature flag that changes it in the template for the L1)
    const instancePhysicalName = Token.isUnresolved(props.instanceIdentifier)
      ? props.instanceIdentifier
      : props.instanceIdentifier?.toLowerCase();
    super(scope, id, {
      physicalName: instancePhysicalName,
    });

    this.vpc = props.vpc;
    if (props.vpcSubnets && props.vpcPlacement) {
      throw new ValidationError('Only one of `vpcSubnets` or `vpcPlacement` can be specified', this);
    }
    this.vpcPlacement = props.vpcSubnets ?? props.vpcPlacement;

    if (props.multiAz === true && props.availabilityZone) {
      throw new ValidationError('Requesting a specific availability zone is not valid for Multi-AZ instances', this);
    }

    const subnetGroup = props.subnetGroup ?? new SubnetGroup(this, 'SubnetGroup', {
      description: `Subnet group for ${this.node.id} database`,
      vpc: this.vpc,
      vpcSubnets: this.vpcPlacement,
      removalPolicy: renderUnless(helperRemovalPolicy(props.removalPolicy), RemovalPolicy.DESTROY),
    });

    const securityGroups = props.securityGroups || [new ec2.SecurityGroup(this, 'SecurityGroup', {
      description: `Security group for ${this.node.id} database`,
      vpc: props.vpc,
    })];

    this.connections = new ec2.Connections({
      securityGroups,
      defaultPort: ec2.Port.tcp(Lazy.number({ produce: () => this.instanceEndpoint.port })),
    });

    let monitoringRole;
    if (props.monitoringInterval && props.monitoringInterval.toSeconds()) {
      monitoringRole = props.monitoringRole || new iam.Role(this, 'MonitoringRole', {
        assumedBy: new iam.ServicePrincipal('monitoring.rds.amazonaws.com'),
        managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonRDSEnhancedMonitoringRole')],
      });
    }

    const storageType = props.storageType ?? StorageType.GP2;
    const iops = defaultIops(storageType, props.iops);
    if (props.storageThroughput && storageType !== StorageType.GP3) {
      throw new ValidationError(`The storage throughput can only be specified with GP3 storage type. Got ${storageType}.`, this);
    }
    if (storageType === StorageType.GP3 && props.storageThroughput && iops
        && !Token.isUnresolved(props.storageThroughput) && !Token.isUnresolved(iops)
        && props.storageThroughput/iops > 0.25) {
      throw new ValidationError(`The maximum ratio of storage throughput to IOPS is 0.25. Got ${props.storageThroughput/iops}.`, this);
    }

    this.cloudwatchLogGroups = {};
    this.cloudwatchLogsExports = props.cloudwatchLogsExports;
    this.cloudwatchLogsRetention = props.cloudwatchLogsRetention;
    this.cloudwatchLogsRetentionRole = props.cloudwatchLogsRetentionRole;
    this.enableIamAuthentication = props.iamAuthentication;

    const enablePerformanceInsights = props.enablePerformanceInsights
      || props.performanceInsightRetention !== undefined || props.performanceInsightEncryptionKey !== undefined;
    if (enablePerformanceInsights && props.enablePerformanceInsights === false) {
      throw new ValidationError('`enablePerformanceInsights` disabled, but `performanceInsightRetention` or `performanceInsightEncryptionKey` was set', this);
    }

    if (props.domain) {
      this.domainId = props.domain;
      this.domainRole = props.domainRole || new iam.Role(this, 'RDSDirectoryServiceRole', {
        assumedBy: new iam.CompositePrincipal(
          new iam.ServicePrincipal('rds.amazonaws.com'),
          new iam.ServicePrincipal('directoryservice.rds.amazonaws.com'),
        ),
        managedPolicies: [
          iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonRDSDirectoryServiceAccess'),
        ],
      });
    }

    const maybeLowercasedInstanceId = FeatureFlags.of(this).isEnabled(cxapi.RDS_LOWERCASE_DB_IDENTIFIER)
    && !Token.isUnresolved(props.instanceIdentifier)
      ? props.instanceIdentifier?.toLowerCase()
      : props.instanceIdentifier;

    const instanceParameterGroupConfig = props.parameterGroup?.bindToInstance({});
    const isInPublicSubnet = this.vpcPlacement && this.vpcPlacement.subnetType === ec2.SubnetType.PUBLIC;
    this.newCfnProps = {
      autoMinorVersionUpgrade: props.autoMinorVersionUpgrade,
      availabilityZone: props.multiAz ? undefined : props.availabilityZone,
      backupRetentionPeriod: props.backupRetention?.toDays(),
      copyTagsToSnapshot: props.copyTagsToSnapshot ?? true,
      dbInstanceClass: Lazy.string({ produce: () => `db.${this.instanceType}` }),
      dbInstanceIdentifier: Token.isUnresolved(props.instanceIdentifier)
        // if the passed identifier is a Token,
        // we need to use the physicalName of the database
        // (we cannot change its case anyway),
        // as it might be used in a cross-environment fashion
        ? this.physicalName
        : maybeLowercasedInstanceId,
      dbSubnetGroupName: subnetGroup.subnetGroupName,
      deleteAutomatedBackups: props.deleteAutomatedBackups,
      deletionProtection: defaultDeletionProtection(props.deletionProtection, props.removalPolicy),
      enableCloudwatchLogsExports: this.cloudwatchLogsExports,
      enableIamDatabaseAuthentication: Lazy.any({ produce: () => this.enableIamAuthentication }),
      enablePerformanceInsights: enablePerformanceInsights || props.enablePerformanceInsights, // fall back to undefined if not set,
      iops,
      monitoringInterval: props.monitoringInterval?.toSeconds(),
      monitoringRoleArn: monitoringRole?.roleArn,
      multiAz: props.multiAz,
      dbParameterGroupName: instanceParameterGroupConfig?.parameterGroupName,
      optionGroupName: props.optionGroup?.optionGroupName,
      performanceInsightsKmsKeyId: props.performanceInsightEncryptionKey?.keyArn,
      performanceInsightsRetentionPeriod: enablePerformanceInsights
        ? (props.performanceInsightRetention || PerformanceInsightRetention.DEFAULT)
        : undefined,
      port: props.port !== undefined ? Tokenization.stringifyNumber(props.port) : undefined,
      preferredBackupWindow: props.preferredBackupWindow,
      preferredMaintenanceWindow: props.preferredMaintenanceWindow,
      processorFeatures: props.processorFeatures && renderProcessorFeatures(props.processorFeatures),
      publiclyAccessible: props.publiclyAccessible ?? isInPublicSubnet,
      storageType,
      storageThroughput: props.storageThroughput,
      vpcSecurityGroups: securityGroups.map(s => s.securityGroupId),
      maxAllocatedStorage: props.maxAllocatedStorage,
      domain: this.domainId,
      domainIamRoleName: this.domainRole?.roleName,
      networkType: props.networkType,
      caCertificateIdentifier: props.caCertificate ? props.caCertificate.toString() : undefined,
      applyImmediately: props.applyImmediately,
    };
  }