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.
- dependsOn: Bucket is required to setup CloudFront.
- defaultRootObject:
index.html
is our default file that we need to serve. - customErrorResponse: We can setup custom rules/response for errors like 400, 404, 500, 501 etc.
- origin:
- originId: unique id (should be same as targetOriginId)
- domainName: S3 bucket as domain (eg. thakkaryash94-cdk-dev.s3.amazonaws.com)
- defaultCacheBehavior:
- targetOriginId: unique id (should be same as originId)
- restrictions: We want our website be to accessible from everywhere, so set it to none.
- viewerCertificate: We can use CloudFront default certificate and can also add custom ACM certificate, IAM certificate etc.
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.
thakkaryash94 / terraform-cdk-react-example
Host react website using terraform CDK on AWS S3
Host Static website using AWS CDK for Terraform
This repo contains the code for DEV.to blog
Top comments (6)
interesting articles - I get access denied on my url
Could you perhaps test your repo, because I think you may need to comment out the "Output the bucket url to access the website" section which fails when I try.
Yes, we need to comment out the bucket access url because we are not serving s3 bucket as a url anymore. That's why we printing CloudFront URL. I kept it for the part 1, but for part 2, we need to comment out the s3 bucket url and can only access using CloudFront URL.
I get access denied on my url - how did you make sure your Cloudfront can have access to the S3? Also, do you Route53 for your dns?
We have setup CloudFront Origin Access Identity(OAI) and also updated the S3 bucket permission as below.
{
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${cloudfrontOriginAccessIdentity.id}"
}
So with this, only CloudFront will be able to access the bucket using OAI.
Hey, I need your help to setup EC2 hosted Bitnami Ghost CMS with Cloudfront. Can we talk? Please.
Post Link : dev.to/anurag_vishwakarma/can-anyo...
stackoverflow.com/questions/644335...
aws.amazon.com/premiumsupport/know...