constructor()

in cdkworkshop.com/cdkworkshop.com.ts [54:158]


    constructor(scope: Construct, id: string, props: CdkWorkshopProps) {
        super(scope, id, props);

        this.renameLogicalId('CloudFrontDNSRecord46217411', 'CloudFrontDNSRecord');

        // Enable AWS GuardDuty in this account, and send any security findings via email
        new GuardDutyNotifier(this, "GuardDuty", {
            environmentName: props.domain,
            email: props.email
        })

        // Create DNS Zone
        const zone = new route53.PublicHostedZone(this, 'HostedZone', {
            zoneName: props.domain,
        })

        // Bucket to hold the static website
        const bucket = new s3.Bucket(this, 'Bucket', {
            websiteIndexDocument: 'index.html'
        });

        const origin = new cloudfront.OriginAccessIdentity(this, "BucketOrigin", {
            comment: props.domain,
        });
        (origin.node.defaultChild as cloudfront.CfnCloudFrontOriginAccessIdentity).overrideLogicalId('BucketOrigin');

        // Due to a bug in `BucketDeployment` (awslabs/aws-cdk#981) we must
        // deploy each version of the content to a different prefix (it's also a
        // good practice, but we plan to support that intrinsicly in
        // `BucketDeployment`).
        const contentDir = path.join(__dirname, '..', 'workshop', 'public');
        const contentHash = hashDirectorySync(contentDir);

        new s3deploy.BucketDeployment(this, 'DeployWebsite', {
            sources: [
                s3deploy.Source.asset(contentDir)
            ],
            destinationBucket: bucket,
            destinationKeyPrefix: contentHash,
            retainOnDelete: true
        });

        let acl: string | undefined
        if (props.restrictToAmazonNetwork) {
            acl = props.restrictToAmazonNetworkWebACL.toString()
        }

        const maxTtl = props.disableCache ? Duration.seconds(0) : undefined;

        // CloudFront distribution
        const cert = acm.Certificate.fromCertificateArn(this, 'Certificate', props.certificate);
        const cdn = new cloudfront.CloudFrontWebDistribution(this, 'CloudFront', {
            viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
            priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
            webACLId: acl,
            originConfigs: [{
                behaviors: [{
                    isDefaultBehavior: true,
                    maxTtl
                }],
                s3OriginSource: {
                    s3BucketSource: bucket,
                    originAccessIdentity: origin,
                    originPath: `/${contentHash}`,
                }
            }],
            viewerCertificate: cloudfront.ViewerCertificate.fromAcmCertificate(cert, {
                aliases: [props.domain],
            }),
        })

        // TODO: Model dependency from CloudFront Web Distribution on S3 Bucket Deployment

        // DNS alias for the CloudFront distribution
        new route53.ARecord(this, 'CloudFrontDNSRecord', {
            recordName: props.domain + '.',
            zone,
            target: route53.RecordTarget.fromAlias(new route53Targets.CloudFrontTarget(cdn)),
        });

        // Configure Outputs

        new CfnOutput(this, 'URL', {
            description: 'The URL of the workshop',
            value: 'https://' + props.domain,
        })

        new CfnOutput(this, 'CloudFrontURL', {
            description: 'The CloudFront distribution URL',
            value: 'https://' + cdn.distributionDomainName,
        })

        new CfnOutput(this, 'CertificateArn', {
            description: 'The SSL certificate ARN',
            value: props.certificate,
        })

        if (zone.hostedZoneNameServers) {
            new CfnOutput(this, 'Nameservers', {
                description: 'Nameservers for DNS zone',
                value: Fn.join(', ', zone.hostedZoneNameServers)
            })
        }

    }