in source/lib/stage-three.ts [46:166]
constructor(scope: cdk.Construct, id: string, props: StageThreeProps) {
super(scope, id);
// -------------------------------------------------------------------------------------------
// Treehash Calc Request Queue
const treehashCalcQueue = new sqs.Queue(this, 'treehash-calc-queue',
{
queueName: `${cdk.Aws.STACK_NAME}-treehash-calc-queue`,
retentionPeriod: cdk.Duration.days(14),
visibilityTimeout: cdk.Duration.seconds(905)
}
);
CfnNagSuppressor.addSuppression(treehashCalcQueue, 'W48', 'Non sensitive metadata - encryption is not required and cost inefficient');
treehashCalcQueue.addToResourcePolicy(iamSec.IamPermissions.sqsDenyInsecureTransport(treehashCalcQueue));
this.treehashCalcQueue = treehashCalcQueue;
// -------------------------------------------------------------------------------------------
// Archive Notification Queue
const archiveNotificationQueue = new sqs.Queue(this, 'archive-notification-queue',
{
queueName: `${cdk.Aws.STACK_NAME}-archive-notification-queue`,
visibilityTimeout: cdk.Duration.seconds(905)
}
);
CfnNagSuppressor.addSuppression(archiveNotificationQueue, 'W48', 'Non sensitive metadata - encryption is not required and cost inefficient');
archiveNotificationQueue.addToResourcePolicy(iamSec.IamPermissions.sqsDenyInsecureTransport(archiveNotificationQueue));
props.archiveNotificationTopic.addSubscription(new subscriptions.SqsSubscription(archiveNotificationQueue));
this.archiveNotificationQueue = archiveNotificationQueue;
// -------------------------------------------------------------------------------------------
// Chunk Copy Queue
const chunkCopyQueue = new sqs.Queue(this, 'chunk-copy-queue',
{
queueName: `${cdk.Aws.STACK_NAME}-chunk-copy-queue`,
visibilityTimeout: cdk.Duration.seconds(905)
}
);
CfnNagSuppressor.addSuppression(chunkCopyQueue, 'W48', 'Non sensitive metadata - encryption is not required and cost inefficient');
chunkCopyQueue.addToResourcePolicy(iamSec.IamPermissions.sqsDenyInsecureTransport(chunkCopyQueue));
// -------------------------------------------------------------------------------------------
// Split Archive into Chunks
const splitArchiveRole = new iam.Role(this, 'splitArchiveRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
});
// Declaring the policy granting access to the stream explicitly to minimize permissions
splitArchiveRole.addToPrincipalPolicy(iamSec.IamPermissions.lambdaLogGroup(`${cdk.Aws.STACK_NAME}-splitArchive`));
splitArchiveRole.addToPrincipalPolicy(iamSec.IamPermissions.glacier(props.sourceVault));
splitArchiveRole.addToPrincipalPolicy(iamSec.IamPermissions.sqsSubscriber(archiveNotificationQueue));
props.stagingBucket.grantReadWrite(splitArchiveRole);
props.statusTable.grantReadWriteData(splitArchiveRole);
chunkCopyQueue.grantSendMessages(splitArchiveRole);
treehashCalcQueue.grantSendMessages(splitArchiveRole);
const defaultSplitArchivePolicy = splitArchiveRole.node.findChild('DefaultPolicy').node.defaultChild as cdk.CfnResource;
CfnNagSuppressor.addCfnSuppression(defaultSplitArchivePolicy, 'W76', 'Policy is auto-generated by CDK');
const splitArchive = new lambda.Function(this, 'SplitArchive', {
functionName: `${cdk.Aws.STACK_NAME}-splitArchive`,
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
memorySize: 256,
timeout: cdk.Duration.minutes(15),
reservedConcurrentExecutions: 45,
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/splitArchive')),
role: splitArchiveRole.withoutPolicyUpdates(),
environment:
{
STAGING_BUCKET: props.stagingBucket.bucketName,
STAGING_BUCKET_PREFIX: 'stagingdata',
STATUS_TABLE: props.statusTable.tableName,
SQS_CHUNK: chunkCopyQueue.queueName,
SQS_HASH: treehashCalcQueue.queueName
}
});
splitArchive.node.addDependency(splitArchiveRole);
splitArchive.addEventSource(new SqsEventSource(archiveNotificationQueue, {batchSize: 1}));
CfnNagSuppressor.addLambdaSuppression(splitArchive);
// -------------------------------------------------------------------------------------------
// Copy Chunk
const copyChunkRole = new iam.Role(this, 'CopyChunkRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
});
copyChunkRole.addToPrincipalPolicy(iamSec.IamPermissions.lambdaLogGroup(`${cdk.Aws.STACK_NAME}-copyChunk`));
copyChunkRole.addToPrincipalPolicy(iamSec.IamPermissions.glacier(props.sourceVault));
copyChunkRole.addToPrincipalPolicy(iamSec.IamPermissions.sqsSubscriber(chunkCopyQueue));
const defaultCopyChunkPolicy = copyChunkRole.node.findChild('DefaultPolicy').node.defaultChild as cdk.CfnResource;
CfnNagSuppressor.addCfnSuppression(defaultCopyChunkPolicy, 'W76', 'Policy is auto-generated by CDK');
props.stagingBucket.grantReadWrite(copyChunkRole);
props.statusTable.grantReadWriteData(copyChunkRole);
props.metricTable.grantReadWriteData(copyChunkRole);
treehashCalcQueue.grantSendMessages(copyChunkRole);
const copyChunk = new lambda.Function(this, 'CopyChunk', {
functionName: `${cdk.Aws.STACK_NAME}-copyChunk`,
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
memorySize: 1024,
timeout: cdk.Duration.minutes(15),
reservedConcurrentExecutions: 35,
role: copyChunkRole.withoutPolicyUpdates(),
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/copyChunk')),
environment:
{
VAULT: props.sourceVault,
STAGING_BUCKET: props.stagingBucket.bucketName,
STAGING_BUCKET_PREFIX: 'stagingdata',
STATUS_TABLE: props.statusTable.tableName,
METRIC_TABLE: props.metricTable.tableName,
SQS_HASH: treehashCalcQueue.queueName
}
});
CfnNagSuppressor.addLambdaSuppression(copyChunk);
copyChunk.addEventSource(new SqsEventSource(chunkCopyQueue, {batchSize: 1}));
}