constructor()

in packages/@aws-cdk/aws-neptune-alpha/lib/cluster.ts [618:752]


  constructor(scope: Construct, id: string, props: DatabaseClusterProps) {
    super(scope, id);
    // Enhanced CDK Analytics Telemetry
    addConstructMetadata(this, props);

    this.vpc = props.vpc;
    this.vpcSubnets = props.vpcSubnets ?? { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS };

    // Determine the subnet(s) to deploy the Neptune cluster to
    const { subnetIds, internetConnectivityEstablished } = this.vpc.selectSubnets(this.vpcSubnets);

    // Cannot test whether the subnets are in different AZs, but at least we can test the amount.
    if (subnetIds.length < 2) {
      throw new Error(`Cluster requires at least 2 subnets, got ${subnetIds.length}`);
    }

    this.subnetGroup = props.subnetGroup ?? new SubnetGroup(this, 'Subnets', {
      description: `Subnets for ${id} database`,
      vpc: this.vpc,
      vpcSubnets: this.vpcSubnets,
      removalPolicy: props.removalPolicy === RemovalPolicy.RETAIN ? props.removalPolicy : undefined,
    });

    const securityGroups = props.securityGroups ?? [
      new ec2.SecurityGroup(this, 'SecurityGroup', {
        description: 'Neptune security group',
        vpc: this.vpc,
      }),
    ];

    // Default to encrypted storage
    const storageEncrypted = props.storageEncrypted ?? true;

    if (props.kmsKey && !storageEncrypted) {
      throw new Error('KMS key supplied but storageEncrypted is false');
    }

    const deletionProtection = props.deletionProtection ?? (props.removalPolicy === RemovalPolicy.RETAIN ? true : undefined);

    this.enableIamAuthentication = props.iamAuthentication;

    if (props.instanceType === InstanceType.SERVERLESS && !props.serverlessScalingConfiguration) {
      throw new Error('You need to specify a serverless scaling configuration with a db.serverless instance type.');
    }

    this.validateServerlessScalingConfiguration(props.serverlessScalingConfiguration);

    // Create the Neptune cluster
    const cluster = new CfnDBCluster(this, 'Resource', {
      // Basic
      engineVersion: props.engineVersion?.version,
      dbClusterIdentifier: props.dbClusterName,
      dbSubnetGroupName: this.subnetGroup.subnetGroupName,
      vpcSecurityGroupIds: securityGroups.map(sg => sg.securityGroupId),
      dbClusterParameterGroupName: props.clusterParameterGroup?.clusterParameterGroupName,
      deletionProtection: deletionProtection,
      associatedRoles: props.associatedRoles ? props.associatedRoles.map(role => ({ roleArn: role.roleArn })) : undefined,
      iamAuthEnabled: Lazy.any({ produce: () => this.enableIamAuthentication }),
      dbPort: props.port,
      // Backup
      backupRetentionPeriod: props.backupRetention?.toDays(),
      preferredBackupWindow: props.preferredBackupWindow,
      preferredMaintenanceWindow: props.preferredMaintenanceWindow,
      // Encryption
      kmsKeyId: props.kmsKey?.keyArn,
      // CloudWatch Logs exports
      enableCloudwatchLogsExports: props.cloudwatchLogsExports?.map(logType => logType.value),
      storageEncrypted,
      serverlessScalingConfiguration: props.serverlessScalingConfiguration,
      // Tags
      copyTagsToSnapshot: props.copyTagsToSnapshot,
    });

    cluster.applyRemovalPolicy(props.removalPolicy, {
      applyToUpdateReplacePolicy: true,
    });

    this.clusterIdentifier = cluster.ref;
    this.clusterResourceIdentifier = cluster.attrClusterResourceId;

    const port = Token.asNumber(cluster.attrPort);
    this.clusterEndpoint = new Endpoint(cluster.attrEndpoint, port);
    this.clusterReadEndpoint = new Endpoint(cluster.attrReadEndpoint, port);

    // Log retention
    const retention = props.cloudwatchLogsRetention;
    if (retention) {
      props.cloudwatchLogsExports?.forEach(logType => {
        new logs.LogRetention(this, `${logType.value}LogRetention`, {
          logGroupName: `/aws/neptune/${this.clusterIdentifier}/${logType.value}`,
          role: props.cloudwatchLogsRetentionRole,
          retention,
        });
      });
    }

    // Create the instances
    const instanceCount = props.instances ?? DatabaseCluster.DEFAULT_NUM_INSTANCES;
    if (instanceCount < 1) {
      throw new Error('At least one instance is required');
    }

    for (let i = 0; i < instanceCount; i++) {
      const instanceIndex = i + 1;

      const instanceIdentifier = props.instanceIdentifierBase != null ? `${props.instanceIdentifierBase}${instanceIndex}`
        : props.dbClusterName != null ? `${props.dbClusterName}instance${instanceIndex}` : undefined;

      const instance = new CfnDBInstance(this, `Instance${instanceIndex}`, {
        // Link to cluster
        dbClusterIdentifier: cluster.ref,
        dbInstanceIdentifier: instanceIdentifier,
        // Instance properties
        dbInstanceClass: props.instanceType._instanceType,
        dbParameterGroupName: props.parameterGroup?.parameterGroupName,
        autoMinorVersionUpgrade: props.autoMinorVersionUpgrade === true,
      });

      // We must have a dependency on the NAT gateway provider here to create
      // things in the right order.
      instance.node.addDependency(internetConnectivityEstablished);

      instance.applyRemovalPolicy(props.removalPolicy, {
        applyToUpdateReplacePolicy: true,
      });

      this.instanceIdentifiers.push(instance.ref);
      this.instanceEndpoints.push(new Endpoint(instance.attrEndpoint, port));
    }

    this.connections = new ec2.Connections({
      defaultPort: ec2.Port.tcp(port),
      securityGroups: securityGroups,
    });
  }