Skip to content

Instantly share code, notes, and snippets.

@MikeBild
Created April 8, 2019 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikeBild/36cc2d60b3b736f4c5725149f8247eca to your computer and use it in GitHub Desktop.
Save MikeBild/36cc2d60b3b736f4c5725149f8247eca to your computer and use it in GitHub Desktop.
AWS-CDK CloudFront CDN + S3 WebSite deployment with automatic cache invalidation
const { join } = require('path');
const { Stack, RemovalPolicy, ScopedAws, CfnOutput } = require('@aws-cdk/cdk');
const { Bucket } = require('@aws-cdk/aws-s3');
const { BucketDeployment, Source } = require('@aws-cdk/aws-s3-deployment');
const {
CloudFrontWebDistribution,
ViewerProtocolPolicy,
PriceClass,
OriginProtocolPolicy,
} = require('@aws-cdk/aws-cloudfront');
const { HostedZoneProvider, AliasRecord } = require('@aws-cdk/aws-route53');
module.exports = class WebSite extends Stack {
constructor(parent, id, props) {
super(parent, id, props);
const { domainName, hostName, certificateArn: acmCertRef } = props;
const region = new ScopedAws(this).region;
const webSiteBucket = new Bucket(this, 'WebSiteBucket', {
bucketName: `${hostName}.${domainName}`,
websiteIndexDocument: 'index.html',
websiteErrorDocument: '404.html',
publicReadAccess: true,
removalPolicy: RemovalPolicy.Orphan,
retainOnDelete: false,
versioned: true,
});
const deployment = new BucketDeployment(this, 'WebSiteDeployment', {
source: Source.asset(join(__dirname, '../public')),
destinationBucket: webSiteBucket,
retainOnDelete: false,
});
const distribution = new CloudFrontWebDistribution(
this,
'WebSiteDistribution',
{
aliasConfiguration: {
names: [`${hostName}.${domainName}`],
acmCertRef,
},
viewerProtocolPolicy: ViewerProtocolPolicy.RedirectToHTTPS,
priceClass: PriceClass.PriceClass100,
originConfigs: [
{
customOriginSource: {
originProtocolPolicy: OriginProtocolPolicy.HttpOnly,
domainName: `${
webSiteBucket.bucketName
}.s3-website.${region}.amazonaws.com`,
},
behaviors: [
{
forwardedValues: {
headers: [],
queryString: true,
},
isDefaultBehavior: true,
compress: true,
minTtlSeconds: 0,
maxTtlSeconds: 31536000,
defaultTtlSeconds: 86400,
},
],
},
],
}
);
const zone = new HostedZoneProvider(this, {
domainName,
}).findAndImport(this, domainName);
new AliasRecord(this, 'WebSiteAliasRecord', {
zone,
recordName: `${hostName}.${domainName}`,
target: distribution,
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment