[AWS] Tìm hiểu về cách host một static web sử dụng S3 + CloudFront + Domain + ACM
Bài viết này sẽ giúp bạn tạo 1 web static sử dụng S3 + CloudFront + Domain + ACM
- Github: lưu trữ repo. Sử dụng Git action để đẩy vào S3
- S3: Lưu trữ website static
- Cloudfront: Dùng để cache các file, giúp tăng tốc được website
- Domain: giá sử chúng ta có 1 domain ở một host nào đó. Ở đây mình có host
rustpanic.com
tạimatbao.vn
- ACM: Tạo SSL/TLS Certificate
S3 Create S3 package rustpanic.com
General configuration
- Block all public access: Bỏ tích. Bởi vì chúng ta cấu hình chỉ cho CloudFront mới truy xuất
Bucket versioning: Chúng ta chọn Disable
Default encryption: Chọn SSE-S3
Ta sẽ tạo ra bucket s3:s3://rustpanic.com
CI/CD Github upload automatically to S3
Cài đặt CI/CD
Trong repo của chúng ta có 1 thư mục .github/workflows
tạo file publish-pages.yml
với nội dung sau
Giả sử website nằm ở trong thư mục public
directory
name: deployment
on:
push:
branches:
- master
jobs:
deploy:
name: Deploy to S3
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Zola
uses: taiki-e/install-action@v2
with:
tool: zola@0.17.2
- name: Build with Zola
run: |
zola build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-southeast-1
- name: Deploy to S3
run: aws s3 sync ./public s3://rustpanic.com
Và s3://rustpanic.com
chính là tên của bucket trên s3 của chúng ta
Note: Thật ra chúng ta còn 1 bước thiếu là khi upload lên cần phải cập nhật lại cache nữa
Tạo account với quyền push lên s3
Tạo một user và add một permission như sau: Vào IAM > User > Persmissions
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::rustpanic.com/*"
}
]
}
Tạo một access_key Vào IAM > User > Credentials > Create access key
Ta sẽ có 2 chuỗi:
AWS_ACCESS_KEY_ID: AKIAUGA3JWGLIGXXXX
Và AWS_SECRET_ACCESS_KEY: secret-key
Ta sẽ sử dụng key này trong cấu hình github
Cài đặt s3
Cài đặt AWS_ACCESS_KEY_ID
và AWS_SECRET_ACCESS_KEY
trong github
Trong github repo > Settings > Secrets and Variabales > Actions
Tạo một certificate
Sau đó chúng ta thêm 1 record này vào Route53. Bước này quan trọng
Cloudfront
Origin
-
Origin domain:
rustpanic.com.s3.ap-southeast-1.amazonaws.com
. Chính là bucket chúng ta tạo lúc nãy -
Name:
rustpanic.com.s3.ap-southeast-1.amazonaws.com
Tên nào cũng được -
Origin access: Chọn
Legacy access identities
. ChọnCreate new OAI
và chọn Origin access identity là cái vừa tạo -
Bucket Policy: Chọn
Yes, update the bucket policy
Bước này giúp chúng ta cấu hình chỉ cho phépCloudfront
có quyền truy xuất S3 bucket
Nó sẽ thêm vào bucket policy một permission như sau:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowLegacyOAIReadOnly",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::rustpanic.com/*"
}
]
}
Trong đó XXXXX
là distribution id của chúng ta đang tạo
-
Add custom header: Không cần, dùng để bảo mật khi ALB đằng sau, chúng ta không có trong mô hình này
-
Enable Origin Shield: Chọn
No
Behavior
- Path pattern:
Default (*)
- Origin and origin groups:
rustpanic.com.s3.ap-southeast-1.amazonaws.com
Viewer
- Viewer protocol policy:
Redirect HTTP to HTTPS
- Allowed HTTP methods:
GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
- Restrict viewer access:
No
Cache key and origin requests
Chọn:
- Cache policy and origin request policy (recommended)
Settings
Certificate
Cần chọn certficate chúng ta vừa tạo
Bước này quan trọng, cần cấu hình một Cloudfront function để khi nhận một link https://rustpanic.com/test --> https://rustpanic.com/test/index.html
- Function associations:
Viewer request:
CloudFront Function
rustpanic_handler
function rustpanic_handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
Cấu hình Route53
Bước 1. Create hosted zone: rustpanic.com
Bước 2. Thêm record A dạng alias
Record name: rustpanic.com
Record type: A
Alias: Yes
Route traffice to: Alias to Cloudfront distribution
Cloudfront Distribution: dytty4t7imgpc.cloudfront.net.
Routing routing: Simple routing
Domain
When creating a hosted zone, we have 2 record default. Using record
NS
type with values:
ns-1296.awsdns-34.org.
ns-407.awsdns-50.com.
ns-1683.awsdns-18.co.uk.
ns-535.awsdns-02.net.
We added this records to domain host that we buy domain
Summary
- Step 1: Create Certificate and add record to route53
- Step 2: Create cloudfront distribution and select s3 bucket as
origin
- Step 3: Route53: Add record A alias poiting to CloudFront distribution
- Step 4: Add Cloudfront function to add suffix
index.html
to API path