cdk/lib/email-mvt-pixel.ts (106 lines of code) (raw):

import type { GuStackProps } from '@guardian/cdk/lib/constructs/core'; import { GuCertificateArnParameter, 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 { aws_cloudfront, Duration } from 'aws-cdk-lib'; import { Certificate } from 'aws-cdk-lib/aws-certificatemanager'; import { HttpVersion, ViewerCertificate } from 'aws-cdk-lib/aws-cloudfront'; import { AaaaRecord, ARecord, HostedZone, RecordTarget, } from 'aws-cdk-lib/aws-route53'; import { CloudFrontTarget } from 'aws-cdk-lib/aws-route53-targets'; interface EmailMVTPixelProps extends GuStackProps { app: string; } export class EmailMVTPixel extends GuStack { constructor(scope: App, id: string, props: EmailMVTPixelProps) { super(scope, id, props); const hostedZoneParameter = new GuStringParameter(this, 'Hosted Zone ID', { description: 'Hosted Zone ID of Route 53 entry', }); const hostedZoneName = new GuStringParameter(this, 'Hosted Zone Name', { description: 'Hosted Zone Name of Route 53 entry', }); const certificateArnParameter = new GuCertificateArnParameter(this, { app: props.app, }); const domainNamePrefix = `email${ props.stage === 'PROD' ? '' : `-${props.stage.toLowerCase()}` }`; const cloudfrontAlias = `${domainNamePrefix}.${hostedZoneName.valueAsString}`; const certificate = Certificate.fromCertificateArn( this, id, certificateArnParameter.valueAsString, ); const logFiles = new GuS3Bucket(this, `CloudFrontLogsS3Bucket`, { app: props.app, bucketName: `email-mvt-pixel-cloudfront-logs-${props.stage.toLowerCase()}`, lifecycleRules: [ { expiration: Duration.days(28), }, ], }); const pixelSourceFiles = new GuS3Bucket(this, 'PixelS3Bucket', { app: props.app, bucketName: `email-mvt-pixel-files-${props.stage.toLowerCase()}`, }); const originAccessIdentity = new aws_cloudfront.OriginAccessIdentity( this, `OriginAccessIdentity`, { comment: `Access Identity for ${pixelSourceFiles.bucketName}`, }, ); const distribution = new aws_cloudfront.CloudFrontWebDistribution( this, `PixelCloudFrontDistribution`, { viewerCertificate: ViewerCertificate.fromAcmCertificate(certificate, { aliases: [cloudfrontAlias], }), loggingConfig: { bucket: logFiles, }, originConfigs: [ { s3OriginSource: { s3BucketSource: pixelSourceFiles, originAccessIdentity: originAccessIdentity, }, behaviors: [{ isDefaultBehavior: true }], }, ], httpVersion: HttpVersion.HTTP2_AND_3, }, ); const hostedZone = HostedZone.fromHostedZoneAttributes( this, 'HostedZoneToSetUpCNAME', { zoneName: hostedZoneName.valueAsString, hostedZoneId: hostedZoneParameter.valueAsString, }, ); new ARecord(this, 'Route53AliasToCloudFront', { target: RecordTarget.fromAlias(new CloudFrontTarget(distribution)), zone: hostedZone, recordName: cloudfrontAlias, ttl: Duration.hours(1), }); new AaaaRecord(this, 'Route53IPv6AliasToCloudFront', { target: RecordTarget.fromAlias(new CloudFrontTarget(distribution)), zone: hostedZone, recordName: cloudfrontAlias, ttl: Duration.hours(1), }); } }