Host Static website using AWS CDK for Terraform
This repo contains the code for DEV.to blog
Posted on August 7, 2020
In part 1, we saw how we can host our website using S3. In this part, we will see how we can configure AWS CloudFront to serve our S3 bucket objects as website. In case, if you have not checked out the Part 1, please read this first.
Let's setup CloudFront distribution using AWS CDK of Terraform. We need to create CloudFront Origin Access Identity(OAI), which we will use for CloudFront and S3 bucket policy.
import { CloudfrontOriginAccessIdentity } from './.gen/providers/aws';
/*
* Create am Origin Access Identity
* Doc link: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/
* Tutorial link: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/
*/
const cloudfrontOriginAccessIdentity = new CloudfrontOriginAccessIdentity(this, 'aws_cloudfront_origin_access_identity', {
comment: 's3-cloudfront-cdk-example'
})
Now, we need to set few required parameters for the CloudFront configuration.
index.html
is our default file that we need to serve.import { CloudfrontDistribution } from './.gen/providers/aws';
const originId = `S3-${BUCKET_NAME}`;
const cloudFrontDistribution = new CloudfrontDistribution(this, `aws_cloudfront_${BUCKET_NAME}`, {
enabled: true,
dependsOn: [bucket],
defaultRootObject: 'index.html',
customErrorResponse: [{
errorCode: 404,
responseCode: 200,
responsePagePath: '/index.html'
}],
origin: [{
originId: originId,
domainName: bucket.bucketDomainName,
s3OriginConfig: [{
originAccessIdentity: cloudfrontOriginAccessIdentity.cloudfrontAccessIdentityPath
}]
}],
defaultCacheBehavior: [{
allowedMethods: ['GET', 'HEAD'],
cachedMethods: ['GET', 'HEAD'],
forwardedValues: [{
cookies: [{ forward: 'none' }],
queryString: false
}],
targetOriginId: originId,
viewerProtocolPolicy: 'allow-all'
}],
restrictions: [{
geoRestriction: [{
restrictionType: 'none'
}]
}],
viewerCertificate: [{
cloudfrontDefaultCertificate: true
}],
});
Previously, our bucket was public, it means anyone can access bucket objects using bucket website URL. Now, we have configured CloudFront to serve our website, so it's time to block that access. With this, our website will be only accessible by CloudFront URL only. No-one will be able to access bucket objects using S3 website URL.
bucket.acl = 'private' // Set bucket ACL as private
bucket.website = [] // Disable website hosting feature
bucket.policy = `{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${cloudfrontOriginAccessIdentity.id}"
},
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::${BUCKET_NAME}/*"
]
}
]
}`
Last, we will print the CloudFront url, which will serve our s3 objects as a website.
// Output the cloudfront url to access the website
new TerraformOutput(this, 'cloudfront_website_endpoint', {
description: 'CloudFront URL',
value: `https://${cloudFrontDistribution.domainName}`
});
Now, we follow the same process to deploy the changes as per the Part 1. After successfull deployment, CloudFront public URL will be printed on the console and we will be able to access our website with default https certificate.
So this is how, we can setup CloudFront with AWS S3 using AWS CDK for Terraform.
This repo contains the code for DEV.to blog
Posted on August 7, 2020
Sign up to receive the latest update from our blog.