export async function step2()

in src/deployments/cdk/src/deployments/opensearch-siem/step-2.ts [61:264]


export async function step2(props: OpenSearchSIEMStep2Props) {
  const {
    accountStacks,
    config,
    outputs,
    vpcs,
    logArchiveBucket,
    context,
    aesLogArchiveBucket,
    processingTimeout = 900,
  } = props;

  for (const [accountKey, accountConfig] of config.getMandatoryAccountConfigs()) {
    const openSearchClusters = StructuredOutput.fromOutputs(outputs, {
      accountKey,
      type: OpenSearchClusterDNSOutput,
    });
    const openSearchClusterExists = openSearchClusters.length === 1;

    console.log(`OpenSearchSiem-Step1: ${openSearchClusterExists}`);

    const openSearchSIEMDeploymentConfig = accountConfig.deployments?.siem;
    if (!openSearchSIEMDeploymentConfig || !openSearchSIEMDeploymentConfig.deploy) {
      // If cluster doesn't exist, based on data in output, and the SIEM section has been removed or marked deployed false
      // continue. ie, this would remove aws resources from the stack.
      continue;
    }

    if (openSearchSIEMDeploymentConfig === undefined) {
      console.warn(`Could not find the SIEM configuration`);
      continue;
    }

    const vpc = vpcs.find(v => v.name === openSearchSIEMDeploymentConfig['vpc-name']);
    if (!vpc) {
      console.log(
        `Skipping OpenSearch deployment because of missing VPC "${openSearchSIEMDeploymentConfig['vpc-name']}"`,
      );
      continue;
    }

    const accountStack = accountStacks.tryGetOrCreateAccountStack(accountKey);
    if (!accountStack) {
      console.warn(`Cannot find account stack ${accountKey}`);
      continue;
    }

    const accountEbsEncryptionKeys = StructuredOutput.fromOutputs(outputs, {
      accountKey,
      type: EbsKmsOutput,
    });
    if (accountEbsEncryptionKeys.length !== 1) {
      console.warn(`Cannot find required EBS KMS Key role in account "${accountKey}"`);
      return;
    }
    const accountEbsEncryptionKeyId = accountEbsEncryptionKeys[0].encryptionKeyId;

    const domainSubnetIds: string[] = [];
    for (const subnetConfig of openSearchSIEMDeploymentConfig['app-subnets']) {
      const subnet = vpc.tryFindSubnetByNameAndAvailabilityZone(subnetConfig.name, subnetConfig.az);
      if (!subnet) {
        console.warn(
          `Cannot find app subnet with name "${subnetConfig.name}" in availability zone "${subnetConfig.az}"`,
        );
        continue;
      }
      domainSubnetIds.push(subnet.id);
    }

    if (domainSubnetIds.length === 0) {
      console.log(
        `Skipping OpenSearch deployment because of missing app subnets "${openSearchSIEMDeploymentConfig['app-subnets']}"`,
      );
      return;
    }

    const openSearchSiemProcessingRoleOutput = StructuredOutput.fromOutputs(outputs, {
      accountKey,
      type: OpenSearchLambdaProcessingRoleOutput,
    });
    if (openSearchSiemProcessingRoleOutput.length !== 1) {
      console.warn(`Cannot find required OpenSearchSiemProcessing role in account "${accountKey}"`);
      return;
    }
    const openSearchSiemProcessingRoleArn = openSearchSiemProcessingRoleOutput[0].roleArn;

    const logGroupLambdaRoleOutput = IamRoleOutputFinder.tryFindOneByName({
      outputs,
      accountKey,
      roleKey: 'LogGroupRole',
    });

    if (!logGroupLambdaRoleOutput) {
      console.warn(`Cannot find required LogGroupLambda role in account "${accountKey}"`);
      return;
    }

    const logAccountKey = config.getMandatoryAccountKey('central-log');
    const logArchiveStack = accountStacks.getOrCreateAccountStack(logAccountKey);

    // Central Bucket
    const masterAccountKey = config.getMandatoryAccountKey('master');
    const centralBucketOutput = CentralBucketOutputFinder.findOneByName({
      outputs,
      accountKey: masterAccountKey,
    });

    // creating security group for the instance
    const securityGroup = new SecurityGroup(accountStack, `OpenSearchSiemSG${accountKey}`, {
      securityGroups: openSearchSIEMDeploymentConfig['security-groups'],
      accountKey,
      vpcId: vpc.id,
      vpcName: vpc.name,
      installerVersion: context.installerVersion,
    });
    const securityGroupId = securityGroup.securityGroups[0].id;

    const azs = new Set(vpc.subnets.map(x => x.az));

    const lambdaRole = iam.Role.fromRoleArn(
      accountStack,
      `${context.acceleratorPrefix}OpenSearchSiemProcessEventsLambdaRole`,
      openSearchSiemProcessingRoleArn,
      {
        mutable: true,
      },
    );

    const domain = createOpenSearchCluster(
      accountKey,
      openSearchSIEMDeploymentConfig,
      accountStack,
      context.acceleratorPrefix,
      accountEbsEncryptionKeyId,
      logGroupLambdaRoleOutput.roleArn,
      domainSubnetIds,
      [securityGroupId],
      vpc,
      [...azs],
      lambdaRole,
      centralBucketOutput.bucketName,
    );

    const configBucket = s3.Bucket.fromBucketName(accountStack, 'ConfigBucket', centralBucketOutput.bucketName);
    const cdkVpc = ec2.Vpc.fromVpcAttributes(accountStack, 'OpenSearchVPCLookupAttr', {
      vpcId: vpc.id,
      availabilityZones: [...azs],
      privateSubnetIds: domainSubnetIds,
    });

    const vpcSecurityGroups: ec2.ISecurityGroup[] = [];
    for (const sg of securityGroup.securityGroups) {
      const tmp = ec2.SecurityGroup.fromSecurityGroupId(accountStack, `OpenSearchVPCLookup-${sg.name}`, sg.id);
      vpcSecurityGroups.push(tmp);
    }

    const maxMindLicense = openSearchSIEMDeploymentConfig['maxmind-license'];
    let geoUploadBucket: s3.IBucket | undefined;
    if (maxMindLicense) {
      geoUploadBucket = new s3.Bucket(accountStack, `${context.acceleratorPrefix}OpenSearchSiem`, {
        encryption: s3.BucketEncryption.S3_MANAGED,
        blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
        removalPolicy: cdk.RemovalPolicy.RETAIN,
        enforceSSL: true,
      });

      geoUploadBucket.addToResourcePolicy(
        new iam.PolicyStatement({
          actions: ['s3:GetObject*'],
          resources: [geoUploadBucket.arnForObjects('*')],
          principals: [lambdaRole],
        }),
      );

      createGeoIpDownloader(
        cdkVpc,
        domainSubnetIds,
        vpcSecurityGroups,
        accountStack,
        context.acceleratorPrefix,
        configBucket,
        maxMindLicense,
        geoUploadBucket,
      );
    }

    const lambdaProcessingFile = openSearchSIEMDeploymentConfig['event-processor-lambda-package'];
    createProcessingLambda(
      cdkVpc,
      domainSubnetIds,
      vpcSecurityGroups,
      accountStack,
      context.acceleratorPrefix,
      processingTimeout,
      lambdaRole,
      configBucket,
      lambdaProcessingFile,
      domain.dns,
      logArchiveStack.accountId,
      [aesLogArchiveBucket, logArchiveBucket],
      geoUploadBucket,
    );
  }
}