constructor()

in lib/static-site.ts [35:120]


    constructor(parent: Construct, name: string, props: StaticSiteProps) {
        super(parent, name);

        // Reference the hosted zone (this does not require a context lookup)
        const zone = route53.HostedZone.fromHostedZoneAttributes(this, 'Zone', {
            hostedZoneId: props.hostedZoneId, 
            zoneName: props.domainName + '.'
        });

        // Output the URL for the site
        const siteOut = new cdk.CfnOutput(this, 'Site', { value: 'https://' + props.domainName });

        // Create a bucket to hold content
        this.siteBucket = new s3.Bucket(this, 'SiteBucket', {
            websiteIndexDocument: 'index.html',
            websiteErrorDocument: 'error.html',
            publicReadAccess: false,
            removalPolicy: cdk.RemovalPolicy.RETAIN,
        });

        this.bucketName = this.siteBucket.bucketName;

        // Output the bucket name
        const bucketOut = new cdk.CfnOutput(this, 'Bucket', { value: this.siteBucket.bucketName });

        // Create an origin access identity so that the public can be private
        const oai = new cloudfront.CfnCloudFrontOriginAccessIdentity(this, 'OAI', {
            cloudFrontOriginAccessIdentityConfig: { comment: props.domainName }
        });

        // Restrict the S3 bucket via a bucket policy that only allows our CloudFront distribution
        const bucketPolicy = new PolicyStatement({
            principals: [new CanonicalUserPrincipal(oai.attrS3CanonicalUserId)],
            actions: ['s3:GetObject'],
            resources: [this.siteBucket.arnForObjects('*')],
        });
        this.siteBucket.addToResourcePolicy(bucketPolicy);

        // CloudFront
        const distribution = new cloudfront.CloudFrontWebDistribution(this, 'SiteDistribution', {
            // aliasConfiguration: {
            //     acmCertRef: props.certificateArn,
            //     names: [props.domainName],
            //     sslMethod: cloudfront.SSLMethod.SNI,
            //     securityPolicy: cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016,
            // },
            viewerCertificate: {
                aliases: [props.domainName],
                props: {
                    acmCertificateArn: props.certificateArn,
                    sslSupportMethod: cloudfront.SSLMethod.SNI,
                    minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016,
                },
            },
            originConfigs: [
                {
                    s3OriginSource: {
                        s3BucketSource: this.siteBucket,
                        originAccessIdentity: cloudfront.OriginAccessIdentity.fromOriginAccessIdentityName(this, 'OAIRef', oai.ref)
                    },
                    behaviors: [{ isDefaultBehavior: true }]
                },
            ],
        });

        // Output the distribution ID
        const distroOut = new cdk.CfnOutput(this, 'DistributionId', {
            value: distribution.distributionId
        });

        // Route53 alias record for the CloudFront distribution
        const aout = new route53.ARecord(this, 'SiteAliasRecord', {
            recordName: props.domainName,
            target: route53.RecordTarget.fromAlias(
                new targets.CloudFrontTarget(distribution)),
            zone
        });

        // Deploy contents of the folder to the S3 bucket
        this.deployment = new s3deploy.BucketDeployment(this, 'DeployWithInvalidation', {
            sources: [s3deploy.Source.asset(props.contentPath)],
            destinationBucket: this.siteBucket,
            distribution,
            distributionPaths: ['/*'],
        });
    }