Securely deliver static sites with CloudFront x S3
table of contents
hello.
This is Rin from the System Solutions Department.
I've entered my third year as an infrastructure engineer, but I'm finally surfing the internet, thinking, "I don't know much about S3, so I might try studying it ('ω')" and when I came across this article.
▼ I tried streaming static sites on AWS S3
"Next, I would like to write about how to stream in conjunction with Cloudfront," but there were no articles, so after about nine years I'd like to write about it in relay format.
Overall flow
Creating an S3 bucket
↓
Uploading an html file to the bucket
↓
Creating a CloudFront distribution
↓
S3 bucket policy settings
↓
Try accessing
I'll try it actually
Creating an S3 bucket
1. After moving to the S3 console, click "Create Bucket."
② Specify "Generic" for the bucket type and enter the bucket name
* The bucket name must be unique all over the world.
③ Other settings are OK by default, but please make sure that the public access settings are set to "Block all public access."
*This time, we want to be able to distribute files in the S3 bucket only via CloudFront.
③ Once you have confirmed this, click "Create Bucket".
I've created it!
④Upload the file
Click the bucket name from the bucket list screen > Upload
Upload the static file you want to view.
This time I uploaded this html file (index.html). (ChatGPT)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAP///yH5BAEAAAAAAAAAAAAAAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20 font-family%3A%20Arial%2C%20sans-serif%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20 0%20%20background-color%3A%20%23f0f0f0%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%20%20%20%20 %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20 font-size%3A%202.5em%3B%0A%20% 20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20 font-size%3A%201.2em%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20% data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;style&gt;" title="&lt;style&gt;" /> </head> <body> <h1>Thank you for reading this article! </h1> <p>I hope you have learned how to securely distribute static sites with CloudFront x S3. </p> </body> </html>
CloudFront Settings
Now that the files you want to distribute have been installed, you will then be setting up CloudFront.
Please move the screen to CloudFront > Create Distribution.
Setting items | value |
Distribution options | Single website or app |
Origin domain | Created S3 bucket |
name | Optionally specified |
Origin Access | Origin access control settings (recommended) |
Once you have selected "Origin access control settings (recommended)" for Origin Access, you will need to create a new rigin access control)
Once you have created an OAC, the Origin access control will automatically populate the OAC you just created.
Other settings are OK by default, so click Create Distribution.
As long as you can create a distribution like this, it's fine!
By the way, what is OAC (Origin Access Control)?
A policy that controls access to S3 buckets from CloudFront.
The S3 bucket will recognize requests from CloudFront and will be able to block access from other users.
OAC also appeared in 2022 as the successor to OAI (Origin Access Identity).
OAC allows for more detailed policy settings than OAI, and also supports the following that were not supported by OAI:
・Amazon S3 server-side encryption with AWS KMS (SSE-KMS)
・Dynamic requests for Amazon S3 (PUT and DELETE)
S3 bucket policy settings
CloudFront > Distributions > Press Created Distribution > Press Origins tab
Press "Edit" for the selected origin.
Go to Origin Access, copy the policy that appears as shown in the image, then transition to S3 bucket permissions.
Once you've moved to the S3 bucket screen, select the permissions tab and edit the bucket policy.
Paste the policy you just copied and save your changes.
Incidentally, the copied policy is as follows:
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::cloudfront-s3-rin-test-bucket/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::xxxxxx:distribution/EE49MGYO530OK" } } } ] }
Meaning of each policy (excerpted only for important points)
Principal | CloudFront services are specified. This allows only CloudFront to access objects in the S3 bucket. |
Action | "s3:GetObject" indicates permission to retrieve the object. |
Resource | Specifies all objects in the bucket. |
Condition | This is intended to only allow requests from a specific CloudFront distribution. |
Once you get this far you're ready!
Try to access
This time, we are not linking our own domain, so we will be accessing the distribution domain directly.
The distribution domain name can be viewed from the general distribution.
I was able to view the HTML file I uploaded successfully!
I would also like to make sure that public access to S3 is not possible, so I will also try accessing the S3 URL.
As expected, it's AccessDenied!