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: ['/*'],
});
}