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,
);
}
}