Delivering S3 Content via CloudFront
CloudFront, a CDN service, can be used to deliver content placed in S3 buckets.
This time, we will enable the static website hosting feature and target publicly accessible S3 buckets.
The use of an OAI (Origin Access Identity) can also be used to achieve actions similar to those in this configuration. Please check this page as well.
Environment
Create an S3 bucket and enable static website hosting.
Set the bucket policy to publish the content in the bucket to the public.
Create a CloudFront distribution and set the bucket as the origin.
Create a Lambda function.
Set this function as a CloudFormation custom resource.
The function will automatically create and delete objects in the bucket when the stack is created or deleted.
The object to be created is index.html for static website hosting.
The runtime for the function is Python 3.8.
CloudFormation template files
The above configuration is built with CloudFormation.
The CloudFormation template is located at the following URL
https://github.com/awstut-an-r/awstut-fa/tree/main/048
Explanation of key points of the template files
This page focuses on how to deliver S3 bucket content using CloudFront.
For more information on the static website hosting capabilities of S3 buckets, please refer to the following page
For information on how to use CloudFormation’s custom resources to perform object creation and deletion on buckets during stack creation and deletion, please check the following page
(Reference) Static Website Hosting for S3 Buckets
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref Prefix
PublicAccessBlockConfiguration:
BlockPublicAcls: false
BlockPublicPolicy: false
IgnorePublicAcls: false
RestrictPublicBuckets: false
WebsiteConfiguration:
IndexDocument: index.html
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref Bucket
PolicyDocument:
Statement:
Action:
- s3:GetObject
Effect: Allow
Resource: !Sub "arn:aws:s3:::${Bucket}/*"
Principal: "*"
Outputs:
BucketArn:
Value: !GetAtt Bucket.Arn
BucketWebsiteURL:
Value: !GetAtt Bucket.WebsiteURL
BucketName:
Value: !Ref Bucket
Code language: YAML (yaml)
There are two points.
The first is the bucket policy.
The bucket policy allows public access to the bucket to be created.
The second point is the data to be retrieved from the bucket.
In this case, the important value is the bucket website URL.
This URL can be retrieved with the built-in function Fn::GetAtt.
As described later, we will use part of this URL when specifying the CloudFront origin server.
A sample bucket website URL is provided below.
http://[bucket-name].s3-website-[region-name].amazonaws.com
CloudFront Distribution
Resources:
Distribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
CachedMethods:
- GET
- HEAD
Compress: true
ForwardedValues:
Cookies:
Forward: none
QueryString: false
TargetOriginId: !Ref BucketName
ViewerProtocolPolicy: allow-all
Enabled: true
Origins:
- DomainName: !Select
- 2
- !Split
- /
- !Ref BucketWebsiteURL
Id: !Ref BucketName
#S3OriginConfig:
CustomOriginConfig:
OriginProtocolPolicy: http-only
PriceClass: PriceClass_All
Code language: YAML (yaml)
There are two key points to configuring a publicly available S3 bucket as a CloudFront origin.
The first is the domain name setting.
This is set in the DomainName property.
For buckets that are publicly exposed with the static website hosting feature enabled, specify the domain name of the bucket website endpoint.
The string after “http://” in the bucket website URL introduced earlier corresponds to this.
Therefore, use Fn::Split as well as the built-in function Fn::Select to extract the domain name and specify it in this property.
The second is related to detailed origin settings.
When an S3 bucket is used as the origin, either of the following two properties must be set.
- CustomOriginConfig: Set when static website hosting is enabled for the S3 bucket.
- S3OriginConfig: Set if static website hosting is not enabled for the S3 bucket.
In this case, it is enabled, so set the CustomOriginConfig property.
When accessing the bucket website endpoint, the communication between CloudFront and the S3 bucket must be a non-SSL HTTP communication.
So set “http-only” in the OriginProtocolPolicy property.
Architecting
Use CloudFormation to build this environment and check the actual behavior.
Create CloudFormation stacks and check the resources in stacks
Create a CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following page
After checking the resources in each stack, information on the main resources created this time is as follows
- S3 bucket: fa-048
- CloudFront distribution domain: https://d3pnwba2gu8n7s.cloudfront.net
CloudFront is also checked from the AWS Management Console.
The CloudFront distribution has been created.
The website endpoint of the S3 bucket is set as the origin of the distribution.
Confirmation of Operation
Now that everything is ready, access the CloudFront distribution.
The contents of the S3 bucket are now displayed.
This means that the website endpoint of the origin S3 bucket is being accessed via CloudFront.
Incidentally, you can also access the origin S3 bucket directly.
This is because the current configuration is not set to restrict direct access to the origin.
Summary
Using CloudFront, we were able to deliver content placed in S3 buckets.