Created
October 17, 2023 23:17
-
-
Save davideicardi/1c4b2849078766dc659afa6ab67034a7 to your computer and use it in GitHub Desktop.
AWS CDK Static Web Site stack from S3 with CloudFront and custom domain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Bucket } from 'aws-cdk-lib/aws-s3'; | |
import { BucketDeployment, Source } from 'aws-cdk-lib/aws-s3-deployment'; | |
import { CloudFrontWebDistribution, OriginProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront'; | |
import { ARecord, HostedZone, RecordTarget } from 'aws-cdk-lib/aws-route53'; | |
import { CloudFrontTarget } from 'aws-cdk-lib/aws-route53-targets'; | |
import { Construct } from 'constructs'; | |
import { aws_s3 } from 'aws-cdk-lib'; | |
interface StaticWebsiteProps { | |
domainName: string; | |
hostedZoneId: string; | |
sourceFolder: string; // relative path to the website source folder, like './out' | |
certificateArn: string; | |
} | |
export class StaticWebsiteSubStack { | |
constructor( | |
scope: Construct, | |
id: string, | |
props: StaticWebsiteProps, | |
) { | |
const websiteBucket = new Bucket(scope, `${id}-bucket`, { | |
websiteIndexDocument: 'index.html', | |
websiteErrorDocument: 'error.html', | |
publicReadAccess: true, | |
// Cause of the issue https://github.com/aws/aws-cdk/issues/25983 | |
// we've used the following workaround: | |
// https://stackoverflow.com/questions/56045776/aws-cdk-s3putbucketpolicy-access-denied-when-deploying-bucket-with-public-read | |
blockPublicAccess: aws_s3.BlockPublicAccess.BLOCK_ACLS, | |
accessControl: aws_s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL, | |
}); | |
const distribution = new CloudFrontWebDistribution(scope, `${id}-cloudfront-dist`, { | |
originConfigs: [ | |
{ | |
customOriginSource: { | |
domainName: websiteBucket.bucketWebsiteDomainName, | |
originProtocolPolicy: OriginProtocolPolicy.HTTP_ONLY, | |
}, | |
behaviors: [{ isDefaultBehavior: true }], | |
}, | |
], | |
viewerCertificate: { | |
aliases: [props.domainName], | |
props: { | |
acmCertificateArn: props.certificateArn, | |
sslSupportMethod: 'sni-only', | |
}, | |
}, | |
}); | |
new BucketDeployment(scope, `${id}-bucket-deployment`, { | |
sources: [Source.asset(props.sourceFolder)], | |
destinationBucket: websiteBucket, | |
distribution: distribution, // invalidate distribution on deploy | |
}); | |
const hostedZone = HostedZone.fromHostedZoneAttributes(scope, `${id}-hosted-zone`, { | |
hostedZoneId: props.hostedZoneId, | |
zoneName: props.domainName, // assuming the hosted zone is the same as the domain name | |
}); | |
new ARecord(scope, `${id}-a-record`, { | |
zone: hostedZone, | |
recordName: props.domainName, | |
target: RecordTarget.fromAlias(new CloudFrontTarget(distribution)), | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment