constructor()

in cdk/lib/generate-product-catalog.ts [21:118]


	constructor(scope: App, id: string, props: GenerateProductCatalogProps) {
		super(scope, id, props);

		const app = 'generate-product-catalog';
		const nameWithStage = `${app}-${this.stage}`;

		const commonEnvironmentVariables = {
			App: app,
			Stack: this.stack,
			Stage: this.stage,
		};

		const lambda = new GuLambdaFunction(this, `${app}-lambda`, {
			description:
				'A lambda to generate the Guardian product catalog from the Zuora catalog',
			functionName: nameWithStage,
			fileName: `${app}.zip`,
			handler: 'index.handler',
			runtime: nodeVersion,
			memorySize: 1024,
			timeout: Duration.seconds(300),
			environment: commonEnvironmentVariables,
			app: app,
		});

		const zuoraCatalogBucketName = 'gu-zuora-catalog';
		const productCatalogBucketName = 'gu-product-catalog';
		const zuoraCatalogFolder = `PROD/Zuora-${this.stage}`;
		const zuoraCatalogBucket = Bucket.fromBucketName(
			this,
			zuoraCatalogBucketName,
			zuoraCatalogBucketName,
		);

		zuoraCatalogBucket.addEventNotification(
			EventType.OBJECT_CREATED,
			new LambdaDestination(lambda),
			{
				prefix: zuoraCatalogFolder,
			},
		);

		const productCatalogBucket = Bucket.fromBucketName(
			this,
			productCatalogBucketName,
			productCatalogBucketName,
		);

		const s3InlinePolicy: Policy = new Policy(this, 'S3 inline policy', {
			statements: [
				new PolicyStatement({
					effect: Effect.ALLOW,
					actions: ['s3:GetObject'],
					resources: [
						`arn:aws:s3::*:membership-dist/${this.stack}/${this.stage}/${app}/`,
						`arn:aws:s3::*:gu-zuora-catalog/${zuoraCatalogFolder}/*`,
					],
				}),
				new PolicyStatement({
					effect: Effect.ALLOW,
					actions: ['s3:PutObject'],
					resources: [`${productCatalogBucket.bucketArn}/${this.stage}/*`],
				}),
			],
		});

		lambda.role?.attachInlinePolicy(s3InlinePolicy);

		new GuCname(this, 'NS1 DNS entry', {
			app: app,
			domainName: props.domainName,
			ttl: Duration.hours(1),
			resourceRecord: 'guardian.map.fastly.net',
		});

		if (this.stage === 'PROD') {
			new GuAlarm(this, `FailedProductCatalogLambdaAlarm`, {
				app,
				alarmName: `The ${app} Lambda has failed`,
				alarmDescription:
					'This means the product catalog may not be up to date in S3. This lambda runs on a regular schedule so action will only be necessary if the alarm is triggered continuously',
				evaluationPeriods: 1,
				threshold: 1,
				snsTopicName: `alarms-handler-topic-${this.stage}`,
				comparisonOperator:
					ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
				metric: new Metric({
					metricName: 'Errors',
					namespace: 'AWS/Lambda',
					statistic: 'Sum',
					period: Duration.seconds(300),
					dimensionsMap: {
						FunctionName: lambda.functionName,
					},
				}),
			});
		}
	}