constructor()

in packages/aws-rfdk/lib/core/lib/mongodb-instance.ts [407:493]


  constructor(scope: Construct, id: string, props: MongoDbInstanceProps) {
    super(scope, id);

    this.version = props.mongoDb.version;

    // Select the subnet for this instance.
    const { subnets } = props.vpc.selectSubnets(props.vpcSubnets);
    if (subnets.length === 0) {
      throw new Error(`Did not find any subnets matching ${JSON.stringify(props.vpcSubnets)}. Please use a different selection.`);
    }
    const subnet = subnets[0];

    this.server = new StaticPrivateIpServer(this, 'Server', {
      vpc: props.vpc,
      vpcSubnets: { subnets: [ subnet ] },
      instanceType: props.instanceType ?? new InstanceType('r5.large'),
      machineImage: MachineImage.latestAmazonLinux2023(),
      blockDevices: [
        {
          deviceName: '/dev/xvda', // Root volume
          volume: BlockDeviceVolume.ebs(MongoDbInstance.ROOT_DEVICE_SIZE.toGibibytes(), { encrypted: true }),
        },
      ],
      keyName: props.keyName,
      resourceSignalTimeout: Duration.minutes(5),
      role: props.role,
      securityGroup: props.securityGroup,
    });

    new ARecord(this, 'ARecord', {
      target: RecordTarget.fromIpAddresses(this.server.privateIpAddress),
      zone: props.mongoDb.dnsZone,
      recordName: props.mongoDb.hostname,
    });

    this.adminUser = props.mongoDb.adminUser ?? new Secret(this, 'AdminUser', {
      description: `Admin credentials for the MongoDB database ${Names.uniqueId(this)}`,
      generateSecretString: {
        excludeCharacters: '"()$\'', // Exclude characters that might interact with command shells.
        excludePunctuation: true,
        includeSpace: false,
        passwordLength: 24,
        requireEachIncludedType: true,
        generateStringKey: 'password',
        secretStringTemplate: JSON.stringify({ username: 'admin' }),
      },
    });

    this.mongoDataVolume = props.mongoDb.mongoDataVolume?.volume ?? new Volume(this, 'MongoDbData', {
      size: MongoDbInstance.DEFAULT_MONGO_DEVICE_SIZE, // First so it can be overriden by the next entry
      ...props.mongoDb.mongoDataVolume?.volumeProps,
      availabilityZone: subnet.availabilityZone,
      encrypted: true,
    });
    const volumeMount = new MountableBlockVolume(this, {
      blockVolume: this.mongoDataVolume,
      volumeFormat: BlockVolumeFormat.XFS,
    });

    const mongoInstaller = new MongoDbInstaller(this, {
      version: props.mongoDb.version,
      userSsplAcceptance: props.mongoDb.userSsplAcceptance,
    });

    // Set up the server's UserData.
    this.server.userData.addCommands('set -xefuo pipefail');
    this.server.userData.addSignalOnExitCommand(this.server.autoscalingGroup);
    this.configureCloudWatchLogStreams(this.server, id, props.logGroupProps); // MUST BE FIRST
    volumeMount.mountToLinuxInstance(this.server, {
      location: MongoDbInstance.MONGO_DEVICE_MOUNT_POINT,
    });
    mongoInstaller.installOnLinuxInstance(this.server);
    this.configureMongoDb(this.server, props.mongoDb);

    this.certificateChain = props.mongoDb.serverCertificate.certChain!;
    this.connections = this.server.connections;
    this.grantPrincipal = this.server.grantPrincipal;
    this.port = 27017;
    this.role = this.server.role;
    this.userData = this.server.userData;
    this.fullHostname = `${props.mongoDb.hostname}.${props.mongoDb.dnsZone.zoneName}`;

    this.node.defaultChild = this.server;

    // Tag deployed resources with RFDK meta-data
    tagConstruct(this);
  }