cdk/lib/email-mvt-pixel-log-archiver.ts (81 lines of code) (raw):
import { GuScheduledLambda } from '@guardian/cdk';
import type { GuStackProps } from '@guardian/cdk/lib/constructs/core';
import { GuStack } from '@guardian/cdk/lib/constructs/core';
import { GuStringParameter } from '@guardian/cdk/lib/constructs/core/parameters/base';
import { GuS3Bucket } from '@guardian/cdk/lib/constructs/s3';
import type { App } from 'aws-cdk-lib';
import { Duration } from 'aws-cdk-lib';
import { Schedule } from 'aws-cdk-lib/aws-events';
import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
export class EmailMVTPixelLogArchiver extends GuStack {
constructor(scope: App, id: string, props: GuStackProps) {
super(scope, id, props);
if (!(props.stage === 'TEST' || props.stage === 'PROD')) return;
const logFilesBucket = new GuStringParameter(this, 'Log Files Bucket', {
description: 'S3 bucket containing CloudFront log files to process',
});
const functionName = `EmailMVTPixelLogArchiverLambda-${props.stage}`;
const desinationBucketNamePrefix = props.stage === 'PROD' ? '' : `test-`;
const destinationBucketNameSuffix = 'ophan-raw-email-mvt-pixel-logs';
// Create non-source and destination buckets
if (props.stage !== 'PROD') {
new GuS3Bucket(this, `DestinationS3Bucket`, {
app: id,
bucketName: `${desinationBucketNamePrefix}${destinationBucketNameSuffix}`,
lifecycleRules: [
{
expiration: Duration.days(1),
},
],
});
}
new GuScheduledLambda(this, 'TransferLambda', {
app: 'email-mvt-pixel-log-archiver-lambda',
functionName: functionName,
fileName: `email-mvt-pixel-log-archiver-lambda.zip`,
handler: 'email-mvt-pixel-log-archiver-lambda.handler',
runtime: Runtime.NODEJS_16_X,
memorySize: 768,
timeout: Duration.seconds(60),
initialPolicy: [
new PolicyStatement({
sid: 'CreateLogGroupForFunction',
resources: ['arn:aws:logs:*:*:*'],
actions: ['logs:CreateLogGroup'],
}),
new PolicyStatement({
sid: 'EnableLambdaToLogToCloudWatch',
resources: [
`arn:aws:logs:*:*:log-group:/aws/lambda/${functionName}:*`,
],
actions: ['logs:CreateLogStream', 'logs:PutLogEvents'],
}),
new PolicyStatement({
sid: 'GiveLambdaAccessToSourceBucket',
resources: [
`arn:aws:s3:::${logFilesBucket.valueAsString}`,
`arn:aws:s3:::${logFilesBucket.valueAsString}/*`,
],
actions: ['s3:GetObject', 's3:ListBucket'],
}),
new PolicyStatement({
sid: 'GiveLambdaAccessToDestinationBucket',
resources: [
`arn:aws:s3:::${desinationBucketNamePrefix}${destinationBucketNameSuffix}/*`,
],
actions: ['s3:GetObject', 's3:PutObject', 's3:PutObjectAcl'],
}),
],
rules: [
{
schedule: Schedule.expression('cron(10 1 ? * * *)'), // 10-past-1 gives time for CW logs to update
},
],
monitoringConfiguration: { noMonitoring: true },
environment: {
source_s3_bucket: logFilesBucket.valueAsString,
destination_s3_bucket: `${desinationBucketNamePrefix}${destinationBucketNameSuffix}`,
},
});
}
}