private createCluster()

in packages/constructs/L3/analytics/datawarehouse-l3-construct/lib/datawarehouse-l3-construct.ts [411:538]


  private createCluster(warehouseKmsKey: MdaaKmsKey, executionRoles?: IMdaaRole[], loggingBucket?: IBucket): Cluster {
    const vpc = Vpc.fromVpcAttributes(this.scope, `vpc-${this.props.vpcId}`, {
      vpcId: this.props.vpcId,
      availabilityZones: ['dummy'],
      privateSubnetIds: this.props.subnetIds,
    });

    const subnets = this.props.subnetIds.map(id => Subnet.fromSubnetId(this.scope, `subnet-${id}`, id));
    const clusterPort = this.props.clusterPort || DataWarehouseL3Construct.defaultClusterPort;
    //Create subnet group
    const subnetGroup = new ClusterSubnetGroup(this.scope, 'subnet-group', {
      description: this.props.naming.resourceName('subnet-group'),
      vpc: vpc,
      removalPolicy: RemovalPolicy.RETAIN,
      vpcSubnets: {
        subnets: subnets,
      },
    });

    const securityGroupIngress: MdaaSecurityGroupRuleProps = {
      ipv4: this.props.securityGroupIngress.ipv4?.map(x => {
        return {
          cidr: x,
          port: clusterPort,
          protocol: Protocol.TCP,
          description: `Redshift Ingress for IPV4 CIDR ${x}`,
        };
      }),
      sg: this.props.securityGroupIngress.sg?.map(x => {
        return { sgId: x, port: clusterPort, protocol: Protocol.TCP, description: `Redshift Ingress for SG ${x}` };
      }),
    };

    //Create security group
    const securityGroup = new MdaaSecurityGroup(this.scope, 'warehouse-sg', {
      naming: this.props.naming,
      securityGroupName: 'warehouse-sg',
      vpc: vpc,
      allowAllOutbound: true,
      addSelfReferenceRule: false,
      ingressRules: securityGroupIngress,
    });

    securityGroup.addIngressRule(securityGroup, Port.allTcp(), 'Self-Ref');

    let clusterType: ClusterType = ClusterType.MULTI_NODE;
    if (this.props.multiNode != undefined) {
      clusterType = this.props.multiNode ? ClusterType.MULTI_NODE : ClusterType.SINGLE_NODE;
    }

    //ClusterParameterGroup
    //Override security related parameters
    const parameters = this.props.parameterGroupParams || {};

    //Inject Workload Management Config into Param Group
    parameters['wlm_json_configuration'] = JSON.stringify(this.props.workloadManagement);
    const parameterGroup = new MdaaRedshiftClusterParameterGroup(this.scope, 'cluster-param-group', {
      parameters: parameters,
      naming: this.props.naming,
    });

    const loggingProperties = loggingBucket
      ? {
          loggingBucket: loggingBucket,
          loggingKeyPrefix: 'logging/',
        }
      : undefined;

    const dbName = this.props.dbName || 'default_db';
    // if snapshotIdentifier is provided, add to the cluster props
    // if snapshotOwnerAccount is provided add it to cluster props
    const snapshotProps: { snapshotIdentifier?: string; ownerAccount?: number } = {};
    if (this.props.snapshotIdentifier) {
      snapshotProps.snapshotIdentifier = this.props.snapshotIdentifier;
    }
    if (this.props.snapshotOwnerAccount) {
      snapshotProps.ownerAccount = this.props.snapshotOwnerAccount;
    }

    //Create the cluster
    const cluster = new MdaaRedshiftCluster(this.scope, 'cluster', {
      masterUsername: this.props.adminUsername,
      vpc: vpc,
      port: clusterPort,
      roles: executionRoles,
      encryptionKey: warehouseKmsKey,
      nodeType: NodeType[this.props.nodeType as keyof typeof NodeType],
      numberOfNodes: this.props.numberOfNodes,
      securityGroup: securityGroup,
      subnetGroup: subnetGroup,
      preferredMaintenanceWindow: this.props.preferredMaintenanceWindow,
      clusterType: clusterType,
      parameterGroup: parameterGroup,
      loggingProperties: loggingProperties,
      naming: this.props.naming,
      adminPasswordRotationDays: this.props.adminPasswordRotationDays,
      automatedSnapshotRetentionDays: this.props.automatedSnapshotRetentionDays,
      defaultDatabaseName: dbName,
      ...snapshotProps,
      redshiftManageMasterPassword: this.props.redshiftManageMasterPassword,
    });

    //Roles to grant SAML federated users access to the warehouse
    //Establishes trust with SAML identity providers
    this.props.federations?.forEach(federation => {
      this.createFederation(cluster.clusterName, federation);
    });

    if (!loggingBucket) {
      MdaaNagSuppressions.addCodeResourceSuppressions(
        cluster,
        [
          {
            id: 'AwsSolutions-RS5',
            reason:
              'Audit logging to S3 is disabled in config. Audit logging to system tables is enforced in Construct.',
          },
          {
            id: 'NIST.800.53.R5-RedshiftClusterConfiguration',
            reason: 'Audit logging to S3 is disabled in config. Cluster encryption using KMS is enforced in Construct.',
          },
        ],
        true,
      );
    }

    return cluster;
  }