const { CfnParameter, CfnCondition, CfnOutput, Fn, Aws } = require('aws-cdk-lib');
const dynamodb = require('aws-cdk-lib/aws-dynamodb');
const cloudwatch = require('aws-cdk-lib/aws-cloudwatch');
const sns = require('aws-cdk-lib/aws-sns');
const lambda = require('aws-cdk-lib/aws-lambda');
const iam = require('aws-cdk-lib/aws-iam');
const logs = require('aws-cdk-lib/aws-logs');
const esbuild = require('esbuild');
function zipFile(lambdaFile, target) {
return esbuild.buildSync({
entryPoints: [lambdaFile],
external: ['@aws-sdk/*'],
target: [target],
platform: 'node',
bundle: true,
write: false
}).outputFiles[0].text;
}
const bucketAVStackName = new CfnParameter(this, 'BucketAVStackName', {
description: 'CloudFormation stack name of bucketAV (if you followed our docs, the name is bucketav)',
type: 'String'
});
const table = new dynamodb.CfnTable(this, 'Table', {
attributeDefinitions: [{
attributeName: 'id',
attributeType: 'S'
}],
billingMode: 'PAY_PER_REQUEST',
keySchema: [{
attributeName: 'id',
keyType: 'HASH'
}],
sseSpecification: {
sseEnabled: true
},
timeToLiveSpecification: {
attributeName: 'ttl',
enabled: true
}
});
const subscriptionLambdaRole = new iam.CfnRole(this, 'SubscriptionLambdaRole', {
assumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [{
Effect: 'Allow',
Principal: {
Service: 'lambda.amazonaws.com'
},
Action: 'sts:AssumeRole'
}]
},
policies: [{
policyName: 'lambda',
policyDocument: {
Statement: [{
Effect: 'Allow',
Action: 'dynamodb:PutItem',
Resource: table.attrArn
}]
}
}]
});
const subscriptionLambdaFunction = new lambda.CfnFunction(this, 'SubscriptionLambdaFunction', {
code: {
zipFile: zipFile('connect-subscription.js', 'node18')
},
environment: {
variables: {
TABLE_NAME: table.ref
}
},
handler: 'index.handler',
memorySize: 1769,
role: subscriptionLambdaRole.attrArn,
runtime: 'nodejs18.x',
timeout: 60
});
const subscriptionLambdaPermission = new lambda.CfnPermission(this, 'SubscriptionLambdaPermission', {
action: 'lambda:InvokeFunction',
functionName: subscriptionLambdaFunction.ref,
principal: 'sns.amazonaws.com',
sourceArn: Fn.importValue(`${bucketAVStackName.valueAsString}-FindingsTopicArn`)
});
const subscriptionLambdaLogGroup = new logs.CfnLogGroup(this, 'SubscriptionLambdaLogGroup', {
logGroupName: `/aws/lambda/${subscriptionLambdaFunction.ref}`,
retentionInDays: 14
});
const subscriptionLambdaPolicy = new iam.CfnPolicy(this, 'SubscriptionLambdaPolicy', {
roles: [
subscriptionLambdaRole.ref
],
policyName: 'logs',
policyDocument: {
Statement: [{
Effect: 'Allow',
Action: [
'logs:CreateLogStream',
'logs:PutLogEvents'
],
Resource: subscriptionLambdaLogGroup.attrArn
}]
}
});
const subscription = new sns.CfnSubscription(this, 'Subscription', {
endpoint: subscriptionLambdaFunction.attrArn,
filterPolicy: {
trace_id: [{prefix: `bucketav:connect:${Aws.STACK_NAME}:`}]
},
protocol: 'lambda',
topicArn: Fn.importValue(`${bucketAVStackName.valueAsString}-FindingsTopicArn`)
});
subscription.addDependency(subscriptionLambdaPermission);
subscription.addDependency(subscriptionLambdaPolicy);
const connectLambdaRole = new iam.CfnRole(this, 'ConnectLambdaRole', {
assumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [{
Effect: 'Allow',
Principal: {
Service: 'lambda.amazonaws.com'
},
Action: 'sts:AssumeRole'
}]
},
policies: [{
policyName: 'lambda',
policyDocument: {
Statement: [{
Effect: 'Allow',
Action: 'sqs:SendMessage',
Resource: Fn.importValue(`${bucketAVStackName.valueAsString}-ScanQueueArn`)
}, {
Effect: 'Allow',
Action: 'dynamodb:GetItem',
Resource: table.attrArn
}]
}
}]
});
const connectLambdaFunction = new lambda.CfnFunction(this, 'ConnectLambdaFunction', {
code: {
zipFile: zipFile('connect.js', 'node18')
},
environment: {
variables: {
TABLE_NAME: table.ref,
STACK_NAME: Aws.STACK_NAME,
SCAN_QUEUE_URL: Fn.importValue(`${bucketAVStackName.valueAsString}-ScanQueueUrl`)
}
},
handler: 'index.handler',
memorySize: 1769,
role: connectLambdaRole.attrArn,
runtime: 'nodejs18.x',
timeout: 60
});
const connectLambdaLogGroup = new logs.CfnLogGroup(this, 'ConnectLambdaLogGroup', {
logGroupName: `/aws/lambda/${connectLambdaFunction.ref}`,
retentionInDays: 14
});
new iam.CfnPolicy(this, 'ConnectLambdaPolicy', {
roles: [
connectLambdaRole.ref
],
policyName: 'logs',
policyDocument: {
Statement: [{
Effect: 'Allow',
Action: [
'logs:CreateLogStream',
'logs:PutLogEvents'
],
Resource: connectLambdaLogGroup.attrArn
}]
}
});