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ại matbao.vn
  • ACM: Tạo SSL/TLS Certificate

Overview

S3 Create S3 package rustpanic.com

General configuration S3

  • 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

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_IDAWS_SECRET_ACCESS_KEY trong github Trong github repo > Settings > Secrets and Variabales > Actions Install Key

Tạo một certificate

Create Certificate

Sau đó chúng ta thêm 1 record này vào Route53. Bước này quan trọng

Cloudfront

Origin

Cấu hình 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ọn Create 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ép Cloudfront 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

Certficate 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

R53

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