Ngân hàng đề — AWS Certified Solutions Architect Professional
Tìm thấy 1221 câu.
A company runs Docker containers on Amazon ECS. A containerized application uses a custom tool that must be manually updated each time the container code is updated. The updated container image can then be used for new tasks. A Solutions Architect has been tasked with automating this process to eliminate the manual work and ensure a new container image is generated each time the tool code is updated.
Which combination of actions should the Solutions Architect take to meet these requirements? (Select THREE.)
-
A
Create an Amazon EventBridge rule that triggers on commits to the AWS CodeCommit repository for the image. Configure the event to trigger an update to the image in Amazon ECR. Push the updated container image to Amazon ECR.
-
B
Create an AWS CodePipeline pipeline that sources the tool code from the AWS CodeCommit repository and initiates an AWS CodeBuild build.
-
C
Create an AWS CodeBuild project that pulls the latest container image from Amazon ECR, updates the container with code from the source AWS CodeCommit repository, and pushes the updated container image to Amazon ECR.
-
D
Create an AWS CodeDeploy application that pulls the latest container image from Amazon ECR, updates the container with code from the source AWS CodeCommit repository, and pushes the updated container image to Amazon ECR.
-
E
Create an AWS CodePipeline pipeline that sources the tool code from the AWS CodeCommit repository and initiates an AWS CodeDeploy application update.
-
F
Create an Amazon ECR repository for the image. Create an AWS CodeCommit repository containing code for the tool being deployed to the container image in Amazon ECR.
Xem giải thích
Đáp án
B, C, F — ba bước tự động sinh container image mới mỗi khi mã của công cụ thay đổi:
- F — Tạo ECR repository cho image, và CodeCommit repository chứa mã của công cụ.
- B — Tạo CodePipeline lấy mã công cụ từ CodeCommit và khởi động một build của CodeBuild.
- C — Tạo CodeBuild project kéo image mới nhất từ ECR, cập nhật container bằng mã từ CodeCommit, rồi đẩy image mới lên ECR.
Vì sao đúng
Ba bước này là ba mảnh của một đường ống hoàn chỉnh, xếp đúng thứ tự nhân quả.
| Mảnh | Việc | Bước |
|---|---|---|
| Nơi chứa | kho mã và kho image | F |
| Cơ chế kích hoạt | phát hiện commit, khởi động build | B |
| Việc build thật | dựng và đẩy image | C |
⚠ Điểm mấu chốt: CodeBuild là nơi DUY NHẤT trong họ Code thật sự chạy lệnh build và đẩy image:*
CodePipeline: điều phối — nối các giai đoạn, không tự chạy lệnh gì
↓
CodeBuild: môi trường thực thi — chạy docker build, docker push
↓
CodeDeploy: triển khai ứng dụng ĐÃ dựng lên EC2/ECS/Lambda
↓
→ dựng image là việc của CodeBuild, không phải CodeDeploy
Đây là điểm phân biệt phương án C với D, và phương án B với E.
Tệp buildspec.yml thể hiện đúng những gì phương án C mô tả:
version: 0.2
phases:
pre_build:
commands:
- aws ecr get-login-password | docker login --username AWS --password-stdin $REPO
- docker pull $REPO/cong-cu:latest
build:
commands:
- docker build -t $REPO/cong-cu:$CODEBUILD_RESOLVED_SOURCE_VERSION .
post_build:
commands:
- docker push $REPO/cong-cu:$CODEBUILD_RESOLVED_SOURCE_VERSION
- docker tag ... && docker push $REPO/cong-cu:latest
⚠ Gắn thẻ latest cho mọi image làm mất khả năng truy vết và lùi phiên bản:
Mọi build đều đẩy lên với thẻ latest
↓
Không biết task đang chạy image nào
↓
Muốn lùi lại phiên bản trước → không còn thẻ nào trỏ tới nó
↓
→ luôn gắn thẻ bằng commit hash hoặc số build, latest chỉ là bí danh thêm
Vì sao các phương án khác sai
-
A (EventBridge rule kích hoạt khi có commit vào CodeCommit, cấu hình sự kiện để "cập nhật image trong ECR", rồi đẩy image lên ECR) — đây là phương án gần nhất và nửa đầu của nó hoàn toàn hợp lệ: EventBridge thật sự bắt được sự kiện commit của CodeCommit, và đó là một cách kích hoạt pipeline. Nó hỏng ở nửa sau. Không có cơ chế nào để "một sự kiện cập nhật image trong ECR" — ECR là kho lưu image, nó không dựng image. Giữa việc phát hiện commit và việc có image mới phải có một môi trường chạy
docker build, mà phương án này không nêu thành phần nào đảm nhận việc đó. Đây là bẫy hay vì nó mô tả đúng điểm đầu và điểm cuối rồi bỏ trống đoạn giữa. -
D (CodeDeploy application kéo image từ ECR, cập nhật container, đẩy image mới lên ECR) — sai vai trò dịch vụ. CodeDeploy triển khai ứng dụng đã được dựng sẵn; nó không có môi trường build, không chạy
docker build, không đẩy image lên registry. Đây là mô tả công việc của CodeBuild gán nhầm tên dịch vụ. -
E (CodePipeline lấy mã từ CodeCommit rồi khởi động một cập nhật của CodeDeploy) — cùng lỗi: bỏ qua giai đoạn build. Không có bước nào dựng image mới, nên CodeDeploy sẽ không có gì mới để triển khai.
Ghi nhớ
⚠ Bốn dịch vụ Code — bảng phải thuộc, đây là chỗ hay lẫn nhất:* | Dịch vụ | Việc | Có chạy lệnh không | |---|---|---| | CodeCommit | kho Git có quản lý | không | | CodeBuild | biên dịch, kiểm thử, dựng và đẩy image | có | | CodeDeploy | triển khai artifact lên EC2/ECS/Lambda | có, nhưng là hook triển khai | | CodePipeline | điều phối các giai đoạn | không, nó gọi dịch vụ khác |
Từ khoá nhận diện:
"generate a new container image" → CodeBuild "automate on every code commit" → CodePipeline với source stage "CodeDeploy dựng image" → LUÔN SAI, CodeDeploy không build "sự kiện tự cập nhật image trong ECR" → SAI, ECR chỉ lưu trữ "triển khai image mới lên ECS" → đó là bước sau, dùng CodeDeploy hoặc cập nhật service
| Các giai đoạn CodePipeline điển hình cho container | Nội dung |
|---|---|
| Source | CodeCommit, GitHub, Bitbucket, S3 |
| Build | CodeBuild: docker build + docker push lên ECR |
| Test | CodeBuild chạy kiểm thử tích hợp |
| Deploy | cập nhật ECS service, hoặc CodeDeploy blue/green |
| Tính năng ECR đáng dùng | Việc |
|---|---|
| Image scanning | quét CVE khi push và quét lại định kỳ |
| Lifecycle policy | tự xoá image cũ — rất cần, image tích luỹ rất nhanh |
| Immutable tags | chặn ghi đè một thẻ đã tồn tại |
| Cross-account access | repository policy |
| Quyền CodeBuild cần | Nội dung |
|---|---|
ecr:GetAuthorizationToken |
đăng nhập registry |
ecr:BatchGetImage, ecr:GetDownloadUrlForLayer |
kéo image |
ecr:PutImage, ecr:UploadLayerPart, ecr:InitiateLayerUpload |
đẩy image |
| Privileged mode | bắt buộc bật để chạy Docker daemon trong CodeBuild |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Build có chạy khi commit không | lịch sử thực thi của pipeline | | Image mới có lên ECR không | aws ecr describe-images --repository-name cong-cu | | Image có thẻ truy vết được không | kiểm thẻ có phải commit hash không, không chỉ latest |
Và một lời khuyên: hãy đặt lifecycle policy cho ECR repository ngay khi tạo nó. Đây là khoản chi phí tích luỹ âm thầm nhất trong một đường ống CI/CD: mỗi lần build sinh ra một image mới, mỗi image mang theo toàn bộ các lớp của nó, và với một đội commit vài chục lần mỗi ngày thì repository phình lên hàng trăm GB trong vài tháng. Không có cảnh báo nào, không có hạn mức nào bị chạm, và dòng chi phí ECR nhỏ tới mức không ai để ý trong những tháng đầu — cho tới khi nó không còn nhỏ nữa. Một policy giữ 30 image gần nhất và xoá image không có thẻ sau 7 ngày là đủ cho phần lớn trường hợp.
An advertising company hosts static content in an Amazon S3 bucket that is served by Amazon CloudFront. The static content is generated programmatically from a Development account, and the S3 bucket and CloudFront are in a Production account. The build pipeline uploads the files to Amazon S3 using an IAM role in the Development Account. The S3 bucket has a bucket policy that only allows CloudFront to read objects using an origin access identity (OAI). During testing all attempts to upload objects using the to the S3 bucket are denied..
How can a Solutions Architect resolve this issue and allow the objects to be uploaded to Amazon S3?
-
A
Modify the S3 upload process in the Development account to set the object owner to the Production Account.
-
B
Create a new IAM role in the Development account with read access to the S3 bucket. Configure S3 to use this new role as its OAI. Modify the build pipeline to assume this role when uploading files from the Development Account.
-
C
Modify the S3 upload process in the Development account to add the bucket-owner-full-control ACL to the objects at upload.
-
D
Create a new cross-account IAM role in the Production account with write access to the S3 bucket. Modify the build pipeline to assume this role to upload the files to the Production Account.
Xem giải thích
Đáp án
D — Tạo IAM role liên tài khoản trong tài khoản Production với quyền ghi vào bucket S3; sửa build pipeline để assume role đó khi tải tệp lên.
Vì sao đúng
Nguyên nhân sự cố nằm ở một câu trong đề: bucket policy chỉ cho phép CloudFront đọc qua OAI. Không có mệnh đề nào cho phép ai đó ghi vào bucket.
| Sự thật trong đề | Suy ra |
|---|---|
| Bucket policy chỉ cho OAI đọc | không có quyền ghi cho bất kỳ ai |
| Pipeline dùng IAM role ở tài khoản Development | principal thuộc tài khoản khác |
| Bucket nằm ở tài khoản Production | truy cập liên tài khoản |
⚠ Điểm mấu chốt: truy cập liên tài khoản cần quyền ở CẢ HAI phía — và ở đây phía tài nguyên đang chặn:
Role ở tài khoản Development có s3:PutObject trong policy của nó
↓
Nhưng bucket ở tài khoản Production không cho principal nào ngoài OAI
↓
→ bị từ chối, vì liên tài khoản đòi CẢ identity policy LẪN resource policy
Phương án D giải bằng cách đưa danh tính về đúng tài khoản sở hữu bucket: pipeline assume một role thuộc tài khoản Production, nên khi ghi, nó là principal nội bộ của tài khoản đó và không còn cần bucket policy cho phép tài khoản ngoài.
// Trust policy của role trong tài khoản Production
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<dev-account>:role/BuildPipelineRole"},
"Action": "sts:AssumeRole"
}
# pipeline assume role rồi mới tải lên
aws sts assume-role \
--role-arn arn:aws:iam::<prod-account>:role/S3UploadRole \
--role-session-name build-upload
⚠ Giải pháp này còn sửa luôn vấn đề quyền sở hữu object, thứ mà đề chưa nêu nhưng sẽ nổ ra sau:
Nếu tài khoản Development ghi trực tiếp vào bucket của Production
↓
Object thuộc sở hữu của tài khoản Development
↓
Chủ bucket có thể KHÔNG đọc được chính object trong bucket của mình
↓
→ assume role của Production thì object thuộc về Production ngay từ đầu
(Từ tháng 4/2023, cài đặt mặc định Bucket owner enforced đã làm chủ bucket luôn sở hữu mọi object, nên vấn đề này ít gặp hơn với bucket mới — nhưng đường đi qua role vẫn là cách sạch nhất.)
Vì sao các phương án khác sai
-
C (thêm ACL
bucket-owner-full-controlcho object lúc tải lên) — đây là phương án gần nhất và nó là cách làm chuẩn cho một vấn đề có thật: khi tài khoản này ghi vào bucket của tài khoản kia, ACL đó trao quyền cho chủ bucket. Nhưng nó không chữa được lỗi của đề. ACL quyết định ai sở hữu và đọc được object sau khi nó đã được tạo; nó không cấp quyền để thực hiện lời gọiPutObjectngay từ đầu. Request vẫn bị từ chối trước khi có object nào để gắn ACL. Ngoài ra, với các bucket dùng cài đặt mặc định hiện nay thì ACL đã bị tắt hoàn toàn, nên tham số này còn gây lỗi. Đây là bẫy tinh vi: một câu trả lời đúng cho câu hỏi "vì sao chủ bucket không đọc được object", đặt vào câu hỏi "vì sao không ghi được". -
B (tạo IAM role mới trong tài khoản Development với quyền đọc bucket, cấu hình S3 dùng role này làm OAI) — mô tả một thứ không tồn tại. OAI là danh tính đặc biệt do CloudFront quản lý, không phải một IAM role bạn tự tạo và gán vào. Bạn không "cấu hình S3 dùng một role làm OAI". Phương án này cũng cấp quyền đọc trong khi vấn đề là ghi.
-
A (sửa quy trình tải lên để đặt chủ sở hữu object là tài khoản Production) — cùng loại nhầm lẫn với C: nó xử lý quyền sở hữu object chứ không xử lý quyền gọi API. Và không có tham số nào đơn giản là "đặt object owner" khi PUT — thứ gần nhất là ACL
bucket-owner-full-control, tức là quay về phương án C.
Ghi nhớ
⚠ Bốn cách truy cập S3 liên tài khoản — bảng phải thuộc: | Cách | Cơ chế | |---|---| | Assume role ở tài khoản đích | principal trở thành nội bộ — sạch nhất | | Bucket policy cho principal của tài khoản khác | phải khai cả hai phía | | Access point với chính sách riêng | tách quyền theo từng nhóm người dùng | | ACL (cũ) | mặc định đã tắt từ 4/2023 |
Từ khoá nhận diện:
"upload denied" liên tài khoản → bucket policy không cho ghi, hoặc thiếu role "bucket policy only allows CloudFront via OAI" → không có ai được ghi cả "bucket-owner-full-control" → giải quyết QUYỀN SỞ HỮU, không phải quyền ghi "cấu hình role làm OAI" → LUÔN SAI, OAI do CloudFront quản lý truy cập liên tài khoản → luôn cần CẢ identity policy LẪN resource policy (trừ khi assume role)
| Quy tắc đánh giá liên tài khoản | Nội dung |
|---|---|
| Cùng tài khoản | chỉ cần một trong hai policy cho phép |
| Khác tài khoản | cần CẢ HAI cùng cho phép |
| Deny tường minh | thắng ở mọi trường hợp |
| Ba cách khoá bucket cho CloudFront | Ghi chú |
|---|---|
| OAC | mới, ký SigV4, hỗ trợ SSE-KMS |
| OAI | cũ, vẫn chạy |
| Custom header + WAF | dùng khi origin là website endpoint hoặc ALB |
| Object ownership của S3 | Chế độ |
|---|---|
| Bucket owner enforced (mặc định từ 4/2023) | ACL tắt, chủ bucket luôn sở hữu mọi object |
| Bucket owner preferred | ACL bật, object có bucket-owner-full-control thuộc chủ bucket |
| Object writer | người ghi sở hữu — nguồn của nhiều sự cố cũ |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Ai bị từ chối và vì sao | CloudTrail ở tài khoản Production, sự kiện PutObject lỗi | | Role có assume được không | aws sts assume-role thủ công từ môi trường build | | Object thuộc về ai | aws s3api get-object-acl hoặc kiểm chế độ ownership |
Và một lời khuyên: hãy đọc CloudTrail ở tài khoản SỞ HỮU TÀI NGUYÊN, không phải ở tài khoản gọi API. Đây là chỗ việc gỡ lỗi liên tài khoản mất nhiều thời gian nhất một cách vô ích: đội ở tài khoản Development nhìn vào CloudTrail của họ, thấy lời gọi PutObject với mã lỗi AccessDenied, và bắt đầu rà soát IAM policy của chính mình — nơi mọi thứ đều đúng. Thông tin thật sự hữu ích nằm ở phía bên kia: sự kiện tương ứng trong tài khoản Production thường kèm theo errorMessage nói rõ chính sách nào đã từ chối. Hai bản ghi cho cùng một request, nhưng chỉ một bản chứa câu trả lời.
A pharmaceutical company has deployed an application on their private Amazon VPC. They need to use a third-party software-as-a-service (SaaS) application which is hosted in another AWS account inside an Amazon VPC.
They need to connect applications to the third-party SaaS from private subnets in the company VPC. The company’s security team has mandated policies that private network needs to be used without internet propagation. No resources that run in the company VPC are allowed to be accessed from outside the company's VPC. All permissions must conform to the principles of least privilege.
Which solution meets these requirements?
-
A
Create an AWS PrivateLink endpoint service. Ask the third-party SaaS provider to create an interface VPC endpoint for this endpoint service. Grant permissions for the endpoint service to the specific account of the third-party SaaS provider.
-
B
Create an AWS Site-to-Site VPN connection between the third-party SaaS application and the company VPC. Configure network ACLs to limit access across the VPN tunnels.
-
C
Create a VPC peering connection between the third-party SaaS application and the company VPC. Update route tables by adding the required routes for the peering connection.
-
D
Create an AWS PrivateLink interface VPC endpoint. Connect this endpoint to the endpoint service that the third-party SaaS application provides. Create a security group to limit the access to the endpoint and associate the security group with the endpoint.
Xem giải thích
Đáp án
D — Tạo AWS PrivateLink interface VPC endpoint, nối tới endpoint service mà nhà cung cấp SaaS bên thứ ba phơi ra; tạo security group giới hạn truy cập tới endpoint và gắn vào endpoint đó.
Vì sao đúng
Đề nêu ba yêu cầu bảo mật, và chiều của kết nối là chi tiết quyết định: công ty là bên TIÊU THỤ dịch vụ, không phải bên cung cấp.
| Yêu cầu của đề | Cách đáp ứng |
|---|---|
| Mạng riêng, không đi qua Internet | PrivateLink — lưu lượng nằm trong mạng AWS |
| Không tài nguyên nào trong VPC công ty bị truy cập từ ngoài | PrivateLink một chiều: chỉ công ty gọi ra |
| Quyền tối thiểu | security group trên endpoint |
⚠ Điểm mấu chốt: PrivateLink là kết nối MỘT CHIỀU — đó chính là tính chất đề đang cần:
VPC công ty (bên tiêu thụ) VPC của SaaS (bên cung cấp)
Interface endpoint ──────────► Endpoint service (NLB)
│
◄── chỉ lưu lượng phản hồi ───────────┘
→ SaaS KHÔNG khởi tạo được kết nối vào VPC công ty
→ không có gì trong VPC công ty phơi ra ngoài
Đây là điểm phân biệt cốt lõi với VPC peering: peering nối hai mạng với nhau và cả hai bên đều gọi sang nhau được (nếu security group cho phép). PrivateLink chỉ phơi một dịch vụ cụ thể, theo một chiều duy nhất.
Interface endpoint là một ENI trong subnet riêng của bạn, có địa chỉ IP riêng, nên gắn được security group — đó là cách đạt quyền tối thiểu:
aws ec2 create-vpc-endpoint --vpc-id vpc-cong-ty \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.vpce.ap-southeast-1.vpce-svc-0abc123 \
--subnet-ids subnet-rieng-1a subnet-rieng-1b \
--security-group-ids sg-chi-cho-app
⚠ Đừng lẫn chiều: nếu CÔNG TY phơi dịch vụ ra cho người khác thì mới cần endpoint service:
Bên CUNG CẤP dịch vụ → tạo endpoint SERVICE (đứng sau NLB hoặc GWLB)
Bên TIÊU THỤ dịch vụ → tạo interface ENDPOINT
↓
Đề nói công ty cần "connect to the third-party SaaS"
↓
→ công ty là bên tiêu thụ → tạo endpoint
Vì sao các phương án khác sai
-
A (tạo endpoint SERVICE ở phía công ty, nhờ nhà cung cấp SaaS tạo interface endpoint, cấp quyền cho tài khoản của họ) — đây là phương án gần nhất và nó dùng đúng công nghệ PrivateLink, chỉ đảo ngược vai trò. Đảo chiều như vậy có nghĩa là công ty phơi một dịch vụ ra cho nhà cung cấp SaaS gọi vào — trái thẳng với chính sách bảo mật mà đề nêu: "No resources that run in the company VPC are allowed to be accessed from outside the company's VPC". Đây là bẫy hay nhất của câu này vì nó thưởng cho người nhớ được PrivateLink là câu trả lời, rồi phạt vì không kiểm lại chiều của kết nối.
-
C (VPC peering giữa VPC của SaaS và VPC công ty) — vi phạm nguyên tắc quyền tối thiểu. Peering nối toàn bộ hai mạng ở tầng định tuyến; kiểm soát duy nhất còn lại là security group và NACL, và một cấu hình sai ở đó là phơi ra cả VPC. Nó cũng cho phép bên SaaS khởi tạo kết nối vào VPC công ty, đúng điều bị cấm. Ngoài ra peering đòi hai dải CIDR không chồng lấn — ràng buộc không kiểm soát được với bên thứ ba.
-
B (Site-to-Site VPN giữa ứng dụng SaaS và VPC công ty, dùng NACL giới hạn) — sai công cụ. Site-to-Site VPN dùng để nối mạng tại chỗ với AWS, không phải để nối hai VPC trong AWS với nhau; và nó cũng tạo ra kết nối mạng hai chiều như peering. NACL là công cụ lọc thô, không có trạng thái, và không phải cách diễn đạt quyền tối thiểu ở đây.
Ghi nhớ
⚠ Bốn cách nối VPC — bảng phải thuộc, chú ý cột chiều: | Cách | Phơi ra cái gì | Chiều | |---|---|---| | PrivateLink | một dịch vụ cụ thể | một chiều | | VPC peering | toàn bộ mạng | hai chiều | | Transit gateway | toàn bộ mạng, nhiều VPC | hai chiều | | Site-to-Site VPN | mạng tại chỗ ↔ VPC | hai chiều |
Từ khoá nhận diện:
"connect to a third-party SaaS privately" → PrivateLink, tạo interface endpoint "no resources in our VPC accessible from outside" → loại peering, VPN, và endpoint service "least privilege" + endpoint → security group gắn vào interface endpoint "tạo endpoint service" khi bạn là bên tiêu thụ → SAI chiều "VPC peering với bên thứ ba" → quá rộng, vi phạm quyền tối thiểu
| Hai loại VPC endpoint | Khác |
|---|---|
| Interface endpoint | ENI có IP riêng, gắn security group được, tính tiền theo giờ + GB |
| Gateway endpoint | mục trong bảng định tuyến, chỉ cho S3 và DynamoDB, miễn phí |
| Thành phần PrivateLink phía cung cấp | Nội dung |
|---|---|
| NLB hoặc Gateway Load Balancer | đứng trước dịch vụ |
| Endpoint service | phơi NLB đó ra |
| Danh sách principal được phép | tài khoản, role hoặc user nào tạo endpoint được |
| Chấp nhận kết nối | tự động hoặc thủ công |
| Ưu điểm của PrivateLink | Nội dung |
|---|---|
| CIDR chồng lấn không sao | không định tuyến giữa hai mạng |
| Không cần internet gateway, NAT | lưu lượng nằm trong mạng AWS |
| Private DNS | dùng tên miền quen thuộc của dịch vụ |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Endpoint có ở trạng thái available không | aws ec2 describe-vpc-endpoints | | Có phân giải được tên không | dig <ten-dich-vu> từ instance trong subnet riêng | | Security group có chặn đúng không | thử kết nối từ một instance không được phép |
Và một lời khuyên: hãy kiểm tra security group của interface endpoint chứ đừng chỉ kiểm security group của instance. Đây là chỗ cấu hình sai theo cả hai hướng mà không có triệu chứng rõ ràng: nếu security group của endpoint quá rộng, mọi thứ trong VPC đều gọi được dịch vụ SaaS — bạn có PrivateLink nhưng không có quyền tối thiểu, và không có gì báo cho bạn biết vì kết nối vẫn hoạt động đúng như mong đợi. Nếu nó quá hẹp, kết nối bị chặn ở tầng endpoint và ứng dụng nhận về một timeout không nói gì, trong khi security group của chính instance thì hoàn toàn đúng — nên bạn sẽ đi tìm lỗi ở mọi nơi trừ nơi cần tìm.
A company has experienced issues updating an AWS Lambda function that is deployed using an AWS CloudFormation stack. The issues have resulted in outages that affected large numbers of customers. A Solutions Architect must adjust the deployment process to support a canary release strategy. Invocation traffic should be routed based on specified weights.
Which solution will meet these requirements?
-
A
Use AWS CodeDeploy to deploy using the CodeDeployDefault.HalfAtATime deployment configuration to distribute the load.
-
B
Deploy the application into a new CloudFormation stack. Use an Amazon Route 53 weighted routing policy to distribute the load.
-
C
Create an alias for new versions of the Lambda function. Use the AWS CLI update-alias command with the routing-config parameter to distribute the load.
-
D
Create a version for every new update to the Lambda function code. Use the AWS CLI update-function-configuration command with the routing-config parameter to distribute the load.
Xem giải thích
Đáp án
C — Tạo alias cho các phiên bản mới của hàm Lambda, dùng lệnh update-alias với tham số --routing-config để chia lưu lượng theo trọng số.
Vì sao đúng
Đề đòi canary release cho Lambda với lưu lượng chia theo trọng số đã định. Lambda có cơ chế dựng sẵn cho đúng việc đó, và nó nằm ở alias.
| Yêu cầu của đề | Cách đáp ứng |
|---|---|
| Canary release | alias trỏ tới hai phiên bản cùng lúc |
| Chia lưu lượng theo trọng số | --routing-config trên alias |
| Lùi lại nhanh khi có sự cố | đổi trọng số về 0 cho phiên bản mới |
⚠ Điểm mấu chốt: chỉ ALIAS mới chia được lưu lượng — bản thân version thì không:
Version của Lambda: bất biến, mỗi bản là một số ($LATEST, 1, 2, 3...)
↓
Một version chỉ là chính nó, không trỏ đi đâu, không chia lưu lượng
↓
Alias: một con trỏ có tên (prod, staging) trỏ tới một version
↓
Với routing-config, alias trỏ tới HAI version kèm trọng số
↓
→ 90% lời gọi vào version 5, 10% vào version 6
Đây là lý do phương án D sai: nó dùng đúng tham số nhưng gắn vào sai đối tượng.
# xuất bản phiên bản mới
aws lambda publish-version --function-name xu-ly-don
# alias prod: 90% về version 5, 10% về version 6
aws lambda update-alias --function-name xu-ly-don --name prod \
--function-version 5 \
--routing-config '{"AdditionalVersionWeights":{"6":0.1}}'
# tăng dần
aws lambda update-alias --function-name xu-ly-don --name prod \
--function-version 5 --routing-config '{"AdditionalVersionWeights":{"6":0.5}}'
# lùi lại tức thì
aws lambda update-alias --function-name xu-ly-don --name prod \
--function-version 5 --routing-config '{}'
⚠ Người gọi phải trỏ tới ALIAS, không trỏ thẳng tới version hay tới hàm:
API Gateway hoặc event source trỏ thẳng vào ARN của hàm
↓
Lời gọi đi vào $LATEST, bỏ qua toàn bộ cơ chế alias
↓
→ routing-config không có tác dụng gì, mà cũng không có lỗi nào
↓
→ ARN phải có hậu tố alias: arn:...:function:xu-ly-don:prod
Vì sao các phương án khác sai
-
D (tạo version cho mỗi lần cập nhật, dùng
update-function-configurationvới tham sốrouting-config) — đây là phương án gần nhất và nó chỉ sai đúng một lệnh: phần "tạo version cho mỗi lần cập nhật" là đúng và cần thiết, và nó cũng nhận rarouting-configlà thứ cần dùng. Nhưngupdate-function-configurationkhông có tham số--routing-config— lệnh đó chỉnh cấu hình của chính hàm (bộ nhớ, timeout, biến môi trường, VPC). Chia trọng số là thuộc tính của alias, nên lệnh đúng làupdate-alias. Đây là bẫy kiểm tra đúng một chi tiết API, và là kiểu câu thưởng cho người đã thật sự gõ lệnh đó. -
A (CodeDeploy với cấu hình
CodeDeployDefault.HalfAtATime) — CodeDeploy thật sự triển khai Lambda được và là công cụ rất hợp lý cho canary. NhưngHalfAtATimelà cấu hình dành cho EC2/On-premises, không phải cho Lambda, và nó không phải canary — nó cập nhật một nửa số instance cùng lúc. Cấu hình Lambda của CodeDeploy có tên khác hẳn:Canary10Percent5Minutes,Linear10PercentEvery1Minute,AllAtOnce. Nếu phương án nêu đúng một trong những cái đó thì đã là câu trả lời tốt. -
B (triển khai vào một CloudFormation stack mới, dùng Route 53 weighted routing để chia tải) — nặng nề và sai tầng. Route 53 chia lưu lượng ở tầng DNS, chỉ có tác dụng khi người gọi phân giải tên miền — nó không áp dụng cho lời gọi Lambda từ event source như S3, SQS hay EventBridge. Dựng cả một stack song song cũng tốn kém hơn nhiều so với việc đổi một tham số trên alias.
Ghi nhớ
⚠ Bốn khái niệm phiên bản của Lambda — bảng phải thuộc: | Khái niệm | Nội dung | |---|---| | $LATEST | bản đang sửa, luôn thay đổi | | Version | ảnh chụp bất biến, đánh số tăng dần | | Alias | con trỏ có tên tới version, chia trọng số được | | Layer | thư viện dùng chung, có version riêng |
Từ khoá nhận diện:
"canary" / "weighted traffic" cho Lambda → alias với
routing-config"rollback quickly" → đổi trọng số về 0, tức thìupdate-function-configuration --routing-config→ LUÔN SAI, không có tham số đóCodeDeployDefault.HalfAtATimecho Lambda → SAI, đó là cấu hình cho EC2 Route 53 weighted routing cho Lambda → SAI tầng, không áp cho event source
| Cấu hình triển khai Lambda của CodeDeploy | Nội dung |
|---|---|
Canary10Percent5Minutes |
10% trong 5 phút rồi chuyển hết |
Canary10Percent30Minutes |
như trên, cửa sổ dài hơn |
Linear10PercentEvery1Minute |
tăng đều 10% mỗi phút |
AllAtOnce |
chuyển ngay toàn bộ |
| Điều cần nhớ về routing-config | Nội dung |
|---|---|
| Số version chia được | tối đa 2 |
| Trọng số | 0.0 tới 1.0 cho version phụ |
| Không dùng được với | $LATEST — phải là version đã publish |
| Provisioned concurrency | cấu hình riêng cho từng version |
| Giám sát trong lúc canary | Chỉ số |
|---|---|
Errors và Throttles |
theo từng version, không chỉ theo hàm |
Duration |
so version mới với version cũ |
| Alarm | gắn với CodeDeploy để tự lùi lại khi vượt ngưỡng |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Lưu lượng có chia đúng không | so Invocations theo dimension ExecutedVersion | | Người gọi có trỏ tới alias không | kiểm ARN trong cấu hình event source | | Version mới có lỗi cao hơn không | so tỷ lệ lỗi giữa hai version |
Và một lời khuyên: hãy lọc chỉ số CloudWatch theo dimension ExecutedVersion khi chạy canary, đừng nhìn chỉ số tổng của hàm. Đây là lý do canary thường không phát hiện được vấn đề mà nó sinh ra để phát hiện: nếu version mới lỗi 100% nhưng chỉ nhận 10% lưu lượng, tỷ lệ lỗi tổng của hàm chỉ nhích lên 10% — một con số dễ bị bỏ qua như nhiễu, đặc biệt nếu hàm vốn đã có vài phần trăm lỗi nền. Bạn sẽ thấy biểu đồ hơi xấu đi, cho rằng cần theo dõi thêm, rồi tăng trọng số lên 50%. Chỉ khi tách theo version thì mới thấy rõ: một bên 0% lỗi, một bên 100%.
An application uses Amazon EC2 instances in an Auto Scaling group and an Amazon RDS MySQL database. The web application has occasional spikes of traffic during the day. The operations team have determined the most appropriate instances sizes for both the EC2 instances and the DB instance. All instances use On-Demand pricing.
What of the following steps can be taken to gain the most cost savings without impacting the reliability of the application?
-
A
Use Spot instance pricing for the RDS database and the EC2 instances in the Auto Scaling group.
-
B
Reserve capacity for the RDS database and the minimum number of EC2 instances that are constantly running.
-
C
Reserve capacity for all EC2 instances and leverage Spot Instance pricing for the RDS database.
-
D
Use On-Demand pricing for the RDS database and use Spot pricing for the EC2 instances in the Auto Scaling group
Xem giải thích
Đáp án
B — Mua dung lượng dự trữ (Reserved) cho cơ sở dữ liệu RDS và cho số lượng EC2 tối thiểu luôn chạy.
Vì sao đúng
Đề nêu ba dữ kiện, và chúng chỉ thẳng tới một mô hình chi phí: kích cỡ máy đã chốt, đỉnh tải chỉ thỉnh thoảng, không được ảnh hưởng độ tin cậy.
| Dữ kiện của đề | Suy ra |
|---|---|
| Kích cỡ đã xác định, không đổi | cam kết dài hạn được — điều kiện của RI |
| Auto Scaling group có phần nền luôn chạy | phần nền đó nên mua RI |
| Đỉnh tải thỉnh thoảng | phần co giãn giữ On-Demand |
| Không được ảnh hưởng độ tin cậy | loại Spot |
⚠ Điểm mấu chốt: chữ "without impacting the reliability" là thứ loại Spot khỏi mọi phương án:
Spot Instance có thể bị thu hồi với 2 phút báo trước
↓
Với tầng web sau Auto Scaling group, mất máy đột ngột là chấp nhận được
↓
Nhưng đề nói rõ "without impacting reliability"
↓
→ Spot đưa vào một yếu tố bất định mới, dù nhỏ
↓
→ và với RDS thì Spot KHÔNG TỒN TẠI
Mô hình đúng: tách đội máy thành hai phần.
Auto Scaling group
├── Phần nền (min capacity) — luôn chạy 24/7 → mua Reserved / Savings Plans
└── Phần co giãn theo đỉnh — chỉ vài giờ mỗi ngày → giữ On-Demand
Lý do rất đơn giản về số học: RI giảm tới 72% nhưng đòi cam kết chạy liên tục. Máy chỉ bật vài giờ mỗi ngày thì On-Demand rẻ hơn RI cho đúng máy đó.
Cơ sở dữ liệu RDS luôn thuộc nhóm mua RI: nó chạy 24/7, không tắt được, kích cỡ đã chốt — đúng hình mẫu của Reserved Instance.
# xem đề xuất dựa trên lịch sử sử dụng thật
aws ce get-reservation-purchase-recommendation \
--service "Amazon Relational Database Service" \
--lookback-period-in-days SIXTY_DAYS \
--term-in-years ONE_YEAR --payment-option NO_UPFRONT
⚠ Xác định "số lượng tối thiểu luôn chạy" bằng số liệu, đừng đoán:
Nhìn biểu đồ số instance đang chạy trong 60 ngày
↓
Lấy đường đáy — mức thấp nhất mà đội máy chưa bao giờ xuống dưới
↓
→ mua RI cho đúng mức đó
↓
Mua nhiều hơn → trả tiền cho dung lượng không dùng
Vì sao các phương án khác sai
-
D (On-Demand cho RDS, Spot cho EC2 trong Auto Scaling group) — đây là phương án gần nhất và nó đúng ở một điểm quan trọng: dùng Spot cho tầng web sau Auto Scaling group là mẫu hoàn toàn hợp lệ trong thực tế, và tiết kiệm được nhiều nhất. Nhưng nó vướng hai chỗ so với đề. Thứ nhất, đề nêu thẳng "without impacting the reliability" — Spot thêm khả năng bị thu hồi, và với ứng dụng web có đỉnh tải thì việc mất máy đúng lúc cao điểm là rủi ro thật. Thứ hai, và quan trọng hơn về mặt tiết kiệm: nó để RDS ở On-Demand, bỏ qua khoản giảm giá lớn nhất và chắc chắn nhất trong toàn bộ hệ thống — một cơ sở dữ liệu chạy 24/7 là ứng viên RI hoàn hảo. Câu hỏi đòi "most cost savings", và phương án bỏ sót khoản đó không thể thắng.
-
A (Spot cho cả RDS lẫn EC2) — RDS không chạy trên Spot; tuỳ chọn đó không tồn tại. Ngoài ra đặt cơ sở dữ liệu lên nền tảng có thể bị thu hồi là điều không ai làm.
-
C (RI cho TẤT CẢ EC2, Spot cho RDS) — hai lỗi. Mua RI cho toàn bộ instance nghĩa là trả tiền cam kết cho cả những máy chỉ bật vài giờ mỗi ngày lúc cao điểm — lãng phí đúng phần mà On-Demand phục vụ tốt hơn. Và một lần nữa, Spot cho RDS là điều không thể.
Ghi nhớ
⚠ Bốn mô hình giá và khối lượng công việc tương ứng — bảng phải thuộc: | Mô hình | Giảm giá | Hợp với | |---|---|---| | On-Demand | 0% | phần co giãn theo đỉnh, tải khó đoán | | Reserved Instance | tới 72% | phần nền chạy 24/7 | | Savings Plans | tới 72% | như RI nhưng linh hoạt hơn về lớp máy | | Spot | tới 90% | stateless, chịu được gián đoạn |
Từ khoá nhận diện:
"minimum number constantly running" → mua RI cho đúng phần đó "occasional spikes" → phần đỉnh giữ On-Demand "without impacting reliability" → loại Spot "RDS on Spot" → LUÔN SAI, không tồn tại "Reserve capacity for ALL instances" khi có co giãn → lãng phí phần đỉnh
| Savings Plans so với RI | Khác |
|---|---|
| Compute Savings Plans | linh hoạt nhất — áp cho EC2, Fargate, Lambda ở mọi Region và lớp máy |
| EC2 Instance Savings Plans | giảm sâu hơn, ràng buộc theo họ máy và Region |
| Standard RI | giảm sâu nhất, bán lại được trên Marketplace |
| Convertible RI | đổi được sang lớp máy khác, giảm ít hơn |
| RDS Reserved Instance | Chi tiết |
|---|---|
| Cam kết theo | lớp máy + engine + Region + Multi-AZ |
| Không cam kết theo | instance cụ thể — xoá rồi dựng lại vẫn được giảm |
| Cảnh báo | đổi lớp máy là RI thành vô dụng |
| Ba lựa chọn trả tiền | Mức giảm |
|---|---|
| All upfront | cao nhất |
| Partial upfront | trung bình |
| No upfront | thấp nhất, nhưng không cần vốn ban đầu |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Mức nền thật là bao nhiêu | biểu đồ số instance đang chạy trong 60 ngày, lấy đường đáy | | RI có được dùng hết không | báo cáo RI utilization trong Cost Explorer | | Bao nhiêu phần chi phí đã được phủ | báo cáo RI coverage |
Và một lời khuyên: hãy đặt AWS Budgets loại "RI utilization" với ngưỡng 90% ngay sau khi mua. Reserved Instance là khoản tiền đã trả trước cho một cấu hình cụ thể, và nó ngừng mang lại giá trị một cách hoàn toàn lặng lẽ: đội của bạn nâng cấp lên thế hệ máy mới, đổi sang Graviton, hay đơn giản là giảm mức nền xuống sau một đợt tối ưu — và từ đó RI vẫn tiếp tục được tính tiền đều đặn mỗi giờ trong khi không giảm giá cho gì cả. Không có cảnh báo, không có log, hoá đơn vẫn về đúng số tiền cam kết. Khoản lãng phí ấy chỉ hiện ra khi có người mở đúng báo cáo utilization, và trong nhiều tổ chức thì báo cáo đó không nằm trong thói quen của ai cả.
A media advertising company currently has resources hosted in two AWS accounts: Management and Production. DNS records are stored in a private hosted zone using Amazon Route 53 in the Management account. The Production account is used for applications and databases.
The company has deployed a two-tier application in a new VPC. To simplify the configuration, the database.company.com CNAME record set for the Amazon RDS endpoint was created in a private hosted zone for Amazon Route 53.
While deploying, the application failed to start. Troubleshooting revealed that database.company.com is not resolvable within the Amazon EC2 instance. The solutions architect confirmed that the record set was created correctly in Route 53.
Which combination of steps should the solutions architect take to resolve this issue? (Select TWO.)
-
A
Use SSH to connect to the application tier EC2 instance. Add an RDS endpoint IP address to the /etc/resolv.conf file.
-
B
Create a private hosted zone for the example.com domain in the Production account. Configure Route 53 replication between AWS accounts.
-
C
Associate a new VPC in the Production account with a hosted zone in the Management account. Delete the association authorization in the Management account.
-
D
Deploy the database on a separate EC2 instance in the new VPC. Create a record set for the instance's private IP in the private hosted zone.
-
E
Create an authorization to associate the private hosted zone in the Management account with the new VPC in the Production account.
Xem giải thích
Đáp án
C, E — hai bước để EC2 ở tài khoản Production phân giải được bản ghi trong private hosted zone thuộc tài khoản Management:
- E — Tạo authorization để liên kết private hosted zone ở tài khoản Management với VPC mới ở tài khoản Production.
- C — Liên kết VPC mới ở tài khoản Production với hosted zone ở tài khoản Management, rồi xoá authorization ở tài khoản Management.
Vì sao đúng
Nguyên nhân sự cố rất cụ thể: private hosted zone chỉ phân giải được từ những VPC đã được liên kết với nó. VPC mới chưa được liên kết, nên bản ghi tồn tại nhưng vô hình.
| Sự thật trong đề | Suy ra |
|---|---|
| Bản ghi đã tạo đúng | không phải lỗi cấu hình DNS |
| Hosted zone ở tài khoản Management | khác tài khoản với VPC |
| VPC mới ở tài khoản Production | chưa nằm trong danh sách liên kết |
⚠ Điểm mấu chốt: liên kết private hosted zone LIÊN TÀI KHOẢN là quy trình hai bước, hai bên, theo đúng thứ tự:
Bước 1 — tài khoản Management (chủ hosted zone):
create-vpc-association-authorization
↓
"Tôi cho phép VPC vpc-xxx ở tài khoản Production liên kết với zone này"
Bước 2 — tài khoản Production (chủ VPC):
associate-vpc-with-hosted-zone
↓
"Tôi chấp nhận, liên kết ngay"
Bước 3 — dọn dẹp:
delete-vpc-association-authorization
↓
→ authorization đã dùng xong, xoá đi để không tồn tại quyền treo
Đây là lý do đề đòi hai phương án: E là bước cấp phép, C là bước thực hiện cộng với dọn dẹp. Thiếu một trong hai thì không có gì xảy ra.
# Ở tài khoản Management
aws route53 create-vpc-association-authorization \
--hosted-zone-id Z1ABCDEF --vpc VPCRegion=ap-southeast-1,VPCId=vpc-moi
# Ở tài khoản Production
aws route53 associate-vpc-with-hosted-zone \
--hosted-zone-id Z1ABCDEF --vpc VPCRegion=ap-southeast-1,VPCId=vpc-moi
# Quay lại tài khoản Management dọn dẹp
aws route53 delete-vpc-association-authorization \
--hosted-zone-id Z1ABCDEF --vpc VPCRegion=ap-southeast-1,VPCId=vpc-moi
⚠ Xoá authorization KHÔNG gỡ liên kết đã tạo — đây là điểm hay bị hiểu nhầm:
Authorization chỉ là một phiếu cho phép, dùng một lần
↓
Sau khi liên kết đã thiết lập, phiếu đó không còn tác dụng gì
↓
Xoá phiếu → liên kết VẪN CÒN nguyên
↓
→ nên bước dọn dẹp trong phương án C là đúng thực hành, không phá gì cả
Ngoài ra, VPC phải bật cả enableDnsSupport lẫn enableDnsHostnames thì private hosted zone mới hoạt động.
Vì sao các phương án khác sai
-
B (tạo private hosted zone cho
example.comở tài khoản Production, cấu hình "Route 53 replication" giữa các tài khoản) — đây là phương án gần nhất và ý tưởng đưa zone về gần VPC là hợp lý. Nhưng không tồn tại tính năng nào tên là "Route 53 replication giữa các tài khoản" — Route 53 không sao chép hosted zone. Tạo một zone trùng tên ở tài khoản khác cũng tạo ra hai nguồn sự thật phải đồng bộ bằng tay, đúng thứ mà việc liên kết VPC sinh ra để tránh. Đây là bẫy mô tả một cơ chế nghe hợp lý nhưng không có thật. -
A (SSH vào EC2 và thêm địa chỉ IP của RDS vào
/etc/resolv.conf) — sai kỹ thuật ở nhiều tầng.resolv.confkhai máy chủ DNS, không khai bản ghi tên miền — thêm IP của RDS vào đó nghĩa là bảo hệ điều hành coi RDS là một DNS server, điều vô nghĩa. Kể cả nếu sửa/etc/hoststhay vào đó thì đây vẫn là cách làm thủ công trên từng máy, không co giãn, và địa chỉ IP của RDS endpoint thay đổi khi chuyển dự phòng. -
D (triển khai cơ sở dữ liệu trên một EC2 riêng trong VPC mới, tạo bản ghi cho IP riêng của instance) — thay đổi cả kiến trúc để né một vấn đề cấu hình DNS. Nó vứt bỏ RDS cùng toàn bộ lợi ích có quản lý, và vẫn để lại nguyên vấn đề gốc: VPC mới chưa liên kết với hosted zone.
Ghi nhớ
⚠ Bốn điều về private hosted zone — bảng phải thuộc: | Điều | Nội dung | |---|---| | Chỉ phân giải được từ VPC đã liên kết | VPC chưa liên kết thì bản ghi vô hình | | Liên kết nhiều VPC | được, kể cả khác Region | | Liên tài quản | cần authorization + associate, hai bên | | Điều kiện VPC | enableDnsSupport và enableDnsHostnames đều phải bật |
Từ khoá nhận diện:
"record created correctly but not resolvable" → VPC chưa liên kết với hosted zone "private hosted zone ở tài khoản khác" → create-vpc-association-authorization rồi associate "Route 53 replication between accounts" → LUÔN SAI, không tồn tại "sửa /etc/resolv.conf" → SAI kỹ thuật và không co giãn VPC Resolver → địa chỉ CIDR của VPC + 2 |
| Public so với private hosted zone | Khác |
|---|---|
| Public | phân giải từ Internet |
| Private | chỉ từ VPC đã liên kết |
| Cùng tên miền cả hai | được — split-horizon DNS, VPC thấy bản private |
| Cách chia sẻ DNS giữa các tài khoản | Cách |
|---|---|
| Liên kết VPC với private hosted zone | đơn giản nhất, đúng bài này |
| Route 53 Resolver rule chia sẻ qua RAM | quy mô lớn, nhiều tài khoản, nhiều zone |
| Profiles (mới) | gói cấu hình DNS chia sẻ cho nhiều VPC |
| Lỗi hay gặp với private hosted zone | Nguyên nhân |
|---|---|
| Không phân giải được | VPC chưa liên kết |
| Phân giải ở VPC này được, VPC kia không | chỉ liên kết một VPC |
| Sau khi liên kết vẫn không được | enableDnsHostnames chưa bật |
| Máy trong VPC hỏi DNS của AD | DHCP options set trỏ đi nơi khác |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Zone đã liên kết VPC nào | aws route53 get-hosted-zone --id <id>, xem VPCs | | Hỏi thẳng VPC Resolver | dig @<cidr+2> database.company.com | | Thuộc tính VPC | describe-vpc-attribute cho cả hai cờ DNS |
Và một lời khuyên: hãy đưa bước liên kết VPC vào chính template dựng VPC, đừng để nó thành thao tác tay sau khi triển khai. Đây là sự cố sẽ lặp lại với mọi VPC mới trong tương lai, và nó lặp lại theo cách tốn thời gian nhất: ứng dụng triển khai thành công, hạ tầng hiện đầy đủ và khoẻ mạnh, bản ghi DNS nằm đúng chỗ và hiển thị đúng trong console Route 53 — chỉ có ứng dụng là không khởi động được. Mọi thứ bạn kiểm tra đều đúng, vì phần sai không nằm ở cấu hình nào cả mà nằm ở một liên kết chưa tồn tại, và không có màn hình nào hiển thị danh sách những thứ lẽ ra phải được liên kết.
A company has deployed a web application in an Amazon VPC. A CloudFront distribution is used for both scalability and performance. The operations team has noticed that the cache hit ratio has been dropping over time leading to a gradual degradation of the performance for the web application.
The cache metrics report indicates that query strings on some URLs are inconsistently ordered and are specified in a mixture of mixed-case letters.
Which actions can a Solutions Architect take to increase the cache hit ratio and resolve the performance issues on the web application?
-
A
Use AWS WAF to create a WebACL and filter based on the case of the query strings in the URL. Configure WAF to trigger an AWS Lambda function that rewrites the URLs to lowercase.
-
B
Update the CloudFront distribution to disable caching based on query string parameters.
-
C
Create a path pattern in the CloudFront distribution that forwards all requests to the origin with case-sensitivity turned off.
-
D
Create a Lambda@Edge function to sort parameters by name and force them to be lowercase. Select the CloudFront viewer request trigger to invoke the function.
Xem giải thích
Đáp án
D — Tạo Lambda@Edge function sắp xếp tham số theo tên và chuyển hết về chữ thường; gắn vào trigger viewer request của CloudFront.
Vì sao đúng
Đề nói rõ nguyên nhân: query string trên một số URL có thứ tự không nhất quán và viết hoa thường lẫn lộn. Với CloudFront, mỗi biến thể là một cache key khác nhau.
| Sự thật trong đề | Suy ra |
|---|---|
| Tỷ lệ trúng cache giảm dần | mỗi biến thể tạo một mục cache riêng |
| Query string thứ tự khác nhau | ?a=1&b=2 và ?b=2&a=1 là hai key |
| Hoa thường lẫn lộn | ?Color=Red và ?color=red là hai key |
⚠ Điểm mấu chốt: CloudFront so cache key theo chuỗi CHÍNH XÁC, nên phải chuẩn hoá TRƯỚC khi tra cache:
Request: /san-pham?Color=Red&size=L
↓
Viewer request trigger — chạy TRƯỚC khi tra cache
↓
Lambda@Edge viết lại thành: /san-pham?color=red&size=l
↓
Mọi biến thể của cùng một truy vấn hội tụ về MỘT chuỗi
↓
→ một mục cache duy nhất thay vì hàng chục
Vị trí trigger là chi tiết quyết định. Bốn điểm móc của CloudFront chạy ở bốn thời điểm khác nhau:
| Trigger | Chạy khi | Dùng được cho bài này |
|---|---|---|
| Viewer request | ngay khi nhận request, TRƯỚC khi tra cache | có — đây là chỗ duy nhất đúng |
| Origin request | chỉ khi cache trượt | không — đã trượt rồi mới chạy |
| Origin response | sau khi origin trả lời | không |
| Viewer response | trước khi trả cho khách | không |
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
if (!request.querystring) return request;
const thamSo = request.querystring.split('&')
.map(cap => {
const [ten, gia = ''] = cap.split('=');
return [ten.toLowerCase(), gia.toLowerCase()];
})
.sort((a, b) => a[0].localeCompare(b[0]))
.map(([ten, gia]) => `${ten}=${gia}`);
request.querystring = thamSo.join('&');
return request;
};
⚠ Chuẩn hoá giá trị về chữ thường có thể làm hỏng ngữ nghĩa — cân nhắc từng tham số:
?token=AbC123 → ?token=abc123
↓
Token, chữ ký, id phân biệt hoa thường đã bị phá
↓
→ chỉ hạ chữ thường cho TÊN tham số và cho những giá trị bạn biết là an toàn
Vì sao các phương án khác sai
-
B (tắt hoàn toàn việc cache theo query string) — đây là phương án gần nhất và nó thật sự làm tỷ lệ trúng cache tăng vọt lên gần 100%: bỏ query string khỏi cache key thì mọi biến thể gộp thành một. Nhưng nó phá vỡ tính đúng đắn của ứng dụng. Nếu
?san-pham=123và?san-pham=456cùng chia sẻ một mục cache, khách hàng thứ hai sẽ nhận về nội dung của khách thứ nhất. Đây là kiểu tối ưu đổi một vấn đề hiệu năng lấy một vấn đề dữ liệu sai — và vấn đề thứ hai luôn tệ hơn. Nó chỉ đúng khi query string thật sự không ảnh hưởng nội dung (ví dụ chỉ chứa tham số theo dõi quảng cáo), điều đề không nói. -
A (WAF WebACL lọc theo hoa thường trong URL, kích hoạt Lambda viết lại URL) — sai vai trò dịch vụ. WAF chặn hoặc cho qua, nó không viết lại request và cũng không "kích hoạt Lambda để rewrite". WAF có
transformationtrong luật nhưng đó là để chuẩn hoá trước khi so khớp luật, không đổi request thật gửi đi. Cơ chế viết lại request ở tầng biên là Lambda@Edge hoặc CloudFront Function. -
C (tạo path pattern trong distribution chuyển tiếp mọi request tới origin với "case-sensitivity turned off") — mô tả một thiết lập không tồn tại. CloudFront không có tuỳ chọn tắt phân biệt hoa thường, và path pattern khớp theo đường dẫn chứ không xử lý query string. Chuyển tiếp mọi request tới origin cũng có nghĩa là không cache gì cả, đi ngược mục tiêu.
Ghi nhớ
⚠ Bốn thứ tạo nên cache key của CloudFront — bảng phải thuộc: | Thành phần | Mặc định | |---|---| | Đường dẫn (path) | luôn có | | Query string | tuỳ cache policy: none / whitelist / all | | Header | tuỳ cache policy | | Cookie | tuỳ cache policy |
Nguyên tắc: càng nhiều thứ trong cache key, tỷ lệ trúng càng thấp.
Từ khoá nhận diện:
"cache hit ratio dropping" + query string lộn xộn → chuẩn hoá bằng Lambda@Edge/CloudFront Function ở viewer request "viewer request" → trước khi tra cache — chỗ duy nhất chuẩn hoá được "disable caching based on query string" khi query string ảnh hưởng nội dung → SAI, trả sai nội dung "WAF viết lại URL" → SAI, WAF không rewrite "tắt case-sensitivity của CloudFront" → LUÔN SAI, không có tuỳ chọn đó
| CloudFront Functions so với Lambda@Edge | Chọn |
|---|---|
| CloudFront Functions | viết lại URL, header đơn giản — dưới 1 ms, rẻ hơn nhiều |
| Lambda@Edge | cần gọi mạng, xử lý thân request, chạy lâu hơn |
Với bài này, CloudFront Function thực ra là lựa chọn tối ưu hơn — nhưng nó không có trong danh sách phương án.
| Cách tăng tỷ lệ trúng cache | Nội dung |
|---|---|
| Chuẩn hoá query string | sắp xếp, hạ chữ thường |
| Chỉ đưa header cần thiết vào cache key | tránh User-Agent thô |
| Tăng TTL | Cache-Control từ origin, hoặc min/default TTL |
| Bật compression | giảm băng thông, không đổi tỷ lệ trúng |
| Origin Shield | thêm một lớp cache trung gian, giảm tải origin |
| Chỉ số cần theo dõi | Ý nghĩa |
|---|---|
CacheHitRate |
phần trăm request phục vụ từ cache |
OriginLatency |
origin trả lời chậm hay nhanh |
4xxErrorRate / 5xxErrorRate |
sức khoẻ chung |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tỷ lệ trúng cache hiện tại | chỉ số CacheHitRate | | Biến thể nào đang phá cache | phân tích log CloudFront bằng Athena, nhóm theo query string | | Hàm có chạy không | log của Lambda@Edge nằm ở Region gần điểm biên, không phải Region gốc |
Và một lời khuyên: hãy phân tích log CloudFront bằng Athena để tìm ra chính xác những biến thể nào đang phá cache, trước khi viết hàm chuẩn hoá. Đây là chỗ dễ tối ưu nhầm nhất: bạn giả định vấn đề nằm ở thứ tự tham số, viết một hàm sắp xếp rất gọn, triển khai — và tỷ lệ trúng cache gần như không nhúc nhích, vì thủ phạm thật là một tham số theo dõi quảng cáo có giá trị duy nhất cho mỗi lượt truy cập, thứ mà không có cách chuẩn hoá nào cứu được. Với tham số kiểu đó, cách chữa là loại nó ra khỏi cache key, không phải sắp xếp lại nó. Log nói cho bạn biết điều đó trong mười phút; phỏng đoán thì tốn cả một chu kỳ triển khai.
A retail company is transitioning its sales data processing system to AWS. The system must handle fluctuating sales data inputs, especially during seasonal peaks. The data processing involves receiving sales transactions, processing them for analytics, and storing the results in an Amazon RDS instance. The system should be able to handle variable loads without manual intervention for scaling.
Which architecture would BEST meet these requirements?
-
A
Implement an Amazon Kinesis Data Firehose for ingesting sales transactions and process them using AWS Lambda functions before storing in an Amazon RDS instance.
-
B
Utilize Amazon EC2 instances to receive sales transactions and process them. Use Amazon EC2 Auto Scaling to scale up the instances based on a schedule of peak times.
-
C
Configure an AWS Step Functions workflow to manage the sales transactions and process them through scheduled AWS Batch jobs before storage the processed data in an Amazon RDS instance.
-
D
Implement the system on an Amazon ECS cluster with auto-scaling enabled for receiving and processing sales transactions and store the processed data in an Amazon RDS instance.
Xem giải thích
Đáp án
A — Dùng Kinesis Data Firehose nhận giao dịch bán hàng và xử lý bằng Lambda trước khi lưu vào Amazon RDS.
Vì sao đúng
Đề đòi xử lý tải biến động, đặc biệt là đỉnh theo mùa, mà không cần can thiệp thủ công để co giãn. Firehose là dịch vụ hoàn toàn có quản lý, tự co giãn theo thông lượng.
| Yêu cầu của đề | Cách đáp ứng |
|---|---|
| Tải biến động, có đỉnh theo mùa | Firehose tự co giãn, không khai dung lượng |
| Không can thiệp thủ công | không có shard để thêm, không có instance để chỉnh |
| Xử lý trước khi lưu | Firehose gọi Lambda để biến đổi ngay trong luồng |
| Lưu vào RDS | qua Lambda, hoặc qua S3 rồi nạp |
⚠ Điểm mấu chốt: Firehose co giãn hoàn toàn tự động, còn Data Streams thì bạn phải quản shard:
Kinesis Data Firehose
↓
Không có khái niệm shard hiển thị ra ngoài
↓
Thông lượng tự tăng theo lượng dữ liệu vào
↓
→ đúng nghĩa "without manual intervention for scaling"
Kinesis Data Streams (chế độ provisioned)
↓
Phải tự tính và chỉnh số shard
↓
→ có can thiệp thủ công, trừ khi dùng chế độ on-demand
Biến đổi bằng Lambda ngay trong Firehose là tính năng có sẵn, không phải thứ phải tự nối:
import base64, json
def handler(su_kien, ngu_canh):
ket_qua = []
for ban_ghi in su_kien['records']:
du_lieu = json.loads(base64.b64decode(ban_ghi['data']))
du_lieu['tong'] = du_lieu['so_luong'] * du_lieu['don_gia']
ket_qua.append({
'recordId': ban_ghi['recordId'],
'result': 'Ok',
'data': base64.b64encode(json.dumps(du_lieu).encode()).decode()})
return {'records': ket_qua}
⚠ Firehose gom dữ liệu theo lô — có độ trễ tính bằng phút, không phải giây:
Buffer size (1–128 MB) hoặc buffer interval (60–900 giây)
↓
Đạt một trong hai ngưỡng thì Firehose mới ghi ra đích
↓
→ độ trễ tối thiểu khoảng 60 giây
↓
→ đề nói "process for analytics", không đòi thời gian thực dưới giây,
nên đánh đổi này chấp nhận được
Vì sao các phương án khác sai
-
D (ECS cluster có auto scaling để nhận và xử lý giao dịch, lưu vào RDS) — đây là phương án gần nhất và nó thật sự tự co giãn được: ECS service auto scaling phản ứng theo chỉ số và không cần người can thiệp. Nhưng nó nhiều việc vận hành hơn hẳn: phải đóng gói image, quản lý task definition, cấu hình chính sách co giãn, xử lý cold start của task, và quan trọng nhất — không có bộ đệm giữa nguồn và tầng xử lý. Khi đỉnh mùa tới, lưu lượng đập thẳng vào các task đang chạy trong lúc auto scaling còn đang phản ứng, nên vẫn có khoảng bị quá tải. Firehose hấp thụ đỉnh ngay lập tức vì nó vốn là một bộ đệm.
-
B (EC2 nhận giao dịch, Auto Scaling theo LỊCH của giờ cao điểm) — vi phạm thẳng yêu cầu "without manual intervention for scaling". Co giãn theo lịch đòi ai đó biết trước khi nào cao điểm và cập nhật lịch mỗi mùa. Đỉnh tải bất thường nằm ngoài lịch sẽ không được phục vụ, còn lịch đặt rộng tay thì trả tiền cho dung lượng không dùng.
-
C (Step Functions điều phối, AWS Batch job theo lịch, rồi lưu vào RDS) — sai về độ trễ và về mô hình. Batch job chạy theo lịch nghĩa là dữ liệu nằm chờ tới lần chạy kế tiếp — không phù hợp với việc nhận giao dịch liên tục. AWS Batch dành cho khối lượng tính toán nặng theo lô, không phải cho luồng giao dịch nhỏ và liên tục.
Ghi nhớ
⚠ Bốn cách nhận dữ liệu luồng — bảng phải thuộc: | Cách | Co giãn | Độ trễ | |---|---|---| | Firehose | hoàn toàn tự động | 60 giây trở lên | | Data Streams (on-demand) | tự động | dưới một giây | | Data Streams (provisioned) | phải chỉnh shard | dưới một giây | | API Gateway + Lambda | tự động | tức thì, nhưng tính tiền theo request |
Từ khoá nhận diện:
"without manual intervention for scaling" → Firehose hoặc on-demand "process before storing" → Firehose với Lambda transformation "scheduled scaling" → SAI khi đề đòi không can thiệp thủ công "Batch jobs theo lịch" cho luồng giao dịch → SAI về độ trễ và mô hình cần dưới một giây → Data Streams, không phải Firehose
| Đích của Firehose | Hỗ trợ |
|---|---|
| S3, Redshift, OpenSearch, Splunk | trực tiếp |
| HTTP endpoint | được, dùng cho đích tuỳ ý |
| RDS | không trực tiếp — qua Lambda hoặc qua S3 rồi nạp |
| Thiết lập buffer của Firehose | Khoảng |
|---|---|
| Buffer size | 1–128 MB |
| Buffer interval | 60–900 giây |
| Nguyên tắc | đạt một trong hai là ghi |
| Tính năng đáng bật của Firehose | Việc |
|---|---|
| Chuyển định dạng | JSON → Parquet/ORC, giảm mạnh chi phí truy vấn sau này |
| Dynamic partitioning | phân vùng S3 theo giá trị trong bản ghi |
| Nén | GZIP, Snappy, ZIP |
| S3 backup | giữ bản ghi thô, kể cả bản ghi biến đổi lỗi |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Có bị nghẽn không | ThrottledRecords của Firehose | | Biến đổi có lỗi không | SucceedRecords so với FailedRecords của Lambda transformation | | Dữ liệu tới đích chưa | DeliveryToS3.Success hoặc chỉ số tương ứng của đích |
Và một lời khuyên: hãy bật S3 backup cho các bản ghi biến đổi lỗi ngay khi cấu hình Firehose. Đây là chỗ dữ liệu biến mất mà không ai nhận ra: nếu Lambda transformation trả về ProcessingFailed cho một bản ghi — vì JSON sai định dạng, vì một trường thiếu, vì một giá trị ngoài dự kiến — Firehose bỏ bản ghi đó đi và tiếp tục với những bản ghi còn lại. Luồng vẫn chạy, đích vẫn nhận dữ liệu đều đặn, không có cảnh báo nào — chỉ là một phần giao dịch không bao giờ tới nơi. Với dữ liệu bán hàng, phần bị mất thường lại chính là những giao dịch bất thường nhất, tức là những giao dịch đáng phân tích nhất.
A company offers a photo sharing application to its users through a social networking app. To ensure images can be displayed with consistency, a single Amazon EC2 instance running JavaScript code processes the photos and stores the processed images in an Amazon S3 bucket. A front-end application runs from a static website in another S3 bucket and loads the processed images for display in the app.
The company has asked a Solutions Architect to make some recommendations for a cost-effective solution that offers massive scalability for a global user base.
Which combination of changes should the Solutions Architect recommend? (Select TWO.)
-
A
Create an Amazon CloudFront distribution in front of the processed images bucket.
-
B
Deploy the applications in an Amazon ECS cluster and apply Service Auto Scaling.
-
C
Replace the EC2 instance with AWS Lambda to run the image processing tasks.
-
D
Place the image processing EC2 instance into an Auto Scaling group.
-
E
Replace the EC2 instance with Amazon Rekognition for image processing.
Xem giải thích
Đáp án
A, C — hai thay đổi cho khả năng mở rộng toàn cầu với chi phí hợp lý:
- C — Thay EC2 instance bằng AWS Lambda để chạy tác vụ xử lý ảnh.
- A — Tạo CloudFront distribution đứng trước bucket S3 chứa ảnh đã xử lý.
Vì sao đúng
Đề nêu hai mục tiêu — cost-effective và massive scalability cho người dùng toàn cầu — và kiến trúc hiện tại có đúng hai điểm nghẽn tương ứng.
| Điểm nghẽn hiện tại | Cách chữa |
|---|---|
| Một EC2 xử lý toàn bộ ảnh | C — Lambda, mỗi ảnh một lời gọi song song |
| Ảnh phục vụ trực tiếp từ S3, người dùng ở xa | A — CloudFront cache tại điểm biên |
⚠ Điểm mấu chốt: xử lý ảnh là tải theo sự kiện, ngắt quãng — đúng hình thái Lambda phục vụ tốt nhất:
Một EC2 duy nhất chạy 24/7
↓
Trả tiền cả lúc không có ảnh nào cần xử lý
Và là điểm nghẽn khi có nhiều ảnh cùng lúc
↓
Lambda kích hoạt bởi sự kiện S3
↓
Mỗi ảnh một lời gọi, chạy song song tới hàng nghìn
Không có ảnh thì không tốn gì
↓
→ vừa mở rộng vừa rẻ hơn, và bỏ luôn việc quản máy chủ
Vì sao CloudFront cho phần phục vụ. Đề nói "global user base". Phục vụ ảnh trực tiếp từ S3 nghĩa là mọi người dùng đều kéo dữ liệu từ một Region duy nhất. CloudFront cache tại điểm biên gần họ, và còn rẻ hơn: phí truyền dữ liệu ra Internet của CloudFront thấp hơn của S3, và các lượt trúng cache không tính phí request tới S3.
# Lambda xử lý ảnh, kích hoạt bởi sự kiện S3
import boto3, io
from PIL import Image
s3 = boto3.client('s3')
def handler(su_kien, ngu_canh):
for ban_ghi in su_kien['Records']:
bucket = ban_ghi['s3']['bucket']['name']
khoa = ban_ghi['s3']['object']['key']
anh_goc = s3.get_object(Bucket=bucket, Key=khoa)['Body'].read()
anh = Image.open(io.BytesIO(anh_goc))
anh.thumbnail((1200, 1200))
dem = io.BytesIO(); anh.save(dem, format='JPEG', quality=85); dem.seek(0)
s3.put_object(Bucket='anh-da-xu-ly', Key=khoa, Body=dem)
⚠ Ghi kết quả vào bucket KHÁC với bucket nguồn, nếu không sẽ có vòng lặp vô hạn:
Lambda ghi ảnh đã xử lý vào cùng bucket đang lắng nghe sự kiện
↓
Việc ghi đó sinh ra một sự kiện mới
↓
Lambda lại chạy, lại ghi, lại sinh sự kiện
↓
→ vòng lặp chạy tới khi cạn concurrency, và hoá đơn thì không dừng lại
Vì sao các phương án khác sai
-
D (đưa EC2 xử lý ảnh vào Auto Scaling group) — đây là phương án gần nhất và nó thật sự giải quyết được vấn đề mở rộng: Auto Scaling thêm máy khi tải tăng, và đây là mẫu kiến trúc hợp lệ. Nhưng nó thua Lambda ở đúng tiêu chí thứ hai của đề. Auto Scaling phản ứng theo chỉ số nên mất vài phút mới thêm được máy, trong khi Lambda co giãn tức thì theo từng sự kiện. Về chi phí, Auto Scaling group luôn phải giữ ít nhất một máy chạy 24/7 để hứng công việc, còn Lambda thì không tốn gì khi rảnh. Với tải ngắt quãng theo sự kiện như xử lý ảnh, Lambda rẻ hơn đáng kể và không có máy nào phải vá lỗi.
-
B (triển khai ứng dụng trong ECS cluster với Service Auto Scaling) — cùng nhóm lý do với D, và còn thêm việc phải quản lý container image, task definition, cluster. Với một tác vụ đơn lẻ chạy vài giây mỗi ảnh, container là mức phức tạp không cần thiết.
-
E (thay EC2 bằng Amazon Rekognition để xử lý ảnh) — sai loại công việc. Rekognition PHÂN TÍCH ảnh — nhận diện vật thể, khuôn mặt, văn bản, kiểm duyệt nội dung. Nó không biến đổi ảnh: không đổi kích cỡ, không nén, không thêm chú thích. Đề nói ứng dụng "xử lý ảnh để hiển thị nhất quán", tức là biến đổi hình ảnh — việc của một thư viện xử lý ảnh chạy trong Lambda, không phải của Rekognition.
Ghi nhớ
⚠ Bốn lựa chọn tính toán theo hình thái tải — bảng phải thuộc: | Hình thái tải | Lựa chọn | |---|---| | Theo sự kiện, ngắt quãng, dưới 15 phút | Lambda | | Chạy liên tục, cần kiểm soát môi trường | ECS/Fargate | | Chạy liên tục, cần kiểm soát máy | EC2 + Auto Scaling | | Job tính toán nặng theo lô | AWS Batch |
Từ khoá nhận diện:
"massive scalability" + xử lý theo sự kiện → Lambda "global user base" + nội dung tĩnh → CloudFront "Rekognition để xử lý ảnh" → SAI, Rekognition PHÂN TÍCH chứ không biến đổi "Auto Scaling group" cho tải theo sự kiện ngắn → chạy được nhưng đắt và chậm hơn Lambda "cost-effective" + máy chạy 24/7 cho tải ngắt quãng → luôn xét serverless trước
| Rekognition làm gì | Nội dung |
|---|---|
| Nhận diện nhãn, vật thể, cảnh | có |
| Nhận diện và so khuôn mặt | có |
| Trích xuất văn bản trong ảnh | có |
| Kiểm duyệt nội dung không phù hợp | có |
| Đổi kích cỡ, nén, cắt ảnh | KHÔNG |
| Giới hạn Lambda cần nhớ khi xử lý ảnh | Con số |
|---|---|
| Thời gian chạy | 15 phút |
| Bộ nhớ | tới 10.240 MB (CPU tỷ lệ theo) |
/tmp |
tới 10.240 MB — chỗ để giải nén ảnh lớn |
| Kích thước gói triển khai | 250 MB đã giải nén; dùng container image nếu thư viện nặng |
| Tối ưu chi phí phục vụ ảnh | Cách |
|---|---|
| CloudFront trước S3 | rẻ hơn và nhanh hơn |
| S3 Intelligent-Tiering | tự chuyển ảnh ít truy cập sang tầng rẻ |
| Lifecycle policy | xoá ảnh gốc sau khi đã xử lý xong |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Có vòng lặp không | theo dõi Invocations — tăng bất thường là dấu hiệu | | Tỷ lệ trúng cache | CacheHitRate của CloudFront | | Bộ nhớ có đủ không | dòng Max Memory Used trong log REPORT |
Và một lời khuyên: hãy đặt reserved concurrency cho hàm xử lý ảnh, ngay cả khi bạn tin rằng không có vòng lặp. Đây là loại sự cố gây thiệt hại tài chính nhanh nhất mà một kiến trúc theo sự kiện có thể tạo ra: một cấu hình nhầm khiến hàm ghi kết quả vào chính bucket nó đang lắng nghe, và vòng lặp bắt đầu chạy ở tốc độ tối đa mà tài khoản cho phép. Không có gì thất bại — mọi lời gọi đều thành công, mọi thao tác ghi đều hợp lệ, không có một dòng lỗi nào trong log. Thứ duy nhất tăng lên là số lời gọi, số object trong bucket, và hoá đơn. Một trần concurrency biến sự cố đó từ thảm hoạ cuối tuần thành một dòng bất thường trên biểu đồ.
A university is running computational algorithms that require large amounts of compute power. The algorithms are being run using a high-performance compute cluster on Amazon EC2 Spot instances. Each time an instance launches a DNS record must be created in an Amazon Route 53 private hosted zone. When the instance is terminated the DNS record must be deleted.
The current configuration uses an Amazon CloudWatch Events rule that triggers an AWS Lambda function to create the DNS record. When scaling the solution to thousands of instances the university has experienced “HTTP 400 error (Bad request)” errors in the Lambda logs. The response header also includes a status code element with a value of "Throttling" and a status message element with a value of "Rate exceeded".
Which combination of steps should the Solutions Architect take to resolve these issues? (Select THREE.)
-
A
Update the CloudWatch Events rule to trigger on Amazon EC2 "Instance Launch Successful" and "Instance Terminate Successful" events for the Auto Scaling group used by the cluster.
-
B
Configure an Amazon SQS FIFO queue and configure a CloudWatch Events rule to use this queue as a target. Remove the Lambda target from the CloudWatch Events rule.
-
C
Configure an Amazon SQS standard queue and configure the existing CloudWatch Events rule to use this queue as a target. Remove the Lambda target from the CloudWatch Events rule.
-
D
Configure a Lambda function to retrieve messages from an Amazon SQS queue. Modify the Lambda function to retrieve a maximum of 10 messages then batch the messages by Amazon Route 53 API call type and submit. Delete the messages from the SQS queue after successful API calls.
-
E
Configure an Amazon Kinesis data stream and configure a CloudWatch Events rule to use this queue as a target. Remove the Lambda target from the CloudWatch Events rule.
-
F
Configure a Lambda function to read data from the Amazon Kinesis data stream and configure the batch window to 5 minutes. Modify the function to make a single API call to Amazon Route 53 with all records read from the Kinesis data stream.
Xem giải thích
Đáp án
A, C, D — ba bước để gộp lời gọi và thoát khỏi lỗi throttling của Route 53:
- A — Sửa CloudWatch Events rule để kích hoạt theo sự kiện "Instance Launch Successful" và "Instance Terminate Successful" của Auto Scaling group.
- C — Tạo SQS standard queue và đặt nó làm target của rule, gỡ Lambda khỏi target.
- D — Lambda đọc tối đa 10 tin nhắn mỗi lần, gom theo loại lời gọi API của Route 53 rồi gửi một lần; xoá tin nhắn sau khi API thành công.
Vì sao đúng
Lỗi trong đề nói chính xác vấn đề: "Rate exceeded" với mã 400 — đó là throttling của API Route 53, không phải của Lambda.
| Sự thật trong đề | Suy ra |
|---|---|
| Hàng nghìn instance | hàng nghìn lời gọi API gần như đồng thời |
Lỗi Throttling, Rate exceeded |
vượt hạn mức API của Route 53 |
| Mỗi instance một lời gọi riêng | cần gom lô |
⚠ Điểm mấu chốt: Route 53 giới hạn 5 lời gọi API mỗi giây cho mỗi tài khoản — nên phải GỘP, không phải thử lại:
Cách cũ: mỗi instance → một Lambda → một ChangeResourceRecordSets
↓
1.000 instance khởi động cùng lúc → 1.000 lời gọi trong vài giây
↓
→ vượt xa 5 lời gọi/giây → throttling
Cách mới: sự kiện → SQS → Lambda đọc lô 10 → MỘT lời gọi cho cả 10 bản ghi
↓
ChangeResourceRecordSets nhận NHIỀU thay đổi trong một request
↓
→ giảm số lời gọi đi cả chục lần, và SQS làm phẳng đỉnh
Vì sao SQS standard chứ không FIFO (phương án B). FIFO giới hạn 300 thao tác mỗi giây — chính nó sẽ thành nút thắt mới. Và thứ tự không quan trọng ở đây: mỗi bản ghi DNS độc lập với nhau.
Vì sao đổi sang sự kiện của Auto Scaling group (A). Sự kiện lifecycle của Auto Scaling đáng tin cậy hơn sự kiện trạng thái EC2 thô, và nó khớp đúng thời điểm máy đã sẵn sàng hoặc đã kết thúc.
import boto3, json
r53 = boto3.client('route53')
def handler(su_kien, ngu_canh):
thay_doi = []
for ban_ghi in su_kien['Records']: # tối đa 10
d = json.loads(ban_ghi['body'])
thay_doi.append({
'Action': 'UPSERT' if d['loai'] == 'launch' else 'DELETE',
'ResourceRecordSet': {
'Name': d['ten'], 'Type': 'A', 'TTL': 60,
'ResourceRecords': [{'Value': d['ip']}]}})
# MỘT lời gọi cho cả lô
r53.change_resource_record_sets(
HostedZoneId='Z1ABCDEF',
ChangeBatch={'Changes': thay_doi})
⚠ Chỉ xoá tin nhắn sau khi API thành công — đó là cách không mất bản ghi nào:
Lambda ném lỗi → tin nhắn quay lại hàng đợi → thử lại sau
↓
Nuốt lỗi và trả về thành công → tin nhắn bị xoá → bản ghi DNS không bao giờ được tạo
Vì sao các phương án khác sai
-
F (Lambda đọc từ Kinesis data stream với batch window 5 phút, gọi một lần Route 53 với tất cả bản ghi đọc được) — đây là phương án gần nhất và ý tưởng gom lô của nó hoàn toàn đúng, thậm chí cửa sổ 5 phút cho lô lớn hơn 10. Nhưng nó vướng một giới hạn cứng:
ChangeResourceRecordSetschỉ nhận tối đa 1.000 thay đổi hoặc 32.000 ký tự mỗi request. Với cụm hàng nghìn instance khởi động đồng loạt, một cửa sổ 5 phút có thể gom được nhiều hơn thế, và lời gọi sẽ bị từ chối. Nó cũng đi kèm phương án E vốn dùng Kinesis — một dịch vụ nặng hơn cần thiết cho việc chỉ là đệm lại vài nghìn sự kiện, và không có cơ chế "trả tin nhắn về hàng đợi" đơn giản như SQS khi xử lý thất bại. -
B (SQS FIFO queue) — dùng đúng ý tưởng đệm nhưng chọn sai loại hàng đợi. FIFO giới hạn 300 thao tác mỗi giây (3.000 khi gom lô), thấp hơn nhiều so với standard queue vốn gần như không giới hạn. Với hàng nghìn instance, FIFO trở thành nút thắt mới. Thứ tự cũng không cần thiết vì các bản ghi DNS độc lập.
-
E (Kinesis data stream làm target của CloudWatch Events rule) — Kinesis là công cụ cho luồng dữ liệu liên tục khối lượng lớn; ở đây chỉ cần một bộ đệm cho các sự kiện rời rạc. Nó thêm việc quản shard và không cho cơ chế thử lại từng tin nhắn tự nhiên như SQS.
Ghi nhớ
⚠ Bốn cách xử lý lỗi throttling API — bảng phải thuộc, theo thứ tự hiệu quả: | Cách | Hiệu quả | |---|---| | Gom lô nhiều thao tác vào một lời gọi | cao nhất — giảm hẳn số request | | Đệm bằng hàng đợi rồi xử lý theo nhịp | cao — làm phẳng đỉnh | | Exponential backoff + jitter | trung bình — không giảm tổng số lời gọi | | Xin nâng hạn mức | tuỳ dịch vụ, không phải lúc nào cũng được |
Từ khoá nhận diện:
"Rate exceeded" / "Throttling" + HTTP 400 → throttling API, cần gom lô "thousands of instances" → đệm bằng SQS standard "SQS FIFO" khi cần thông lượng cao → SAI, giới hạn 300/giây "batch window 5 phút" cho API có trần số thay đổi → có thể vượt trần request "retry" như giải pháp duy nhất → không giảm tổng số lời gọi
| Giới hạn Route 53 cần nhớ | Con số |
|---|---|
| Lời gọi API | 5 request/giây mỗi tài khoản |
Thay đổi mỗi ChangeResourceRecordSets |
1.000 thay đổi hoặc 32.000 ký tự |
| Bản ghi mỗi hosted zone | 10.000 (nâng được) |
| SQS standard so với FIFO | Chọn |
|---|---|
| Standard | thông lượng gần như không giới hạn, có thể lặp và đảo thứ tự |
| FIFO | giữ thứ tự, đúng một lần, 300/3.000 thao tác mỗi giây |
| Thiết lập Lambda đọc SQS | Giá trị |
|---|---|
| Batch size | tới 10.000 (standard), 10 là mặc định hợp lý khi mỗi lô thành một lời gọi API |
| Visibility timeout | ≥ 6 lần timeout của hàm |
ReportBatchItemFailures |
báo lỗi từng tin nhắn thay vì thử lại cả lô |
| DLQ | bắt buộc |
| Giải pháp thay thế cho DNS theo instance | Cách |
|---|---|
| Route 53 Auto Naming (Cloud Map) | dịch vụ chuyên cho đăng ký/huỷ đăng ký tự động |
| Dùng tên do AWS cấp | bỏ hẳn nhu cầu tạo bản ghi |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Còn bị throttle không | đếm lỗi Throttling trong log Lambda | | Có tồn đọng không | ApproximateAgeOfOldestMessage của SQS | | Có bản ghi nào bị bỏ sót không | so số instance đang chạy với số bản ghi trong hosted zone |
Và một lời khuyên: hãy đối chiếu định kỳ số instance đang chạy với số bản ghi trong hosted zone. Đây là chỗ bản ghi DNS mồ côi tích tụ mà không ai phát hiện: nếu một tin nhắn xoá bản ghi bị lỗi và rơi vào DLQ, instance đã biến mất từ lâu nhưng bản ghi trỏ tới IP của nó vẫn còn — và IP đó rồi sẽ được cấp lại cho một máy khác, có thể của một khối lượng công việc hoàn toàn khác. Không có lỗi nào xuất hiện ở phía DNS, truy vấn vẫn trả về một địa chỉ hợp lệ, kết nối vẫn thiết lập được. Thứ duy nhất sai là nó dẫn tới nhầm máy, và triệu chứng sẽ xuất hiện ở một hệ thống khác hẳn, nhiều tuần sau đó.