Giới thiệu
Trong bài viết này, chúng ta sẽ tìm hiểu cách triển khai một ứng dụng SPA (Single Page Application) được viết bằng React trên AWS S3 và CloudFront. Mô hình mà chúng ta sẽ sử dụng sẽ giúp bạn quản lý các API REST thông qua AWS API Gateway và sử dụng CloudFront để tối ưu hóa việc chia sẻ tài nguyên giữa các miền (CORS).
Chúng ta sẽ dựa vào kho mã mẫu do AWS cung cấp.
Kiến trúc tổng quan
Các dịch vụ AWS
- AWS API Gateway: Giúp bạn tạo, xuất bản và duy trì API REST, HTTP, và WebSocket với quy mô lớn.
- AWS CloudFormation: Hỗ trợ bạn thiết lập tài nguyên AWS, cung cấp nhanh chóng và đồng nhất, cũng như quản lý chúng trong suốt vòng đời trong các tài khoản và vùng AWS.
- AWS CloudFront: Tăng tốc độ phân phối nội dung web của bạn bằng cách cung cấp qua mạng lưới trung tâm dữ liệu toàn cầu, giảm độ trễ và cải thiện hiệu suất.
- AWS CloudTrail: Giúp bạn kiểm toán quản lý, tuân thủ và rủi ro hoạt động của tài khoản AWS.
- AWS CloudWatch: Giúp bạn theo dõi các thông số của tài nguyên AWS và các ứng dụng mà bạn chạy trên AWS theo thời gian thực.
- AWS IAM: Giúp bạn quản lý quyền truy cập tài nguyên AWS một cách an toàn bằng cách kiểm soát ai được xác thực và ủy quyền sử dụng chúng.
- AWS Route 53: Dịch vụ DNS web có tính khả dụng cao và có thể mở rộng.
- Amazon S3: Dịch vụ lưu trữ đối tượng dựa trên đám mây giúp bạn lưu trữ, bảo vệ và truy xuất bất kỳ lượng dữ liệu nào.
CloudFormation (IaC)
Trong kho mã mẫu, chúng ta sẽ tập trung vào thông tin có trong tệp react-cors-spa-stack.yaml. Trong tệp YAML này, chúng ta có tất cả các chỉ dẫn để AWS CloudFormation cung cấp các tài nguyên AWS cần thiết cho ví dụ này.
Bucket AWS S3
PublicAccessBlockConfiguration
chặn tất cả quyền truy cập công khai.- Nhật ký bucket được bật và lưu trữ trong
LoggingBucket
. BucketName
thiết lập tên của bucket (đây là thông tin quan trọng nếu bạn gặp khó khăn trong việc tìm bucket trong AWS Console).
yaml
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Sub 'react-cors-spa-${SimpleAPI}'
PublicAccessBlockConfiguration:
BlockPublicAcls : true
BlockPublicPolicy : true
IgnorePublicAcls : true
RestrictPublicBuckets : true
LoggingConfiguration:
DestinationBucketName: !Ref LoggingBucket
LogFilePrefix: s3-access-logs
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: 'AES256'
Chính sách Bucket AWS S3
- Cho phép hành động
s3:GetObject*
. CFDistributionSPA
là thực thể duy nhất được phép thực hiện hành độngs3:GetObject*
.
yaml
BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
PolicyDocument:
Id: MyPolicy
Version: 2012-10-17
Statement:
- Sid: PolicyForCloudFrontPrivateContent
Effect: Allow
Resource: !Sub ${S3Bucket.Arn}/*
Principal:
Service: cloudfront.amazonaws.com
Condition:
StringEquals:
AWS:SourceArn: !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${CFDistributionSPA}
Action: 's3:GetObject*'
Bucket: !Ref S3Bucket
CloudFront
- Thiết lập nguồn gốc là Bucket S3 của SPA, sử dụng
CloudFrontOriginAccessControl
như phương thức OAC giữa CloudFront và AWS S3. - Thuộc tính
DefaultRootObject
nhận giá trịindex.html
. Đây là tệp mà CloudFront sẽ coi là đối tượng gốc từ Bucket AWS S3.
yaml
CFDistributionSPA:
Type: 'AWS::CloudFront::Distribution'
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt S3Bucket.RegionalDomainName
Id: myS3Origin
S3OriginConfig:
OriginAccessIdentity: ""
OriginAccessControlId: !GetAtt CloudFrontOriginAccessControl.Id
Enabled: 'true'
DefaultRootObject: index.html
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: myS3Origin
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # CachingOptimized
OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf # CORS-S3Origin
ResponseHeadersPolicyId: eaab4381-ed33-4a86-88ca-d9558dc6cd63 # CORS-with-preflight-and-SecurityHeadersPolicy
ViewerProtocolPolicy: redirect-to-https
CustomErrorResponses:
- ErrorCode: 403
ResponseCode: 200
ResponsePagePath: /index.html
- ErrorCode: 501
ResponseCode: 501
ErrorCachingMinTTL: 0
PriceClass: PriceClass_All
Logging:
Bucket: !GetAtt LoggingBucket.RegionalDomainName
Prefix: 'cf-spa-access-logs'
ViewerCertificate:
CloudFrontDefaultCertificate: true
MinimumProtocolVersion: 'TLSv1.2_2021'
CloudFront OriginAccessControl
- Mô tả các chữ ký yêu cầu giữa CloudFront và Bucket AWS S3 (OAC).
yaml
CloudFrontOriginAccessControl:
Type: AWS::CloudFront::OriginAccessControl
DependsOn:
- S3Bucket
Properties:
OriginAccessControlConfig:
Description: Default Origin Access Control
Name: !Ref AWS::StackName
OriginAccessControlOriginType: s3
SigningBehavior: always
SigningProtocol: sigv4
Triển khai
-
Đầu tiên, chạy lệnh sau để CloudFormation cung cấp tài nguyên ứng dụng:
bashaws cloudformation deploy \ --stack-name react-cors-spa-demo \ --template-file react-cors-spa-stack.yaml \ --region us-east-1 \ --no-fail-on-empty-changeset
-
Bây giờ, chúng ta sẽ lấy các giá trị được cung cấp bởi mẫu CloudFormation, được liệt kê trong phần
Outputs
:yamlOutputs: BucketName: Value: !Sub "react-cors-spa-${SimpleAPI}" SPADomain: Value: !GetAtt CFDistributionSPA.DomainName APIDomain: Value: !GetAtt CFDistributionAPI.DomainName
Chạy lệnh:
bashaws cloudformation describe-stacks \ --stack-name react-cors-spa-demo \ --region us-east-1 \ --query "Stacks[0].Outputs"
Lưu
BucketName
để sử dụng sau này. -
Xây dựng ứng dụng React của bạn. Trong ví dụ này, bạn có thể thực hiện bằng cách chạy
yarn build
và tìm thư mụcout
. -
Bây giờ chỉ cần tải nội dung từ bước trước, sử dụng
BucketName
từ bước 2, lên Bucket AWS S3:bashaws s3 sync ./out "s3://$BUCKET_NAME"
Nếu bạn đang sử dụng Next.js giống như ví dụ của AWS, bạn cũng cần bao gồm thư mục
_next_
trong Bucket AWS S3:bashaws s3 sync ./_next "s3://$BUCKET_NAME"
Kết luận
Giờ đây, bạn đã biết cách lưu trữ ứng dụng React SPA của mình trong một hệ thống nhanh chóng, an toàn và tiết kiệm chi phí trên AWS Cloud.
Nếu bạn thấy nội dung này hữu ích hoặc có bất kỳ câu hỏi nào về nó, hãy để lại bình luận bên dưới nhé!
Các phương pháp tốt nhất
- Kiểm tra cấu hình: Đảm bảo rằng tất cả các thông số cấu hình đã được thiết lập đúng.
- Quản lý phiên bản: Sử dụng phiên bản bucket S3 để theo dõi sự thay đổi của nội dung.
- Bảo mật: Thiết lập chính sách IAM chặt chẽ để hạn chế quyền truy cập.
Những cạm bẫy thường gặp
- Quên bật nhật ký: Không bật nhật ký có thể khiến bạn không theo dõi được các truy cập và lỗi.
- Thiếu kiểm tra CORS: Nếu không cấu hình đúng CORS, ứng dụng có thể không hoạt động trên các miền khác.
Mẹo hiệu suất
- Sử dụng cache: Sử dụng các chính sách cache trong CloudFront để cải thiện hiệu suất tải trang.
- Tối ưu hóa hình ảnh: Sử dụng hình ảnh với kích thước tối ưu để giảm thời gian tải.
Khắc phục sự cố
- Lỗi 403: Nếu bạn gặp lỗi 403, hãy kiểm tra chính sách bucket và quyền truy cập của CloudFront.
- Vấn đề CORS: Kiểm tra cấu hình CORS trong API và CloudFront để đảm bảo rằng nó được thiết lập đúng.
Câu hỏi thường gặp
-
Làm thế nào để tôi có thể điều chỉnh cấu hình CloudFront cho ứng dụng của mình?
- Bạn có thể chỉnh sửa mẫu CloudFormation để thay đổi các thuộc tính trong
CFDistributionSPA
.
- Bạn có thể chỉnh sửa mẫu CloudFormation để thay đổi các thuộc tính trong
-
Có cần sử dụng API Gateway không?
- Nếu ứng dụng của bạn cần tương tác với các API bên ngoài, thì API Gateway là cần thiết.
-
Có cách nào để giám sát hiệu suất của ứng dụng không?
- Bạn có thể sử dụng AWS CloudWatch để theo dõi và phân tích dữ liệu hiệu suất của ứng dụng.