Skip to content

Instantly share code, notes, and snippets.

@therightstuff
Last active March 5, 2023 22:15
Show Gist options
  • Save therightstuff/cba78113aa48fb0ba7c5348940597ec7 to your computer and use it in GitHub Desktop.
Save therightstuff/cba78113aa48fb0ba7c5348940597ec7 to your computer and use it in GitHub Desktop.
Connecting a domain to a static-hosted S3 website with CDK 2
// ************************************************************************
// ************************ s3 bucket static website **********************
// ************************************************************************
// NOTE: See README.md for instructions on how to configure a Hosted Zone.
// CAUTION: Hosted Zones are not free, nor is their usage. Each domain you
// configure will cost you a minimum of $0.50 per month (assuming
// reasonable use)
// See https://aws.amazon.com/route53/pricing/ for more details.
const domainName = "example.com";
if (domainName) {
// Many thanks to https://blog.dennisokeeffe.com/blog/2020-11-04-deploying-websites-to-aws-s3-with-the-cdk
// and GitHub Copilot for this example!
let zone;
try {
zone = HostedZone.fromLookup(this, domainName, {
domainName,
});
} catch (err) {
// throw a wrapped error to make it easier to find in the logs
throw new WrappedError(`Hosted zone not found / region not specified for stack ${id} with region options ${props}.`, err);
}
// create the site bucket
const siteBucket = new Bucket(this, "static-website", {
bucketName: domainName,
websiteIndexDocument: "index.html",
publicReadAccess: true, // your bucket will be browsable directly via unsecured HTTP
removalPolicy: RemovalPolicy.DESTROY, // NOT recommended for production code
autoDeleteObjects: true, // NOT recommended for production code
});
// Uncomment the lines related to the subdomain if you want it connected as well
// const subdomainName = `www.${domainName}`;
// TLS certificate
const dnsValidatedCertificate = new DnsValidatedCertificate(
this,
"SiteCertificate",
{
domainName: domainName,
// subjectAlternativeNames: [subdomainName],
hostedZone: zone,
region: "us-east-1", // Cloudfront only checks us-east-1 (N. Virginia) for certificates.
}
);
// CloudFront distribution that provides HTTPS
const distribution = new CloudFrontWebDistribution(
this,
"SiteDistribution",
{
viewerCertificate: {
aliases: [domainName /*, subdomainName*/],
props: {
acmCertificateArn: dnsValidatedCertificate.certificateArn,
sslSupportMethod: SSLMethod.SNI,
minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_1_2016,
},
},
originConfigs: [
{
s3OriginSource: {
s3BucketSource: siteBucket,
},
behaviors: [{ isDefaultBehavior: true }],
},
],
}
);
// Route53 record for the naked domain
new ARecord(this, "SiteAliasRecord", {
recordName: domainName,
target: RecordTarget.fromAlias(
new targets.CloudFrontTarget(distribution)
),
zone,
});
// Route53 record for the subdomain
/*new CnameRecord(this, "SiteCnameRecord", {
recordName: subdomainName,
domainName: distribution.distributionDomainName,
zone,
});*/
// Deploy the static website to the site bucket
// The contents of ./static-website are the contents of the website's root folder
// The distribution must be specified in order to perform cache invalidation, up
// to 1000 invalidations free per month
new BucketDeployment(this, "static-website-deployment", {
sources: [Source.asset("./static-website")],
destinationBucket: siteBucket,
distribution: distribution
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment