Ngân hàng đề — AWS Certified Solutions Architect Professional
Tìm thấy 1221 câu.
A retail company runs its customer support call system on its in-house data center. The Solutions Architect was tasked to migrate the call system to AWS and leverage the use of managed services to reduce management overhead. The solution must be able to handle the current tasks such as receiving calls and creating contact flows. It must be able to scale to handle more calls as the customer base grows. The company also wants to add deep learning capabilities to the call system to reduce the need to speak to an agent. It must be able to recognize the intent of the caller based on certain keywords and handle basic tasks, as well as provide information to the call center agents.
Which combination of actions should the Solutions Architect implement to meet the company's requirements? (Select TWO.)
-
A
Send incoming customer calls to an Amazon Kinesis stream and process their voice through Amazon Comprehend to determine the customer’s intent.
-
B
Build a conversational interface on Amazon Alexa for Business to have AI-based answers to customer queries, thereby reducing the need to speak to an agent.
-
C
Use an Amazon Lex bot to recognize callers' intent.
-
D
Use the Amazon Connect service to create an omnichannel cloud-based contact center for the agents.
-
E
Leverage Amazon Rekognition to identify the caller and process the voice through Amazon Polly to determine the intent based on the customer’s voice.
Xem giải thích
Đáp án
**C và D — Dùng Amazon Connect để dựng tổng đài đám mây đa kênh cho tổng đài viên, và dùng một bot Amazon Lex để nhận biết ý định của người gọi.
Vì sao đúng
Đề liệt kê hai nhóm yêu cầu, và hai dịch vụ khớp chính xác: | Yêu cầu | Dịch vụ | |---|---| | Nhận cuộc gọi, tạo contact flow, co giãn | Amazon Connect | | Nhận biết ý định từ lời nói, xử lý việc cơ bản | Amazon Lex |
⚠ Từ khoá "contact flow" là tên riêng của Amazon Connect:
Contact flow: sơ đồ kịch bản cuộc
gọi trong Connect
↓
"Bấm 1 để..., bấm 2 để..."
→ chuyển hàng đợi, phát nhạc chờ,
định tuyến tới tổng đài viên
↓
Đây là thuật ngữ đặc thù,
thấy là biết ngay
⚠ Và Lex là dịch vụ nhận biết ý định — không phải Comprehend: | Dịch vụ | Việc | |---|---| | Lex | giao diện hội thoại, nhận ý định (intent) và slot | | Comprehend | phân tích VĂN BẢN: thực thể, cảm xúc, chủ đề | | Transcribe | giọng nói → văn bản | | Polly | văn bản → giọng nói | | Rekognition | phân tích ẢNH và VIDEO |
⚠ Đây là lý do phương án E sai hoàn toàn:
E nói: Rekognition nhận diện người
gọi, Polly xác định ý định
↓
Rekognition xử lý ẢNH, không
xử lý âm thanh
→ Polly SINH giọng nói, không
hiểu giọng nói
↓
Cả hai đều dùng ngược chiều
⚠ Và phương án A sai ở chỗ Comprehend không nghe được:
Comprehend nhận VĂN BẢN đầu vào
↓
Muốn dùng phải qua Transcribe
trước
↓
Và ngay cả vậy, Comprehend phân
tích cảm xúc/thực thể chứ
không dựng hội thoại
Tích hợp Lex vào contact flow:
{"Type": "GetCustomerInput",
"Parameters": {
"BotName": "TongDaiHoTro",
"BotAlias": "SanXuat",
"Text": "Xin chào, tôi có thể giúp gì cho anh chị?"},
"Transitions": {"Conditions": [
{"NextAction": "TraCuuDonHang",
"Condition": {"Operator": "Equals", "Operands": ["TraCuuDonHang"]}},
{"NextAction": "ChuyenTongDaiVien",
"Condition": {"Operator": "Equals", "Operands": ["GapNguoi"]}}]}}
⚠ Lex tự làm cả nhận dạng giọng nói lẫn hiểu ngôn ngữ:
Người gọi nói
↓
Lex: ASR (nghe) + NLU (hiểu)
→ trả về intent và slot
↓
Không cần ghép Transcribe
thủ công
Định nghĩa intent:
{"intentName": "TraCuuDonHang",
"sampleUtterances": [
"Tôi muốn kiểm tra đơn hàng",
"Đơn hàng của tôi tới đâu rồi",
"Kiểm tra tình trạng giao hàng"],
"slots": [{"name": "MaDonHang",
"slotType": "AMAZON.AlphaNumeric",
"slotConstraint": "Required",
"valueElicitationPrompt": {"messages":
[{"content": "Cho tôi xin mã đơn hàng"}]}}],
"fulfillmentActivity": {"type": "CodeHook"}}
⚠ Slot là chỗ Lex thu thập thông tin còn thiếu:
Người gọi: "kiểm tra đơn hàng"
→ Lex biết intent, nhưng thiếu
mã đơn
↓
Lex tự hỏi lại "cho tôi xin
mã đơn hàng"
→ cho tới khi đủ slot
↓
Rồi mới gọi Lambda xử lý
⚠ Và Alexa for Business (phương án B) là sản phẩm khác hẳn:
Alexa for Business: quản lý thiết
bị Alexa trong phòng họp
↓
Đặt phòng, bắt đầu cuộc gọi
hội nghị
↓
Không phải nền tảng tổng đài
→ và AWS đã ngừng dịch vụ này
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không có tổng đài vật lý nào phải vận hành | | | Trả tiền theo phút gọi, tự co giãn | | | Bot xử lý việc đơn giản, giảm tải tổng đài viên | |
⚠ Và Connect còn có nhiều tính năng AI khác: | Tính năng | Việc | |---|---| | Contact Lens | phân tích cuộc gọi, cảm xúc, tuân thủ kịch bản | | Amazon Q in Connect | gợi ý câu trả lời cho tổng đài viên theo thời gian thực | | Voice ID | xác thực người gọi bằng giọng nói | | Customer Profiles | gộp thông tin khách từ nhiều nguồn |
⚠ Và "cung cấp thông tin cho tổng đài viên" trong đề chính là Amazon Q in Connect:
Đề nói bot phải "cung cấp thông tin
cho tổng đài viên"
↓
Amazon Q in Connect nghe cuộc gọi
và gợi ý câu trả lời từ kho
tri thức
↓
Tiền thân là Amazon Connect Wisdom
Vì sao các phương án khác sai
- **A. Đưa cuộc gọi vào Kinesis rồi xử lý giọng nói qua Comprehend để xác định ý định — đây là phương án gần nhất và Kinesis Video Streams thật sự nhận được luồng âm thanh từ Connect, nhưng Comprehend chỉ phân tích văn bản và không dựng được hội thoại nhiều lượt.
- **B. Dựng giao diện hội thoại trên Alexa for Business — đó là dịch vụ quản lý thiết bị Alexa trong doanh nghiệp, không phải nền tảng tổng đài; và đã ngừng cung cấp.
- **E. Dùng Rekognition nhận diện người gọi và Polly xác định ý định — Rekognition xử lý ảnh/video, Polly sinh giọng nói chứ không hiểu giọng nói.
Ghi nhớ
⚠ Bảy dịch vụ AI của AWS — bảng phải thuộc: | Dịch vụ | Đầu vào → đầu ra | |---|---| | Lex | lời nói/văn bản → intent + slot | | Polly | văn bản → giọng nói | | Transcribe | giọng nói → văn bản | | Comprehend | văn bản → thực thể, cảm xúc, chủ đề | | Translate | văn bản → văn bản ngôn ngữ khác | | Rekognition | ảnh/video → nhãn, khuôn mặt, chữ | | Textract | tài liệu → văn bản có cấu trúc |
Từ khoá nhận diện:
"contact flow, call center" → Amazon Connect "recognize intent of the caller" → Lex "convert speech to text" → Transcribe "read text aloud" → Polly "sentiment of customer emails" → Comprehend "extract data from scanned forms" → Textract
Ba lưu ý về Amazon Connect: | Lưu ý | Chi tiết | |---|---| | Trả tiền theo phút, không có phí cố định | | | Đa kênh: thoại, chat, task, email | | | Contact flow dựng bằng giao diện kéo thả | |
⚠ Mô hình giá là điểm mạnh lớn:
Tổng đài truyền thống: mua giấy
phép theo số ghế
↓
Trả tiền dù tổng đài viên
rảnh rỗi
↓
Connect: trả theo phút gọi thật
→ mùa cao điểm tự co giãn
Ba lưu ý về Lex: | Lưu ý | Chi tiết | |---|---| | V2 hỗ trợ nhiều ngôn ngữ trong một bot | | | Lambda code hook để xử lý nghiệp vụ | | | Cần huấn luyện lại khi thêm utterance | |
Ba lưu ý về thiết kế bot: | Lưu ý | Chi tiết | |---|---| | Luôn có lối thoát sang người thật | | | Xác nhận lại trước khi làm việc quan trọng | | | Fallback intent cho câu không hiểu | |
⚠ Lối thoát sang người là bắt buộc:
Bot không hiểu ba lần liên tiếp
→ chuyển tổng đài viên
↓
Không có lối thoát: khách hàng
bị kẹt trong vòng lặp
→ trải nghiệm tệ hơn hẳn tổng
đài cũ
Ba lưu ý về ghi âm và tuân thủ: | Lưu ý | Chi tiết | |---|---| | Ghi âm lưu vào S3, mã hoá được | | | Contact Lens che thông tin nhạy cảm | | | Phải thông báo cho người gọi về việc ghi âm | |
Ba lưu ý về tích hợp: | Tích hợp | Việc | |---|---| | Lambda | truy vấn CSDL nghiệp vụ trong contact flow | | Kinesis Video Streams | luồng âm thanh thời gian thực | | Kinesis Data Streams | sự kiện contact trace record |
Ba lưu ý về đo lường: | Chỉ số | Ý nghĩa | |---|---| | Tỷ lệ chặn (containment rate) | bao nhiêu cuộc bot xử lý trọn | | Thời gian chờ trung bình | chất lượng phục vụ | | Tỷ lệ bỏ cuộc | khách gác máy trước khi được phục vụ |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gọi thử với nhiều cách diễn đạt khác nhau | | | Thử nói câu bot không hiểu — xem fallback | | | Đo tỷ lệ chuyển sang người thật | |
Và một lời khuyên: hãy thu thập cách nói thật của khách hàng trước khi huấn luyện bot. Danh sách utterance do đội dự án tự nghĩ ra bao giờ cũng lịch sự và đầy đủ hơn cách người ta nói qua điện thoại — và bot huấn luyện trên đó sẽ không hiểu phần lớn cuộc gọi thật.
A cryptocurrency exchange company has recently signed up for a 3rd party online auditing system, which is also using AWS, to perform regulatory compliance audits on their cloud systems. The online auditing system needs to access certain AWS resources in your network to perform the audit.
In this scenario, which of the following approach is the most secure way of providing access to the 3rd party online auditing system?
- A Create a new IAM role for cross-account access which allows the online auditing system account to assume the role. Assign a policy that allows full and unrestricted access to all AWS resources.
- B Create a new IAM role for cross-account access which allows the online auditing system account to assume the role. Assign it a policy that allows only the actions required for the compliance audit.
- C Create a new IAM user and assign a user policy to the IAM user that allows full and unrestricted access to all AWS resources. Create a new access and secret key for the IAM user and provide these credentials to the 3rd party auditing company.
- D Create a new IAM user and assign a user policy to the IAM user that allows only the actions required by the online audit system. Create a new access and secret key for the IAM user and provide these credentials to the 3rd party auditing company.
Xem giải thích
Đáp án
**B — Tạo một IAM role cho truy cập liên tài khoản, cho phép tài khoản của hệ thống kiểm toán giả nhận vai trò đó, và gắn chính sách chỉ cho phép đúng những hành động cần cho việc kiểm toán.
Vì sao đúng
Đề hỏi cách an toàn nhất, và có hai trục quyết định: | Trục | Lựa chọn đúng | |---|---| | Cơ chế truy cập | role (credential tạm), không phải IAM user (khoá tĩnh) | | Phạm vi quyền | tối thiểu, không phải toàn quyền |
⚠ Bốn phương án chính là bốn tổ hợp của hai trục đó: | Phương án | Cơ chế | Phạm vi | |---|---|---| | A | role ✅ | toàn quyền ❌ | | B | role ✅ | tối thiểu ✅ | | C | IAM user ❌ | toàn quyền ❌ | | D | IAM user ❌ | tối thiểu ✅ |
⚠ Vì sao role thắng IAM user — đây là điểm cốt lõi:
IAM user: access key + secret key
→ tồn tại tới khi bị xoá
↓
Gửi cho bên thứ ba
→ không kiểm soát được họ lưu
ở đâu, gửi cho ai
↓
Rò rỉ → kẻ tấn công dùng được
vô thời hạn
Role: credential TẠM, tối đa 12 giờ
→ tự hết hạn
↓
Thu hồi = sửa trust policy
→ có hiệu lực NGAY, không phải
chờ ai xoá khoá
Trust policy với External ID:
{"Version": "2012-10-17", "Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::999988887777:root"},
"Action": "sts:AssumeRole",
"Condition": {"StringEquals": {
"sts:ExternalId": "chuoi-bi-mat-duy-nhat-cho-khach-hang-nay"}}}]}
⚠ External ID là bắt buộc khi bên thứ ba là nhà cung cấp dịch vụ:
Nhà kiểm toán phục vụ nhiều
khách hàng
↓
Không có External ID: kẻ xấu
là khách hàng khác của họ
có thể lừa nhà kiểm toán
giả nhận vai trò của BẠN
↓
Đây là "confused deputy problem"
Nhà kiểm toán có vai trò truy cập
vào tài khoản A và B
↓
Kẻ xấu ở B khai ARN vai trò
của A vào cấu hình
↓
Nhà kiểm toán giả nhận vai trò A
thay mặt kẻ xấu
→ External ID chặn đúng chuyện
này
Chính sách quyền tối thiểu cho kiểm toán:
{"Version": "2012-10-17", "Statement": [{
"Effect": "Allow",
"Action": ["config:Describe*", "config:Get*",
"cloudtrail:LookupEvents",
"iam:GenerateCredentialReport",
"iam:Get*", "iam:List*",
"s3:GetBucketPolicy", "s3:GetBucketAcl"],
"Resource": "*"}]}
⚠ Và AWS có sẵn chính sách quản lý cho việc này:
aws iam attach-role-policy --role-name KiemToanBenNgoai \
--policy-arn arn:aws:iam::aws:policy/SecurityAudit
| Chính sách | Phạm vi |
|---|---|
SecurityAudit |
đọc cấu hình bảo mật |
ViewOnlyAccess |
xem siêu dữ liệu, không xem nội dung |
ReadOnlyAccess |
đọc cả NỘI DUNG (kể cả object S3) |
⚠ ReadOnlyAccess rộng hơn nhiều người tưởng:
"ReadOnly" nghe như vô hại
→ nhưng nó cho `s3:GetObject`
↓
Đọc được mọi tệp trong mọi bucket
→ với sàn giao dịch tiền mã hoá
là rủi ro rất lớn
↓
`SecurityAudit` mới là chính sách
đúng cho kiểm toán
Giới hạn thêm bằng điều kiện:
"Condition": {
"IpAddress": {"aws:SourceIp": ["203.0.113.0/24"]},
"DateLessThan": {"aws:CurrentTime": "2026-12-31T23:59:59Z"}}
Giới hạn IP nguồn và thời hạn
→ hợp đồng kiểm toán có kỳ hạn
→ vai trò cũng nên có
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không có khoá dài hạn nào rời khỏi tài khoản | | | Thu hồi tức thì bằng cách sửa trust policy | | | CloudTrail ghi lại từng phiên giả nhận | |
⚠ Và điểm cuối rất quan trọng cho kiểm toán:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole
Mỗi lần giả nhận đều ghi lại:
ai, khi nào, từ IP nào
↓
`RoleSessionName` truy về đúng
người ở phía nhà kiểm toán
Vì sao các phương án khác sai
- **D. Tạo IAM user với chính sách chỉ cho phép hành động cần thiết, cấp access key cho nhà kiểm toán — đây là phương án gần nhất và phạm vi quyền hoàn toàn đúng, nhưng access key là khoá dài hạn nằm ngoài tầm kiểm soát của bạn, không tự hết hạn và không thu hồi được ngay.
- **A. Tạo role liên tài khoản nhưng gắn chính sách toàn quyền — vi phạm nguyên tắc quyền tối thiểu; nhà kiểm toán không cần quyền xoá hay sửa gì.
- **C. Tạo IAM user toàn quyền và cấp khoá — kết hợp cả hai điều tệ nhất.
Ghi nhớ
⚠ Bốn cách cấp quyền cho bên thứ ba — bảng phải thuộc: | Cách | An toàn | |---|---| | IAM role + External ID | tốt nhất | | IAM role không External ID | rủi ro confused deputy | | IAM user với khoá xoay vòng | kém | | IAM user khoá cố định | tệ nhất |
Từ khoá nhận diện:
"third-party access, most secure" → cross-account role "third party serves multiple customers" → External ID "never share access keys" → luôn đúng "read-only security audit" → chính sách
SecurityAudit
Ba lưu ý về trust policy: | Lưu ý | Chi tiết | |---|---| | Principal là tài khoản hoặc role bên kia | | | Điều kiện sts:ExternalId cho nhà cung cấp | | | MaxSessionDuration giới hạn thời hạn phiên | |
⚠ Đừng để External ID là thứ đoán được:
Dùng tên công ty hoặc số hợp đồng
→ đoán được
↓
Sinh ngẫu nhiên, duy nhất cho
từng khách hàng
→ và do BÊN CUNG CẤP DỊCH VỤ
sinh ra, không phải khách
Ba lưu ý về giám sát truy cập bên ngoài: | Công cụ | Việc | |---|---| | IAM Access Analyzer | tìm tài nguyên chia sẻ ra ngoài tổ chức | | CloudTrail | ghi mọi lời gọi AssumeRole | | Access Advisor | xem dịch vụ nào thật sự được dùng |
⚠ Access Advisor giúp thu hẹp quyền sau khi cấp:
aws iam generate-service-last-accessed-details \
--arn arn:aws:iam::111122223333:role/KiemToanBenNgoai
Cấp rộng lúc đầu vì không biết
họ cần gì
↓
Sau một tháng, xem họ thật sự
gọi dịch vụ nào
→ cắt phần không dùng
Ba lưu ý về quyền tối thiểu: | Lưu ý | Chi tiết | |---|---| | Bắt đầu từ không có gì, thêm dần | | | Dùng chính sách quản lý sẵn khi hợp | | | Rà lại định kỳ, cắt quyền không dùng | |
Ba lưu ý về permissions boundary: | Lưu ý | Chi tiết | |---|---| | Đặt trần tuyệt đối cho vai trò | | | Ngăn việc leo thang quyền | | | Hữu ích khi vai trò do bên khác cấu hình | |
Ba lưu ý về ghi log phiên: | Lưu ý | Chi tiết | |---|---| | RoleSessionName nên chứa danh tính người dùng | | | Đặt bắt buộc bằng điều kiện trong trust policy | | | Giúp truy vết khi có sự cố | |
Ba lưu ý về kết thúc hợp đồng: | Việc | Cách | |---|---| | Xoá role là chấm dứt truy cập ngay | | | Kiểm CloudTrail xem còn lời gọi nào không | | | Với IAM user thì phải xoá cả khoá | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Thử giả nhận không có External ID — phải bị từ chối | | | Thử một hành động ghi — phải bị từ chối | | | Xem CloudTrail có ghi lại phiên không | |
Và một lời khuyên: hãy dùng chính sách SecurityAudit chứ đừng dùng ReadOnlyAccess cho kiểm toán viên. Cái tên "chỉ đọc" nghe vô hại nhưng nó cho phép đọc nội dung mọi object trong mọi bucket — với một sàn giao dịch tiền mã hoá, đó là toàn bộ dữ liệu khách hàng.
A company runs hundreds of Amazon EC2 instances inside an Amazon VPC. Whenever an EC2 error is encountered, the solutions architect performs manual steps in order to regain access to the impaired instance. The management wants to automatically recover impaired EC2 instances in the VPC. The goal is to automatically fix an instance that has become unreachable due to network misconfigurations, RDP issues, firewall settings, and many others to meet the compliance requirements.
Which of the following options is the most suitable solution that the solutions architect should implement to meet the above requirements?
-
A
Use the EC2Rescue tool to diagnose and troubleshoot problems on your Amazon EC2 Linux and Windows Server instances. Run the tool automatically by using AWS Lambda and a custom script.
-
B
To meet the compliance requirements, use a combination of AWS Config and the AWS Systems Manager State Manager to self-diagnose and troubleshoot problems on your Amazon EC2 Linux and Windows Server instances. Automate the recovery process by using AWS Systems Manager Maintenance Windows.
-
C
To meet the compliance requirements, use a combination of AWS Config and the AWS Systems Manager Session Manager to self-diagnose and troubleshoot problems on your EC2 Linux and Windows Server instances. Automate the recovery process by setting up a monitoring system using Amazon CloudWatch, AWS Lambda, and the AWS Systems Manager Run Command that will automatically monitor and recover impaired EC2 instances.
-
D
Use the EC2Rescue tool to diagnose and troubleshoot problems on your EC2 Linux and Windows Server instances. Run the tool automatically by using the AWS Systems Manager Automation and the
AWSSupport-ExecuteEC2Rescuedocument.
Xem giải thích
Đáp án
**D — Dùng công cụ EC2Rescue để chẩn đoán và khắc phục sự cố trên instance Linux và Windows Server, chạy tự động bằng AWS Systems Manager Automation với tài liệu AWSSupport-ExecuteEC2Rescue.
Vì sao đúng
Đề mô tả đúng nhóm sự cố mà EC2Rescue sinh ra để xử lý:
Instance KHÔNG truy cập được vì
cấu hình mạng sai, RDP hỏng,
tường lửa chặn
↓
Máy vẫn chạy, nhưng bạn không
vào được
↓
Không vào được thì không sửa
được bằng cách thông thường
⚠ Đây là điểm mấu chốt: mọi công cụ cần agent đều vô dụng ở đây: | Công cụ | Cần gì | Còn dùng được không | |---|---|---| | SSM Run Command | SSM Agent kết nối được | KHÔNG — mạng đã hỏng | | Session Manager | SSM Agent kết nối được | KHÔNG | | SSH/RDP | mạng và dịch vụ hoạt động | KHÔNG | | AWSSupport-ExecuteEC2Rescue | chỉ cần quyền API | CÓ |
⚠ Vì sao nó vẫn chạy được — cơ chế rất đáng biết:
1. Dừng instance hỏng
↓
2. Tháo volume gốc ra
↓
3. Tạo một instance CỨU HỘ mới
↓
4. Gắn volume hỏng vào instance đó
như đĩa phụ
↓
5. Chạy EC2Rescue TRÊN instance
cứu hộ để sửa hệ thống tệp
↓
6. Gắn volume trả lại, khởi động
instance gốc
Toàn bộ việc sửa diễn ra từ BÊN
NGOÀI máy hỏng
↓
Không phụ thuộc vào mạng hay
dịch vụ nào bên trong nó
Chạy tự động:
aws ssm start-automation-execution \
--document-name AWSSupport-ExecuteEC2Rescue \
--parameters '{
"UnreachableInstanceId": ["i-0abc123"],
"AllowEncryptedVolume": ["True"],
"SubnetId": ["subnet-cuu-ho"]}'
⚠ Và tài liệu này sửa được đúng những thứ đề liệt kê: | Sự cố | EC2Rescue làm gì | |---|---| | Tường lửa Windows chặn hết | tắt tường lửa tạm thời | | RDP không bật | bật lại dịch vụ RDP | | Cấu hình mạng sai | khôi phục cấu hình mặc định | | Boot hỏng (Linux) | sửa /etc/fstab, grub | | Driver lỗi | gỡ driver gây sự cố |
⚠ Và tự động hoá bằng EventBridge khi phát hiện instance hỏng:
{"source": ["aws.health"],
"detail-type": ["AWS Health Event"],
"detail": {"service": ["EC2"],
"eventTypeCode": ["AWS_EC2_INSTANCE_STATUS_CHECK_FAILED"]}}
⚠ Hoặc dùng CloudWatch alarm trên StatusCheckFailed_Instance:
aws cloudwatch put-metric-alarm \
--alarm-name may-hong-i-0abc123 \
--metric-name StatusCheckFailed_Instance \
--namespace AWS/EC2 --statistic Maximum \
--dimensions Name=InstanceId,Value=i-0abc123 \
--period 60 --evaluation-periods 3 --threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--alarm-actions arn:aws:automate:ap-southeast-1:ec2:recover
⚠ Hai loại status check khác nhau — phải phân biệt: | Kiểm tra | Hỏng nghĩa là | Sửa bằng | |---|---|---| | StatusCheckFailed_System | hạ tầng AWS hỏng | ec2:recover — chuyển sang máy chủ vật lý khác | | StatusCheckFailed_Instance | hệ điều hành trong máy có vấn đề | EC2Rescue |
Đề nói lỗi do cấu hình mạng, RDP,
tường lửa
↓
Đó là lỗi BÊN TRONG hệ điều hành
→ Instance status check
→ `ec2:recover` không giúp được
⚠ Và vì sao phương án A không đủ:
A nói dùng EC2Rescue chạy bằng
Lambda và script tự viết
↓
Phải tự viết toàn bộ luồng:
dừng máy, tháo đĩa, dựng máy
cứu hộ, gắn, chạy, gắn lại
↓
AWS đã đóng gói sẵn luồng đó
→ viết lại là thừa và dễ sai
⚠ Và vì sao B, C sai:
B: State Manager + Maintenance Windows
→ State Manager giữ cấu hình
ĐÚNG CHUẨN theo lịch
→ nhưng cần SSM Agent chạy được
↓
C: Session Manager + Run Command
→ cả hai đều cần agent kết nối
tới SSM endpoint
→ mạng hỏng thì không kết nối
được
⚠ Đây là nghịch lý của mọi công cụ dựa trên agent:
Agent cần mạng để nhận lệnh
↓
Sự cố là MẠNG HỎNG
↓
Chính lúc cần công cụ nhất
là lúc nó không dùng được
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không phụ thuộc trạng thái bên trong máy hỏng | | | Luồng cứu hộ do AWS viết và bảo trì | | | Ghi lại toàn bộ các bước, phục vụ tuân thủ | |
⚠ Và điểm cuối là lý do đề nhắc "yêu cầu tuân thủ":
Automation ghi lại từng bước,
ai chạy, kết quả gì
↓
Sửa tay qua console: không có
dấu vết nào
→ kiểm toán viên không xác nhận
được quy trình
Vì sao các phương án khác sai
- **A. Dùng EC2Rescue chạy tự động bằng Lambda và script tự viết — đây là phương án gần nhất và chọn đúng công cụ, nhưng phải tự dựng lại toàn bộ luồng cứu hộ mà AWS đã đóng gói sẵn trong
AWSSupport-ExecuteEC2Rescue. - **C. Dùng Config + Session Manager và tự động hoá bằng CloudWatch, Lambda, Run Command — cả Session Manager lẫn Run Command đều cần SSM Agent kết nối được, mà đó chính là thứ đã hỏng.
- **B. Dùng Config + State Manager, tự động hoá bằng Maintenance Windows — cũng cần agent hoạt động; và Maintenance Windows là để bảo trì theo lịch, không phải ứng cứu sự cố.
Ghi nhớ
⚠ Bốn công cụ Systems Manager — bảng phải thuộc: | Công cụ | Việc | Cần agent | |---|---|---| | Run Command | chạy lệnh trên nhiều máy | CÓ | | Session Manager | shell không cần SSH | CÓ | | State Manager | giữ cấu hình đúng chuẩn | CÓ | | Automation | luồng thao tác trên tài nguyên AWS | KHÔNG (tuỳ tài liệu) |
⚠ Automation khác ba cái kia ở chỗ nó thao tác qua API AWS:
Run Command: chạy lệnh BÊN TRONG
hệ điều hành
↓
Automation: gọi API AWS — dừng
máy, tạo snapshot, gắn volume
→ không cần vào trong máy
Từ khoá nhận diện:
"unreachable instance" → EC2Rescue qua SSM Automation "system status check failed" →
ec2:recover"run command on many instances" → Run Command "shell access without SSH keys" → Session Manager "keep configuration compliant" → State Manager
Ba lưu ý về EC2Rescue: | Lưu ý | Chi tiết | |---|---| | Có bản cho Linux và Windows | | | Chạy trực tuyến (trong máy) hoặc ngoại tuyến (qua Automation) | | | Thu thập log chẩn đoán để gửi AWS Support | |
⚠ Thu thập log để gửi Support:
aws ssm start-automation-execution \
--document-name AWSSupport-CollectEC2InstanceLogs \
--parameters '{"InstanceId": ["i-0abc123"]}'
Ba lưu ý về Automation: | Lưu ý | Chi tiết | |---|---| | Tài liệu AWSSupport-* do AWS viết sẵn | | | Có bước phê duyệt thủ công nếu cần | | | Chạy được theo lịch, theo sự kiện, hoặc thủ công | |
⚠ Bước phê duyệt hữu ích cho thao tác nguy hiểm:
{"name": "ChoDuyet", "action": "aws:approve",
"inputs": {"Approvers": ["arn:aws:iam::...:role/TruongNhom"],
"MinRequiredApprovals": 1}}
Dừng instance sản xuất là việc
gây gián đoạn
↓
Chèn bước duyệt trước khi làm
Ba lưu ý về phục hồi tự động: | Cơ chế | Xử lý | |---|---| | ec2:recover | hạ tầng hỏng — chuyển máy chủ vật lý | | ASG health check | thay thế máy hỏng bằng máy mới | | EC2Rescue | sửa hệ điều hành trong máy |
⚠ Với máy không giữ trạng thái, thay mới đơn giản hơn sửa:
Instance trong ASG hỏng
→ cứ chấm dứt, ASG tạo máy mới
↓
Nhanh hơn và sạch hơn việc sửa
↓
EC2Rescue dành cho máy CÓ trạng
thái, không thay được
Ba lưu ý về phòng ngừa: | Lưu ý | Chi tiết | |---|---| | Bật SSM Agent và VPC endpoint cho SSM | | | Đừng dựa vào SSH — dùng Session Manager | | | Thử thay đổi tường lửa qua Automation, không sửa tay | |
⚠ VPC endpoint cho SSM giữ agent sống khi không có Internet:
Agent cần tới ssm, ssmmessages,
ec2messages
↓
Ba interface endpoint trong VPC
→ agent kết nối được cả trong
subnet riêng không có NAT
Ba lưu ý về ghi chép: | Lưu ý | Chi tiết | |---|---| | Automation ghi lại từng bước | | | CloudTrail ghi lời gọi API | | | Xuất kết quả sang S3 cho kiểm toán | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Cố ý chặn hết tường lửa một máy thử, chạy Automation | | | Đo thời gian từ lúc hỏng tới lúc phục hồi | | | Kiểm log Automation có đủ chi tiết cho kiểm toán | |
Và một lời khuyên: hãy thử quy trình cứu hộ trên một máy thử trước khi cần dùng thật. Luồng AWSSupport-ExecuteEC2Rescue cần một subnet và quyền IAM phù hợp để dựng instance cứu hộ — và phát hiện thiếu chúng lúc máy sản xuất đang chết là kịch bản tệ nhất.
A pharmaceutical company has a hybrid cloud architecture in AWS. It has three different accounts for its environments: DEV, UAT, and PROD, which are all part of the consolidated billing account. The PROD account has purchased 10 Reserved EC2 Instances in the us-west-2a Availability Zone.
Currently, there are no running EC2 instances in the PROD account because the application is not live yet. However, in the DEV account, there are 5 EC2 instances running in the us-west-2a Availability Zone. In the UAT account, there are also 5 EC2 instances running in the us-west-1a Availability Zone. All the EC2 instances in the DEV and UAT accounts match the reserved instance type in the PROD account.
In this scenario, which account benefits the most from the Reserved Instance pricing?
- A Currently, only the UAT account benefits from the Reserved Pricing.
-
B
Since both DEV and UAT accounts are running an EC2 instance type that exactly matches the Reserved Instance type, then the Reserved instance pricing will be applied to all EC2 instances in those two member accounts.
- C Currently, only the DEV account benefits from the Reserved Pricing.
- D None. Considering that the PROD account is the one that purchased the Reserved Instance and it does not have any running EC2 instance, there is currently no other member account that benefits from the Reserved Instance pricing.
Xem giải thích
Đáp án
C — Hiện tại chỉ tài khoản DEV được hưởng giá Reserved Instance.
Vì sao đúng
Reserved Instance mua theo AZ cụ thể được chia sẻ trong gia đình thanh toán hợp nhất, nhưng phải khớp đúng Availability Zone: | Tài khoản | Instance | AZ | Khớp RI? | |---|---|---|---| | PROD | 0 máy | — | không có gì để áp | | DEV | 5 máy | us-west-2a | KHỚP | | UAT | 5 máy | us-west-1a | KHÁC REGION |
⚠ Điểm mấu chốt nằm ở tên AZ, đọc rất dễ lướt qua:
us-west-2a ← RI mua ở đây (Oregon)
us-west-1a ← UAT chạy ở đây (Bắc California)
↓
Đây là HAI REGION KHÁC NHAU
→ không phải hai AZ trong
cùng Region
us-west-1 = N. California
us-west-2 = Oregon
↓
Chữ số ở giữa là REGION
→ chữ cái cuối mới là AZ
⚠ RI không bao giờ áp qua Region:
RI mua ở Region nào chỉ dùng
ở Region đó
↓
Kể cả Regional RI (không gắn AZ)
cũng chỉ trong một Region
↓
Muốn đổi Region: phải sửa RI
hoặc bán trên Marketplace
⚠ Và vì sao PROD không hưởng gì dù chính nó mua:
PROD mua 10 RI
→ nhưng không chạy máy nào
↓
RI là cam kết TRẢ TIỀN, không
phải một máy
→ không dùng thì tiền vẫn mất
↓
Giảm giá chảy sang tài khoản
khác trong gia đình
⚠ Và đây chính là mục đích của thanh toán hợp nhất:
aws organizations describe-organization
RI và Savings Plans được chia sẻ
toàn tổ chức theo mặc định
↓
Máy chạy ở bất kỳ tài khoản nào
khớp điều kiện đều được áp
↓
Tránh việc mỗi tài khoản phải
mua riêng
Tắt chia sẻ nếu không muốn:
aws ec2 modify-instance-capacity-reservation-attributes ...
# hoặc trong Billing preferences: bỏ tick RI/Savings Plans discount sharing
Tắt chia sẻ ở một tài khoản
→ RI của nó chỉ dùng cho chính nó
↓
Hữu ích khi các đơn vị kinh doanh
tính chi phí riêng
⚠ Và có một chi tiết quan trọng về AZ ID:
"us-west-2a" của tài khoản A
→ có thể là AZ vật lý KHÁC
với "us-west-2a" của tài khoản B
↓
AWS xáo tên AZ theo tài khoản
để cân bằng tải
↓
Việc khớp RI dùng AZ ID
(`usw2-az1`), không dùng tên
Xem AZ ID thật:
aws ec2 describe-availability-zones \
--query 'AvailabilityZones[].[ZoneName,ZoneId]' --output table
Tài khoản PROD: us-west-2a = usw2-az3
Tài khoản DEV: us-west-2a = usw2-az1
↓
Cùng tên, khác AZ vật lý
→ Zonal RI KHÔNG khớp
⚠ Đây là lý do nên mua Regional RI thay vì Zonal RI: | Loại | Ưu | Nhược | |---|---|---| | Zonal RI | đặt trước công suất trong AZ đó | cứng nhắc, vướng vấn đề AZ ID | | Regional RI | áp cho mọi AZ trong Region, linh hoạt kích cỡ | KHÔNG đặt trước công suất |
Regional RI có "instance size
flexibility"
↓
RI cho m5.2xlarge áp được cho
2 máy m5.xlarge
→ hoặc 4 máy m5.large
↓
Zonal RI không có tính năng này
⚠ Và Savings Plans linh hoạt hơn RI nữa: | Loại | Phạm vi | |---|---| | EC2 Instance Savings Plan | một họ instance, một Region | | Compute Savings Plan | MỌI họ, MỌI Region, cả Fargate và Lambda |
Compute Savings Plan: cam kết
số tiền mỗi giờ
↓
Đổi Region, đổi họ instance,
chuyển sang Fargate
→ vẫn được giảm giá
↓
Giảm ít hơn RI một chút, nhưng
linh hoạt hơn nhiều
Ba lợi ích của thanh toán hợp nhất: | Lợi ích | Chi tiết | |---|---| | RI dùng chung, không lãng phí | | | Giá bậc thang tính trên tổng lượng dùng | | | Một hoá đơn, dễ theo dõi | |
Ghi nhớ về chất lượng câu hỏi
⚠ Đề nói RI mua ở "us-west-2a" nhưng việc khớp thật sự dùng AZ ID chứ không dùng tên AZ.
Nếu áp đúng cơ chế thật, câu trả lời phụ thuộc vào việc us-west-2a của PROD và us-west-2a của DEV có cùng AZ ID hay không — và tên AZ được xáo theo từng tài khoản nên hai cái đó thường không trùng nhau.
Trong thực tế:
Muốn RI dùng chung giữa các tài
khoản trong tổ chức
↓
Mua REGIONAL RI, không mua
Zonal RI
↓
Regional RI không quan tâm AZ
→ và có linh hoạt kích cỡ
Câu hỏi kiểm tra đúng nguyên tắc "RI chia sẻ trong consolidated billing, phải khớp Region/AZ", nhưng ví dụ Zonal RI chia sẻ liên tài khoản không phải cách nên làm.
Vì sao các phương án khác sai
- **B. Cả DEV và UAT đều được hưởng vì đều chạy đúng kiểu instance — đây là phương án gần nhất và đúng về việc RI chia sẻ trong gia đình thanh toán, nhưng UAT chạy ở
us-west-1a— một Region khác hẳn, nên RI không áp được. - **A. Chỉ UAT được hưởng — ngược lại; UAT mới là tài khoản ở sai Region.
- **D. Không tài khoản nào được hưởng vì PROD không chạy máy — sai; giảm giá RI chảy sang các tài khoản khác trong gia đình thanh toán hợp nhất.
Ghi nhớ
⚠ Bốn cách tiết kiệm chi phí tính toán — bảng phải thuộc: | Cách | Giảm tối đa | Linh hoạt | |---|---|---| | Spot Instance | ~90% | có thể bị thu hồi | | Compute Savings Plan | ~66% | mọi họ, mọi Region | | EC2 Instance Savings Plan | ~72% | một họ, một Region | | Standard RI (3 năm trả trước) | ~72% | cứng nhất |
Từ khoá nhận diện:
"consolidated billing, RI sharing" → áp cho mọi tài khoản khớp điều kiện "different Region" → RI KHÔNG áp "capacity reservation needed" → Zonal RI hoặc On-Demand Capacity Reservation "flexible across instance families" → Compute Savings Plan
Ba lưu ý về RI: | Lưu ý | Chi tiết | |---|---| | Là cam kết thanh toán, không phải một máy | | | Regional RI có linh hoạt kích cỡ | | | Standard RI bán được trên Marketplace, Convertible thì không | |
⚠ Convertible RI đổi được sang loại khác: | Loại | Đổi | Bán lại | |---|---|---| | Standard | không | CÓ | | Convertible | CÓ (sang họ khác, OS khác) | không |
Ba lưu ý về Savings Plans: | Lưu ý | Chi tiết | |---|---| | Cam kết USD mỗi giờ, không cam kết số máy | | | Tự áp vào phần dùng có mức giảm cao nhất trước | | | Compute SP phủ cả Fargate và Lambda | |
Ba lưu ý về thanh toán hợp nhất: | Lưu ý | Chi tiết | |---|---| | Chia sẻ RI/SP bật mặc định | | | Tắt được cho từng tài khoản | | | Giá bậc thang tính trên tổng toàn tổ chức | |
⚠ Giá bậc thang là lợi ích dễ bị bỏ qua:
S3 giảm giá theo tổng dung lượng
↓
Ba tài khoản mỗi cái 100 TB
→ tính riêng: giá bậc 100 TB
↓
Hợp nhất: tính như 300 TB
→ bậc giá thấp hơn
Ba lưu ý về AZ ID: | Lưu ý | Chi tiết | |---|---| | Tên AZ xáo theo tài khoản | | | AZ ID (usw2-az1) là định danh thật | | | Dùng AZ ID khi so sánh giữa các tài khoản | |
Ba lưu ý về theo dõi mức dùng RI: | Công cụ | Việc | |---|---| | Cost Explorer RI Utilization | RI có được dùng hết không | | RI Coverage | bao nhiêu phần tải được RI phủ | | Cost Anomaly Detection | báo khi chi phí bất thường |
⚠ Utilization và Coverage là hai con số khác nhau:
Utilization thấp: mua thừa RI
↓
Coverage thấp: còn nhiều máy
chạy giá On-Demand
→ nên mua thêm
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Xem RI Utilization trong Cost Explorer | | | So ZoneId giữa các tài khoản | | | Kiểm hoá đơn xem giảm giá áp vào tài khoản nào | |
Và một lời khuyên: hãy mua Regional RI hoặc Savings Plans thay vì Zonal RI khi nhiều tài khoản dùng chung. Tên Availability Zone được xáo khác nhau ở mỗi tài khoản, nên một Zonal RI mua ở us-west-2a của tài khoản này có thể không bao giờ khớp với máy chạy ở us-west-2a của tài khoản kia.
An Internet-of-Things (IoT) company is building a portal that stores data coming from its 20,000 gas sensors. The gas sensors, which have unique IDs, are used to detect a gas leak or other emissions inside the oil facility. Every 15 minutes, the sensors will send a data point throughout the day containing its ID, current gas level data, as well as the timestamp. Each data point contains critical information coming from the gas sensors. The company would like to query the information coming from a particular gas sensor for the past week and would like to delete all data that are older than eight weeks. The application is using a NoSQL database which is why they are using the Amazon DynamoDB service.
How would you implement this in the most cost-effective way?
- A Use one table every week, with a primary key which is the concatenated value of the sensor ID and the timestamp.
- B Use one table every week, with a composite primary key which is the sensor ID as the partition key and the timestamp as the sort key.
- C Use one table with a primary key which is the sensor ID. Use the timestamp as the hash key.
- D Use one table with a primary key which is the concatenated value of the sensor ID and the timestamp.
Xem giải thích
Đáp án
**B — Dùng một bảng mỗi tuần, với khoá chính tổ hợp: mã cảm biến làm partition key và thời điểm làm sort key.
Vì sao đúng
Đề có hai yêu cầu về truy vấn và một về xoá, và thiết kế khoá phải phục vụ cả ba: | Yêu cầu | Phần nào của thiết kế | |---|---| | Truy vấn dữ liệu của MỘT cảm biến trong tuần qua | partition key = mã cảm biến | | Lấy theo khoảng thời gian | sort key = thời điểm | | Xoá dữ liệu quá 8 tuần, rẻ nhất | bảng theo tuần → DeleteTable |
⚠ Khoá tổ hợp là thứ cho phép truy vấn theo khoảng:
`Query` với partition key = "CB-042"
→ và sort key BETWEEN hai mốc
↓
DynamoDB đọc đúng dải cần
→ chỉ tốn RCU cho phần đọc thật
resp = table.query(
KeyConditionExpression=Key('ma_cam_bien').eq('CB-042')
& Key('thoi_diem').between('2026-08-25T00:00:00',
'2026-09-01T00:00:00'))
⚠ Và đây là lý do phương án A và D sai — nối chuỗi làm khoá:
Khoá = "CB-042#2026-08-25T10:15:00"
↓
Đó là MỘT giá trị partition key
duy nhất
↓
Muốn lấy dữ liệu một tuần
→ phải biết TRƯỚC từng timestamp
→ hoặc `Scan` toàn bảng
↓
`Scan` đọc mọi dòng → rất đắt
⚠ Khác biệt căn bản giữa nối chuỗi và khoá tổ hợp: | Thiết kế | Truy vấn theo khoảng | |---|---| | Khoá đơn nối chuỗi | KHÔNG — phải Scan | | Partition key + sort key | CÓ — Query theo dải |
⚠ Và phương án C sai ở thuật ngữ lẫn thiết kế:
C nói "primary key là mã cảm biến,
dùng timestamp làm HASH key"
↓
Hash key CHÍNH LÀ partition key
→ không thể vừa là mã cảm biến
vừa là timestamp
↓
Mô tả tự mâu thuẫn
| Tên gọi | Đồng nghĩa |
|---|---|
| Partition key | hash key |
| Sort key | range key |
Tạo bảng theo tuần:
aws dynamodb create-table \
--table-name cam-bien-2026-W35 \
--attribute-definitions \
AttributeName=ma_cam_bien,AttributeType=S \
AttributeName=thoi_diem,AttributeType=S \
--key-schema \
AttributeName=ma_cam_bien,KeyType=HASH \
AttributeName=thoi_diem,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
⚠ Và bảng theo tuần khiến việc xoá gần như miễn phí:
Xoá dữ liệu quá 8 tuần bằng
`DeleteItem`
→ mỗi mục tốn WCU
↓
20.000 cảm biến × 96 điểm/ngày
× 7 ngày = 13,4 triệu mục
→ 13,4 triệu WCU chỉ để xoá
↓
`DeleteTable`: MIỄN PHÍ
Tính khối lượng:
20.000 cảm biến
× 96 điểm mỗi ngày (15 phút một lần)
× 7 ngày
↓
= 13.440.000 mục mỗi tuần
⚠ Và phân bố phân vùng rất đều với thiết kế này:
20.000 mã cảm biến khác nhau
làm partition key
↓
DynamoDB rải đều trên nhiều
phân vùng
→ không có phân vùng nóng
↓
Ngược lại: nếu dùng NGÀY làm
partition key
→ mọi ghi trong ngày dồn vào
một phân vùng
⚠ Và truy vấn chỉ chạm đúng một bảng:
Hỏi "tuần qua" → đọc bảng tuần này
↓
Hỏi "bốn tuần qua" → đọc bốn bảng
→ ứng dụng phải gộp kết quả
↓
Đây là cái giá của mẫu bảng
theo thời gian
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Truy vấn theo cảm biến + khoảng thời gian rất hiệu quả | | | Xoá dữ liệu cũ miễn phí | | | Không có phân vùng nóng | |
Ghi nhớ về chất lượng câu hỏi
⚠ TTL là cách hiện đại hơn và đơn giản hơn nhiều so với bảng theo tuần.
aws dynamodb update-time-to-live --table-name cam-bien \
--time-to-live-specification "Enabled=true,AttributeName=het_han"
table.put_item(Item={
'ma_cam_bien': 'CB-042',
'thoi_diem': '2026-09-01T10:15:00',
'muc_khi': 12.4,
'het_han': int(time.time()) + 8*7*86400})
| Tiêu chí | Bảng theo tuần | TTL |
|---|---|---|
| Chi phí xoá | miễn phí | MIỄN PHÍ |
| Ứng dụng phức tạp | phải biết tên bảng, gộp nhiều bảng | KHÔNG đổi gì |
| Truy vấn liên tuần | phải gọi nhiều bảng | một Query |
| Xoá đúng hạn | chính xác | trong vòng vài ngày |
TTL ra mắt 2017 — sau khi mẫu
"bảng theo ngày/tuần" trở thành
thực hành phổ biến
↓
Với yêu cầu "xoá dữ liệu quá
8 tuần", TTL đơn giản hơn
hẳn và không cần sửa gì ở
tầng ứng dụng
Và với dữ liệu chuỗi thời gian từ cảm biến, Amazon Timestream là dịch vụ chuyên dụng:
Timestream: tự phân tầng nóng/lạnh
→ tự xoá theo chính sách lưu giữ
→ có hàm nội suy, cửa sổ trượt
sẵn trong SQL
Vì sao các phương án khác sai
- **D. Một bảng duy nhất với khoá chính là giá trị nối của mã cảm biến và thời điểm — đây là phương án gần nhất và bảo đảm khoá duy nhất, nhưng khoá đơn không cho phép truy vấn theo khoảng thời gian; và xoá dữ liệu cũ phải quét toàn bảng rồi xoá từng mục.
- **A. Bảng mỗi tuần nhưng khoá chính là giá trị nối — giải quyết được việc xoá, nhưng vẫn không truy vấn được theo khoảng trong tuần.
- **C. Một bảng với primary key là mã cảm biến, timestamp làm hash key — hash key chính là partition key, nên mô tả này tự mâu thuẫn.
Ghi nhớ
⚠ Hai loại khoá chính của DynamoDB — bảng phải thuộc: | Loại | Thành phần | Truy vấn được | |---|---|---| | Simple | chỉ partition key | chỉ theo khoá chính xác | | Composite | partition + sort key | theo dải sort key |
Từ khoá nhận diện:
"query by ID over a time range" → composite key, timestamp làm sort key "delete old data cheaply" → TTL hoặc bảng theo thời gian "query on non-key attribute" → GSI "time-series sensor data" → Timestream đáng cân nhắc
⚠ Query và Scan — khác biệt về chi phí rất lớn: | Thao tác | Đọc gì | Chi phí | |---|---|---| | Query | một phân vùng, theo dải | theo lượng đọc thật | | Scan | TOÀN BỘ bảng | theo cả bảng |
Scan trên bảng 13 triệu mục
→ đọc hết rồi mới lọc
↓
Trả về 10 mục nhưng tính tiền
cho 13 triệu
Ba lưu ý về chỉ mục: | Loại | Đặc điểm | |---|---| | LSI | cùng partition key, sort key khác; tạo cùng lúc với bảng | | GSI | partition key khác hẳn; thêm bất cứ lúc nào | | GSI có công suất riêng | phải cấp thông lượng riêng |
Ba lưu ý về thiết kế partition key: | Lưu ý | Chi tiết | |---|---| | Độ phân tán cao (nhiều giá trị khác nhau) | | | Truy cập đều giữa các giá trị | | | Tránh dùng ngày/giờ làm partition key | |
⚠ Dùng ngày làm partition key là lỗi kinh điển:
Mọi ghi trong ngày vào cùng
một phân vùng
↓
Phân vùng đó chạm trần
1.000 WCU
→ bị chặn dù bảng còn công
suất
Ba lưu ý về TTL: | Lưu ý | Chi tiết | |---|---| | Thuộc tính phải là số, epoch giây | | | Xoá trong vòng vài ngày sau hạn | | | Không tốn WCU | |
⚠ Mục đã hết hạn vẫn xuất hiện trong Query cho tới khi bị xoá thật:
Cần lọc chính xác
→ thêm điều kiện filter theo
thời gian trong truy vấn
Ba lưu ý về chế độ thanh toán: | Chế độ | Hợp với | |---|---| | On-demand | tải khó đoán, đỉnh đột ngột | | Provisioned | tải ổn định, biết trước | | Provisioned + auto scaling | tải theo chu kỳ |
20.000 cảm biến gửi đều mỗi
15 phút
↓
Tải rất ổn định, đoán được
→ provisioned + reserved capacity
rẻ hơn nhiều
Ba lưu ý về IoT: | Lưu ý | Chi tiết | |---|---| | IoT Core nhận dữ liệu từ thiết bị | | | Rule engine ghi thẳng vào DynamoDB | | | Timestream chuyên cho chuỗi thời gian | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đo RCU tiêu thụ của một Query điển hình | | | Xem CloudWatch Contributor Insights tìm khoá nóng | | | Kiểm ThrottledRequests có tăng không | |
Và một lời khuyên: hãy cân nhắc TTL trước khi dựng mẫu bảng theo thời gian. Bảng theo tuần giải quyết đúng bài toán chi phí xoá, nhưng nó đẩy toàn bộ độ phức tạp sang tầng ứng dụng — mỗi truy vấn liên tuần trở thành nhiều lời gọi phải gộp kết quả, và mỗi đoạn mã mới phải biết quy tắc đặt tên bảng.
A company has released a new mobile game and its backend servers are hosted on the company’s on-premises data center. The game logic is exposed using REST APIs that have multiple functions depending on the user state. Access to the backend services is controlled with an API key, while any test traffic is distinguished by a different key. A central file server stores player session data. User traffic is variable throughout the day but the on-premises servers cannot handle traffic during peak hours. The game also has latency issues caused by the slow fetching of player session data. The management tasked the solutions architect to migrate this infrastructure to AWS in order to improve scalability and reduce the latency for data access while keeping the backend API model unchanged.
Which of the following is the recommended solution to meet the company requirements?
-
A
Create a fleet of Amazon EC2 instances to host the backend services. Expose the REST APIs by placing the instances behind a Network Load Balancer (NLB). Use Amazon Aurora Serverless to store the player session data.
-
B
Use AWS Lambda functions to run the backend game logic. Expose the REST APIs by using Amazon API Gateway. Use Amazon DynamoDB with auto-scaling to store the player session data.
-
C
Use AWS Lambda functions to run the backend game logic. Expose the REST APIs by using AWS AppSync. Use Amazon Aurora Serverless to store the player session data.
-
D
Use AWS Lambda functions to run the backend game logic. Expose the REST APIs by placing the Lambda functions behind an Application Load Balancer (ALB). Use Amazon DynamoDB with auto-scaling to store the player session data.
Xem giải thích
Đáp án
**B — Dùng AWS Lambda chạy logic nghiệp vụ, phơi REST API qua Amazon API Gateway, và lưu dữ liệu phiên người chơi trong DynamoDB có auto scaling.
Vì sao đúng
Đề nêu bốn ràng buộc, và phương án này khớp cả bốn: | Ràng buộc | Thành phần | |---|---| | Tải biến động, máy chủ hiện tại không chịu nổi đỉnh | Lambda tự co giãn | | Giữ nguyên mô hình REST API | API Gateway REST API | | Truy cập điều khiển bằng API key, có key riêng cho test | API key + usage plan + stage | | Chậm khi lấy dữ liệu phiên | DynamoDB, độ trễ mili giây |
⚠ Điểm mấu chốt: đề nhắc API key và lưu lượng test — đó là mô tả của API Gateway:
API Gateway có sẵn:
- API key
- usage plan (hạn mức, tần suất)
- stage (prod, test)
↓
Không phải viết gì để có
những thứ đó
aws apigateway create-api-key --name khoa-san-xuat --enabled
aws apigateway create-usage-plan --name goi-san-xuat \
--throttle burstLimit=5000,rateLimit=2000 \
--quota limit=10000000,period=MONTH \
--api-stages apiId=abc123,stage=prod
⚠ Và đây là lý do phương án D sai — ALB không có khái niệm API key:
ALB gọi được Lambda (từ 2018)
↓
Nhưng ALB là load balancer
→ không có API key, usage plan,
throttling theo khách hàng,
request validation
↓
Phải tự viết hết trong Lambda
| Tính năng | API Gateway | ALB |
|---|---|---|
| API key + usage plan | CÓ | không |
| Throttling theo khách hàng | CÓ | không |
| Kiểm tra request theo schema | CÓ | không |
| Nhiều stage (prod/test) | CÓ | không |
| Cache phản hồi | CÓ | không |
⚠ Và phương án C sai vì AppSync là GraphQL:
Đề nói rõ: "giữ nguyên mô hình
backend API"
↓
AppSync phơi GraphQL, không
phải REST
↓
Chuyển sang GraphQL = viết lại
toàn bộ client game
⚠ Và Aurora Serverless (C) không hợp cho dữ liệu phiên:
Dữ liệu phiên: đọc/ghi theo khoá,
rất nhiều, rất nhanh
↓
DynamoDB: mili giây một chữ số,
co giãn không giới hạn
↓
Aurora Serverless v1 còn có
độ trễ khi đánh thức
⚠ Và phương án A giữ nguyên EC2 — không giải quyết được vấn đề co giãn:
Đội EC2 sau NLB
→ vẫn phải cấu hình ASG, vẫn
có thời gian khởi động máy
↓
Và NLB là tầng 4
→ không hiểu REST, không có
API key
Bảng phiên trong DynamoDB:
table = dynamodb.create_table(
TableName='phien-nguoi-choi',
KeySchema=[{'AttributeName': 'ma_nguoi_choi', 'KeyType': 'HASH'}],
AttributeDefinitions=[
{'AttributeName': 'ma_nguoi_choi', 'AttributeType': 'S'}],
BillingMode='PAY_PER_REQUEST')
⚠ Và TTL tự dọn phiên hết hạn:
table.put_item(Item={
'ma_nguoi_choi': 'NC-9981',
'trang_thai': {...},
'het_han': int(time.time()) + 86400})
⚠ Và DAX đưa độ trễ xuống micro giây nếu cần:
DynamoDB: mili giây một chữ số
↓
DAX (cache trước DynamoDB):
micro giây cho lượt đọc
↓
Với game nhạy độ trễ, đáng
cân nhắc
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không có máy chủ nào phải quản | | | Co giãn từ 0 tới hàng chục nghìn yêu cầu/giây | | | Trả tiền theo lượt gọi, không trả cho lúc rảnh | |
⚠ Và điểm cuối rất hợp với mẫu tải của game:
Tải biến động trong ngày
→ EC2: phải chạy đủ máy cho
giờ cao điểm suốt 24 giờ
↓
Lambda: giờ vắng gần như
không tốn gì
⚠ Nhưng khởi động nguội là điều phải tính:
Lambda lâu không gọi
→ lần gọi đầu mất thêm vài
trăm mili giây tới vài giây
↓
Với game nhạy độ trễ
→ dùng provisioned concurrency
aws lambda put-provisioned-concurrency-config \
--function-name logic-game --qualifier prod \
--provisioned-concurrent-executions 50
Vì sao các phương án khác sai
- **D. Lambda đặt sau Application Load Balancer, dùng DynamoDB — đây là phương án gần nhất và ALB thật sự gọi được Lambda, nhưng ALB không có API key, usage plan hay stage, nên phải tự viết lại toàn bộ cơ chế kiểm soát truy cập mà đề yêu cầu giữ nguyên.
- **C. Lambda phơi qua AWS AppSync, dùng Aurora Serverless — AppSync là GraphQL, thay đổi hẳn mô hình API mà đề yêu cầu giữ nguyên.
- **A. Đội EC2 sau NLB, dùng Aurora Serverless — vẫn phải quản máy chủ, và NLB ở tầng 4 nên không xử lý được API key hay định tuyến theo đường dẫn.
Ghi nhớ
⚠ Bốn cách phơi API trên AWS — bảng phải thuộc: | Cách | Kiểu API | Tính năng quản trị | |---|---|---| | API Gateway REST | REST | đầy đủ nhất: key, usage plan, cache | | API Gateway HTTP | REST | rẻ hơn, nhanh hơn, ít tính năng hơn | | AppSync | GraphQL | giải quyết dữ liệu, subscription | | ALB + Lambda | HTTP thô | ít nhất |
⚠ REST API và HTTP API — chọn theo tính năng cần: | Tính năng | REST API | HTTP API | |---|---|---| | API key + usage plan | CÓ | KHÔNG | | Request validation | CÓ | không | | Cache | CÓ | không | | WAF | CÓ | không | | Giá | cao hơn ~3,5 lần | rẻ hơn |
Đề cần API key
→ BẮT BUỘC REST API
→ HTTP API không có
Từ khoá nhận diện:
"API key, usage plan" → API Gateway REST API "keep REST model unchanged" → không dùng AppSync "session data, low latency" → DynamoDB (+ DAX) "variable traffic, scale to zero" → Lambda "GraphQL, real-time subscriptions" → AppSync
Ba lưu ý về API Gateway: | Lưu ý | Chi tiết | |---|---| | API key KHÔNG phải cơ chế xác thực | | | Dùng Cognito authorizer hoặc Lambda authorizer để xác thực | | | Timeout tối đa 29 giây (REST/HTTP API) | |
⚠ Điểm đầu rất quan trọng:
API key chỉ để nhận diện khách
và áp hạn mức
↓
Nó đi trong header, dễ trích
từ ứng dụng di động
↓
Xác thực người dùng phải dùng
Cognito hoặc JWT
Ba lưu ý về Lambda: | Lưu ý | Chi tiết | |---|---| | Timeout tối đa 15 phút | | | Bộ nhớ 128 MB - 10 GB, CPU tỷ lệ theo bộ nhớ | | | Provisioned concurrency chống khởi động nguội | |
⚠ Tăng bộ nhớ thường làm hàm RẺ hơn:
Tăng bộ nhớ → CPU mạnh hơn
→ chạy nhanh hơn
↓
Giá = bộ nhớ × thời gian
→ gấp đôi bộ nhớ mà nhanh hơn
gấp đôi thì rẻ hơn
↓
Dùng AWS Lambda Power Tuning
để tìm điểm tối ưu
Ba lưu ý về DynamoDB cho phiên: | Lưu ý | Chi tiết | |---|---| | Khoá là mã người chơi | | | TTL tự dọn phiên cũ | | | DAX nếu cần micro giây | |
Ba lưu ý về di trú REST API: | Lưu ý | Chi tiết | |---|---| | Giữ nguyên đường dẫn và tên tham số | | | Nhập OpenAPI vào API Gateway được | | | Chuyển dần bằng weighted routing của Route 53 | |
Ba lưu ý về chi phí: | Thành phần | Cách tính | |---|---| | API Gateway REST | theo triệu lượt gọi + truyền dữ liệu | | Lambda | GB-giây + số lượt gọi | | DynamoDB on-demand | theo đơn vị đọc/ghi |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy thử tải với đỉnh dự kiến | | | Đo p99 độ trễ, không chỉ trung bình | | | Kiểm tỷ lệ khởi động nguội trong X-Ray | |
Và một lời khuyên: hãy đo độ trễ ở phân vị 99 chứ đừng nhìn trung bình. Kiến trúc serverless có trung bình rất tốt nhưng đuôi dài do khởi động nguội — và trong một game, những người chơi rơi vào cái đuôi đó chính là những người bỏ đi.
A stock trading company is running its application on the AWS cloud. The mission-critical database is hosted on an Amazon RDS for MySQL instance deployed in a Multi-AZ configuration. An AWS Backup rule is in place to take automated snapshots hourly. The operations team recently performed an RDS database failover test and found that it caused an outage of approximately 40 seconds.
The management has asked the solutions architect to implement a solution that will reduce the outage to less than 20 seconds. Most connections should stay alive during failovers except for the ones that are in the middle of a transaction or SQL statement. New database connections should still be accepted, and the incoming write requests should be queued until the failover completes.
Which of the following options should the solutions architect implement to meet the company's requirements? (Choose THREE.)
-
A
Ensure that Multi-AZ is enabled on Amazon RDS for MySQL and create one or more read replicas to ensure quick failover.
-
B
Migrate the Amazon RDS for MySQL cluster to an Amazon Aurora for MySQL cluster.
-
C
Set up an Amazon RDS Proxy in front of the database layer to automatically route traffic to healthy RDS instances.
-
D
Ensure that Multi-AZ is enabled on Amazon Aurora and create one or more Aurora Replicas.
-
E
Enable the Amazon RDS Optimized Writes feature and create an Amazon ElastiCache for Memcached cluster in front of the database layer to cache any frequently requested queries.
-
F
Enable the Amazon RDS Optimized Reads feature and launch an Amazon ElastiCache for Redis cluster in front of the database layer to temporarily serve database queries in case of RDS failure.
Xem giải thích
Đáp án
**B, C và D — Chuyển cụm RDS for MySQL sang Aurora MySQL; đặt RDS Proxy trước tầng cơ sở dữ liệu; và bật Multi-AZ trên Aurora cùng một hoặc nhiều Aurora Replica.
Vì sao đúng
Đề nêu bốn yêu cầu rất cụ thể, và ba đáp án ghép lại mới đủ: | Yêu cầu | Thành phần | |---|---| | Chuyển đổi dưới 20 giây | Aurora (thường dưới 30 giây, với proxy thì nhanh hơn) | | Phần lớn kết nối SỐNG SÓT | RDS Proxy | | Vẫn nhận kết nối mới | RDS Proxy | | Yêu cầu ghi xếp hàng chờ | RDS Proxy |
⚠ Ba yêu cầu cuối chỉ RDS Proxy làm được — đây là điểm mấu chốt:
Không có proxy: CSDL chuyển đổi
→ MỌI kết nối đang mở bị đứt
↓
Ứng dụng phải bắt lỗi và kết
nối lại
↓
Có proxy: proxy giữ kết nối
với ứng dụng
→ nó tự nối lại với CSDL mới
ở phía sau
Ứng dụng ←──── giữ nguyên ────→ Proxy
↓
nối lại với writer mới
↓
Aurora writer
⚠ Và việc "xếp hàng yêu cầu ghi" là hành vi riêng của proxy:
Trong lúc chuyển đổi, chưa có
writer
↓
Proxy GIỮ yêu cầu lại thay vì
trả lỗi
↓
Writer mới sẵn sàng → gửi tiếp
→ ứng dụng chỉ thấy chậm, không
thấy lỗi
Tạo proxy:
aws rds create-db-proxy --db-proxy-name proxy-giao-dich \
--engine-family MYSQL \
--auth '[{"AuthScheme":"SECRETS",
"SecretArn":"arn:aws:secretsmanager:...",
"IAMAuth":"REQUIRED"}]' \
--role-arn arn:aws:iam::111122223333:role/RDSProxy \
--vpc-subnet-ids subnet-1a subnet-1b
⚠ RDS Proxy bắt buộc dùng Secrets Manager cho thông tin đăng nhập:
Không nhận mật khẩu trực tiếp
↓
Phải tạo secret trước
→ và proxy cần IAM role đọc
secret đó
↓
Đây là thiết kế có chủ đích
⚠ Và Aurora nhanh hơn RDS ở khâu chuyển đổi vì kiến trúc lưu trữ: | Tiêu chí | RDS Multi-AZ | Aurora | |---|---|---| | Lưu trữ | hai bản riêng, sao chép đồng bộ | MỘT tầng lưu trữ chung, 6 bản trên 3 AZ | | Chuyển đổi | 60-120 giây | thường dưới 30 giây | | Replica đọc được | KHÔNG (standby) | CÓ (tối đa 15) | | Replica làm dự phòng | không tự động | CÓ, theo thứ tự ưu tiên |
RDS: standby phải nhận vai writer,
DNS phải đổi
↓
Aurora: tầng lưu trữ đã chung
→ một replica chỉ cần "nhận
quyền ghi"
→ nhanh hơn nhiều
Đặt thứ tự ưu tiên chuyển đổi:
aws rds create-db-instance \
--db-instance-identifier aurora-replica-1 \
--db-cluster-identifier cum-giao-dich \
--engine aurora-mysql --db-instance-class db.r6g.xlarge \
--promotion-tier 0
⚠ promotion-tier quyết định replica nào lên thay:
Tier 0-15, số nhỏ được ưu tiên
↓
Cùng tier → chọn instance lớn
nhất
↓
Không có replica nào: Aurora
phải TẠO instance mới
→ chậm hơn nhiều
⚠ Đây là lý do D (có Aurora Replica) là bắt buộc, không phải tuỳ chọn:
Cụm Aurora chỉ có một writer
→ writer hỏng, không có replica
↓
Aurora dựng instance mới từ
tầng lưu trữ
→ mất hàng phút, không phải
hàng giây
⚠ Và vì sao phương án A không đủ:
A: giữ RDS MySQL, thêm read replica
↓
Read replica của RDS KHÔNG
tự động lên thay writer
→ phải promote thủ công
↓
Và chuyển đổi Multi-AZ của RDS
vốn đã 40 giây — đúng con số
đề đang muốn giảm
⚠ Và vì sao E, F sai:
Optimized Writes: giảm ghi hai lần
của MySQL
→ cải thiện thông lượng GHI
↓
Optimized Reads: dùng NVMe cục
bộ cho bảng tạm
→ cải thiện truy vấn phức tạp
↓
CẢ HAI không liên quan gì tới
thời gian chuyển đổi
Và ElastiCache trước CSDL
→ giảm tải đọc
↓
Không giúp gì cho việc GHI
trong lúc chuyển đổi
→ F còn nói cache "phục vụ truy
vấn khi RDS hỏng"
→ cache chỉ có dữ liệu đã cache,
không thay được CSDL
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Chuyển đổi nhanh hơn nhiều | | | Kết nối ứng dụng không đứt | | | Gộp kết nối, giảm tải cho CSDL | |
⚠ Và gộp kết nối là lợi ích phụ đáng kể:
Hàng nghìn kết nối từ ứng dụng
→ proxy gộp thành ít kết nối
thật tới CSDL
↓
CSDL không phải tốn bộ nhớ
cho từng kết nối
Vì sao các phương án khác sai
- **A. Bảo đảm Multi-AZ trên RDS MySQL và tạo read replica — đây là phương án gần nhất và read replica thật sự tăng khả năng chịu tải, nhưng read replica của RDS không tự động lên thay writer, và chuyển đổi Multi-AZ của RDS chính là 40 giây mà đề đang muốn giảm.
- **E. Bật Optimized Writes và dựng ElastiCache for Memcached — Optimized Writes cải thiện thông lượng ghi, không liên quan tới thời gian chuyển đổi.
- **F. Bật Optimized Reads và dựng ElastiCache for Redis để phục vụ truy vấn khi RDS hỏng — cache chỉ có dữ liệu đã nạp, không thay thế được cơ sở dữ liệu.
Ghi nhớ
⚠ Bốn cấu hình sẵn sàng cao cho CSDL — bảng phải thuộc: | Cấu hình | Chuyển đổi | |---|---| | RDS Multi-AZ instance | 60-120 giây | | RDS Multi-AZ DB cluster | dưới 35 giây | | Aurora + replica | thường dưới 30 giây | | Aurora + replica + RDS Proxy | nhanh hơn, kết nối không đứt |
Từ khoá nhận diện:
"connections should stay alive during failover" → RDS Proxy "queue write requests during failover" → RDS Proxy "reduce failover time" → Aurora + replica "too many connections" → RDS Proxy gộp kết nối "Lambda connecting to RDS" → RDS Proxy
⚠ Lambda + RDS là ca kinh điển cần proxy:
Mỗi lời gọi Lambda mở kết nối mới
→ hàng nghìn lời gọi đồng thời
↓
CSDL chạm `max_connections`
→ lỗi "too many connections"
↓
Proxy gộp lại
Ba lưu ý về RDS Proxy: | Lưu ý | Chi tiết | |---|---| | Bắt buộc dùng Secrets Manager | | | Hỗ trợ MySQL, PostgreSQL, MariaDB, SQL Server | | | Tính phí theo vCPU của instance CSDL | |
⚠ Pinning làm mất tác dụng gộp kết nối:
Dùng giao dịch, biến phiên,
bảng tạm, prepared statement
↓
Proxy phải "ghim" kết nối cho
một client
→ không dùng chung được
↓
Theo dõi `DatabaseConnectionsCurrentlySessionPinned`
Ba lưu ý về Aurora: | Lưu ý | Chi tiết | |---|---| | Lưu trữ chung, 6 bản trên 3 AZ | | | Tối đa 15 replica, đọc được | | | Reader endpoint tự cân bằng tải | |
Ba loại endpoint của Aurora: | Endpoint | Trỏ tới | |---|---| | Cluster (writer) | instance đang ghi | | Reader | cân bằng giữa các replica | | Custom | nhóm instance tự định nghĩa |
⚠ Custom endpoint hữu ích khi tách loại tải:
Truy vấn báo cáo nặng
→ custom endpoint trỏ tới
hai replica lớn
↓
Truy vấn thường → reader
endpoint
Ba lưu ý về di trú sang Aurora: | Cách | Ngừng dịch vụ | |---|---| | Tạo Aurora Read Replica từ RDS rồi promote | rất ngắn | | Khôi phục từ snapshot | dài | | DMS full load + CDC | rất ngắn |
⚠ Cách đầu là cách đơn giản nhất cho MySQL:
aws rds create-db-cluster \
--db-cluster-identifier cum-aurora \
--engine aurora-mysql \
--replication-source-identifier <arn-rds-mysql>
Ba lưu ý về ứng dụng: | Lưu ý | Chi tiết | |---|---| | Vẫn phải có logic thử lại | | | Đặt timeout kết nối hợp lý | | | Đừng cache DNS quá lâu | |
⚠ Cache DNS của JVM là bẫy kinh điển:
JVM mặc định cache DNS VĨNH VIỄN
ở một số cấu hình
↓
CSDL chuyển đổi, DNS đổi
→ ứng dụng vẫn gọi IP cũ
↓
Đặt `networkaddress.cache.ttl=5`
Ba việc kiểm chứng: | Việc | Cách | |---|---| | failover-db-cluster và bấm giờ | | | Đếm số kết nối đứt trong lúc chuyển đổi | | | Kiểm ứng dụng có nhận lỗi nào không | |
aws rds failover-db-cluster --db-cluster-identifier cum-giao-dich
Và một lời khuyên: hãy giữ logic thử lại trong ứng dụng dù đã có RDS Proxy. Proxy che được phần lớn gián đoạn nhưng đề bài cũng nói rõ: kết nối đang giữa một giao dịch vẫn bị đứt — và với hệ thống giao dịch chứng khoán, đó chính là những kết nối quan trọng nhất.
A data analytics company has recently adopted a hybrid cloud infrastructure with AWS. They are in the business of collecting and processing vast amounts of data. Each data set generates up to several thousands of files which can range from 10 MB to 1 GB in size. The archived data is rarely restored and in case there is a request to retrieve it, the company has a maximum of 24 hours to send the files. The data sets can be searched using its file ID, set name, authors, tags, and other criteria.
Which of the following options provides the most cost-effective architecture to meet the above requirements?
-
A
1. For each completed data set, compress and concatenate all of the files into a single Glacier archive.
2. Store the associated archive ID for the compressed files along with other search metadata in a DynamoDB table.
3. For retrieving the data, query the DynamoDB table for files that match the search criteria and then restore the files from the retrieved archive ID.
-
B
1. Store the files of the completed data sets into a single S3 bucket.
2. Store the S3 object key for the compressed files along with other search metadata in a DynamoDB table.
3. For retrieving the data, query the DynamoDB table for files that match the search criteria and then restore the files from the S3 bucket.
-
C
1. Store individual files in Glacier using the filename as the archive name.
2. For retrieving the data, query the Glacier vault for files matching the search criteria.
-
D
1. Store individual compressed files to an S3 bucket. Also store the search metadata and the S3 object key of the files in a separate S3 bucket.
2. Create a lifecycle rule to move the data from an S3 Standard class to Glacier after a certain a month.
3. For retrieving the data, query the S3 bucket for files matching the search criteria and then retrieve the file from the other S3 bucket.
Xem giải thích
Đáp án
**A — Với mỗi bộ dữ liệu hoàn chỉnh, nén và gộp toàn bộ tệp thành một archive Glacier duy nhất; lưu archive ID cùng siêu dữ liệu tìm kiếm trong một bảng DynamoDB; khi cần lấy thì truy vấn DynamoDB rồi khôi phục theo archive ID.
Vì sao đúng
Đề cho ba dữ kiện, và mỗi cái loại bớt phương án: | Dữ kiện | Hệ quả | |---|---| | Dữ liệu hiếm khi khôi phục | lớp lưu trữ lạnh nhất | | Có tối đa 24 giờ để gửi tệp | Glacier hoàn toàn đủ | | Tìm theo file ID, tên bộ, tác giả, thẻ | cần chỉ mục ngoài — DynamoDB |
⚠ Điểm mấu chốt: Glacier vault KHÔNG tìm kiếm được:
Glacier chỉ biết archive ID
→ một chuỗi dài do AWS sinh
↓
Không có tên tệp, không có
thẻ, không có tìm kiếm
↓
Phải tự giữ chỉ mục ở nơi khác
Đây là lý do phương án C sai — "truy vấn vault theo tiêu chí tìm kiếm" là việc không tồn tại.
⚠ Và gộp tệp lại là chỗ tiết kiệm lớn nhất:
Mỗi bộ dữ liệu có hàng nghìn tệp
↓
Lưu riêng: mỗi archive tính
thêm 32 KB siêu dữ liệu
↓
Và Glacier tính phí tối thiểu
90 ngày cho mỗi archive
↓
Gộp thành một: một lần phí
siêu dữ liệu, một lần phí
yêu cầu
Tính thử với 5.000 tệp:
Lưu riêng: 5.000 × 32 KB
= 160 MB siêu dữ liệu thừa
↓
Và 5.000 lời gọi API upload
↓
Gộp lại: 1 archive, 32 KB,
1 lời gọi
Bảng chỉ mục trong DynamoDB:
table.put_item(Item={
'ma_bo_du_lieu': 'BDL-2026-0331',
'ten_bo': 'khao-sat-dia-chan-vinh-bac-bo',
'tac_gia': 'nhom-dia-vat-ly',
'the': ['dia-chan', '3d', 'ngoai-khoi'],
'archive_id': 'NkbByEejwEggmBz2fT...',
'vault': 'kho-du-lieu-lanh',
'kich_thuoc_byte': 48293847562,
'danh_sach_tep': ['tep-001.segy', 'tep-002.segy']})
⚠ Và GSI cho phép tìm theo tác giả hoặc thẻ:
aws dynamodb update-table --table-name chi-muc-bo-du-lieu \
--attribute-definitions AttributeName=tac_gia,AttributeType=S \
--global-secondary-index-updates '[{"Create": {
"IndexName": "theo-tac-gia",
"KeySchema": [{"AttributeName":"tac_gia","KeyType":"HASH"}],
"Projection": {"ProjectionType": "ALL"}}}]'
Khôi phục:
job = glacier.initiate_job(
vaultName='kho-du-lieu-lanh',
jobParameters={'Type': 'archive-retrieval',
'ArchiveId': archive_id,
'Tier': 'Standard'})
⚠ Chọn tầng lấy ra theo hạn 24 giờ của đề: | Tầng | Thời gian | Giá | |---|---|---| | Expedited | 1-5 phút | đắt nhất | | Standard | 3-5 giờ | trung bình | | Bulk | 5-12 giờ | rẻ nhất |
Hạn 24 giờ
→ Bulk hoàn toàn đủ
→ và rẻ nhất
⚠ Và vì sao phương án B đắt hơn:
B lưu vào "một bucket S3"
→ không nói lớp lưu trữ
↓
Mặc định là S3 Standard
→ đắt hơn Glacier khoảng
5-6 lần
↓
Với dữ liệu "hiếm khi khôi
phục", đó là lãng phí lớn
⚠ Và vì sao phương án D lộn xộn:
D lưu siêu dữ liệu vào MỘT BUCKET
S3 KHÁC
↓
S3 không truy vấn được theo
tác giả hay thẻ
→ phải liệt kê và đọc từng
object
↓
Đó là việc DynamoDB làm trong
mili giây
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Chi phí lưu trữ thấp nhất | | | Tìm kiếm nhanh qua DynamoDB | | | Một archive cho cả bộ, ít phí phụ | |
⚠ Nhưng gộp có một cái giá:
Cần đúng MỘT tệp trong bộ
→ phải lấy cả archive về
↓
Với bộ vài chục GB, đó là
nhiều dữ liệu và nhiều tiền
truyền
↓
Đề nói tìm theo BỘ dữ liệu
→ nên chấp nhận được
⚠ Và Glacier có tính năng lấy một phần archive:
job = glacier.initiate_job(
vaultName='kho-du-lieu-lanh',
jobParameters={'Type': 'archive-retrieval',
'ArchiveId': archive_id,
'RetrievalByteRange': '0-1048575'})
Lấy theo dải byte
→ nhưng phải biết tệp nằm ở
byte nào
→ nên lưu cả offset vào
DynamoDB nếu cần
Ghi nhớ về chất lượng câu hỏi
⚠ S3 Glacier "vault" là dịch vụ độc lập, đã lỗi thời so với lớp lưu trữ Glacier của S3.
| Tiêu chí | Glacier vault (dịch vụ riêng) | S3 Glacier storage class |
|---|---|---|
| API | riêng, dùng archive ID | API S3 thông thường |
| Tên tệp | KHÔNG có | có key như mọi object |
| Liệt kê | job chạy hàng giờ | S3 Inventory hoặc ListObjects |
| Vòng đời | thủ công | luật vòng đời tự động |
| Trạng thái | legacy | hiện hành |
Cách làm hiện nay:
aws s3 cp bo-du-lieu.tar.gz \
s3://kho-lanh/2026/BDL-2026-0331.tar.gz \
--storage-class DEEP_ARCHIVE
Object có KEY đọc được
→ liệt kê, gắn thẻ, đặt luật
vòng đời bình thường
↓
Vẫn nên có DynamoDB làm chỉ mục
để tìm theo tác giả/thẻ
→ hoặc S3 Inventory + Athena
Và Deep Archive rẻ hơn Glacier Flexible tới 4 lần: | Lớp | Giá (USD/GB-tháng, xấp xỉ) | Lấy ra | |---|---|---| | S3 Standard | 0,023 | tức thì | | Glacier Instant Retrieval | 0,004 | tức thì | | Glacier Flexible Retrieval | 0,0036 | phút tới giờ | | Glacier Deep Archive | 0,00099 | 12-48 giờ |
Hạn 24 giờ của đề
→ Deep Archive ở chế độ Standard
(12 giờ) vừa khít
→ rẻ hơn nữa
Vì sao các phương án khác sai
- **B. Lưu tệp vào một bucket S3, giữ object key và siêu dữ liệu trong DynamoDB — đây là phương án gần nhất và cấu trúc chỉ mục hoàn toàn đúng, nhưng nó không nói tới lớp lưu trữ lạnh, nên mặc định là S3 Standard — đắt hơn nhiều lần cho dữ liệu hiếm khi đọc.
- **D. Lưu tệp nén vào S3, siêu dữ liệu vào một bucket S3 khác, đặt luật vòng đời sang Glacier — S3 không truy vấn được theo tác giả hay thẻ; phải liệt kê và đọc từng object.
- **C. Lưu từng tệp riêng vào Glacier với tên tệp làm tên archive, rồi truy vấn vault theo tiêu chí tìm kiếm — Glacier vault không có khả năng tìm kiếm, và archive name không phải thứ tra cứu được.
Ghi nhớ
⚠ Sáu lớp lưu trữ S3 — bảng phải thuộc: | Lớp | Lấy ra | Hợp với | |---|---|---| | Standard | tức thì | truy cập thường xuyên | | Intelligent-Tiering | tức thì | mẫu truy cập không đoán được | | Standard-IA | tức thì | ít đọc, cần ngay | | Glacier Instant Retrieval | tức thì | lưu trữ nhưng thỉnh thoảng cần gấp | | Glacier Flexible Retrieval | phút tới giờ | lưu trữ, chờ được | | Glacier Deep Archive | 12-48 giờ | lưu trữ tuân thủ dài hạn |
Từ khoá nhận diện:
"rarely restored, 24 hours to retrieve" → Glacier Deep Archive hoặc Flexible "search by metadata" → DynamoDB làm chỉ mục "thousands of small files to archive" → gộp lại trước khi lưu "need it back in minutes" → Glacier Instant Retrieval "unknown access pattern" → Intelligent-Tiering
Ba lưu ý về phí tối thiểu: | Lớp | Thời gian tối thiểu | |---|---| | Standard-IA, One Zone-IA | 30 ngày | | Glacier Instant Retrieval | 90 ngày | | Glacier Flexible Retrieval | 90 ngày | | Glacier Deep Archive | 180 ngày |
⚠ Phí tối thiểu làm hỏng tính toán tiết kiệm:
Chuyển dữ liệu sang Deep Archive
→ xoá sau 30 ngày
↓
Vẫn trả tiền đủ 180 ngày
→ đắt hơn để ở Standard
Ba lưu ý về kích thước object: | Lưu ý | Chi tiết | |---|---| | IA và Glacier tính tối thiểu 128 KB mỗi object | | | Nhiều tệp nhỏ nên gộp lại | | | Siêu dữ liệu Glacier tính thêm 32-40 KB | |
⚠ Tệp 10 KB trong Glacier vẫn tính như 128 KB:
1 triệu tệp 10 KB = 10 GB thật
↓
Tính tiền như 128 GB
→ gấp 12,8 lần
Ba lưu ý về chỉ mục: | Cách | Đặc điểm | |---|---| | DynamoDB | truy vấn mili giây, GSI linh hoạt | | S3 Inventory + Athena | rẻ hơn, chậm hơn, chỉ siêu dữ liệu S3 | | OpenSearch | tìm toàn văn, đắt hơn |
Ba lưu ý về vòng đời: | Lưu ý | Chi tiết | |---|---| | Chuyển tầng tính phí theo số object | | | Không chuyển ngược tự động được | | | Dùng thẻ hoặc tiền tố để lọc | |
Ba lưu ý về khôi phục: | Lưu ý | Chi tiết | |---|---| | Khôi phục tạo bản sao tạm trong S3 | | | Đặt Days cho bản sao đó | | | Bulk rẻ nhất, Expedited đắt nhất | |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Khôi phục thử một bộ, bấm giờ | | | So chi phí thật trong Cost Explorer | | | Kiểm chỉ mục có khớp với dữ liệu thật | |
Và một lời khuyên: hãy khôi phục thử một bộ dữ liệu ít nhất mỗi năm. Dữ liệu nằm trong Glacier nhiều năm mà chưa ai lấy ra lần nào là dữ liệu chưa được chứng minh là còn dùng được — và chỉ mục DynamoDB có thể đã lệch khỏi thực tế mà không ai biết.
A company recently switched to using Amazon CloudFront for its content delivery network. The development team already made the preparations necessary to optimize the application performance for global users. The company’s content management system (CMS) serves both dynamic and static content. The dynamic content is served from a fleet of Amazon EC2 instances behind an application load balancer (ALB) while the static assets are served from an Amazon S3 bucket. The ALB is configured as the default origin of the CloudFront distribution. An Origin Access Control (OAC) was created and applied to the S3 bucket policy to allow access only from the CloudFront distribution. Upon testing the CMS webpage, the static assets return an error 404 message.
Which of the following solutions must be implemented to solve this error? (Select TWO.)
-
A
Update the CloudFront distribution and create a new behavior that will forward to the origin of the static assets based on path pattern.
-
B
Update the application load balancer listener to check for HEADER condition if the request is from CloudFront and forward it to the Amazon S3 bucket.
-
C
Edit the CloudFront distribution and create another origin for serving the static assets.
-
D
Replace the CloudFront distribution with AWS Global Accelerator. Configure the AWS Global Accelerator with multiple endpoint groups that target endpoints on all AWS Regions. Use the accelerator’s static IP address to create a record in Amazon Route 53 for the apex domain.
-
E
Update the application load balancer listener and create a new path-based rule for the static assets so that it will forward requests to the Amazon S3 bucket.
Xem giải thích
Đáp án
**A và C — Sửa CloudFront distribution để thêm một origin nữa phục vụ tài nguyên tĩnh, và tạo một cache behavior mới chuyển yêu cầu tới origin đó theo mẫu đường dẫn.
Vì sao đúng
Đề mô tả tình huống rất rõ ràng:
ALB là origin MẶC ĐỊNH
→ mọi yêu cầu đều tới ALB
↓
Yêu cầu ảnh, CSS, JS cũng tới ALB
→ ALB không có chúng
→ trả 404
↓
Bucket S3 đã cấu hình đúng
với OAC, nhưng không ai gọi
tới nó
⚠ Điểm mấu chốt: một distribution có nhiều origin, và behavior quyết định đi đâu:
Distribution
├── Origin 1: ALB (mặc định)
└── Origin 2: S3 bucket
↑
Behavior với path pattern
/static/* → Origin 2
Default behavior (*) → Origin 1
Thêm origin S3:
{"Id": "s3-tai-nguyen-tinh",
"DomainName": "tai-nguyen.s3.ap-southeast-1.amazonaws.com",
"S3OriginConfig": {"OriginAccessIdentity": ""},
"OriginAccessControlId": "E1ABCDEFGHIJKL"}
Thêm cache behavior:
{"PathPattern": "/static/*",
"TargetOriginId": "s3-tai-nguyen-tinh",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"AllowedMethods": {"Quantity": 2, "Items": ["GET", "HEAD"]}}
⚠ Thứ tự behavior rất quan trọng:
CloudFront xét behavior theo THỨ TỰ
↓
Cái khớp ĐẦU TIÊN thắng
↓
Default behavior (*) luôn ở cuối
→ đặt behavior cụ thể lên trước
Nếu đặt "*" trước "/static/*"
→ mọi thứ khớp "*" ngay
→ "/static/*" không bao giờ tới
⚠ Và hai đáp án phải đi cùng nhau:
Chỉ thêm origin (C)
→ không có behavior nào trỏ tới
→ origin nằm đó vô dụng
↓
Chỉ thêm behavior (A)
→ không có origin để trỏ tới
↓
Phải cả hai
⚠ Và vì sao phương án E sai — ALB không chuyển tiếp tới S3:
ALB chỉ chuyển tới target group:
instance, IP, Lambda
↓
KHÔNG chuyển tới bucket S3
↓
Chỉ có thể trả redirect 301
tới URL S3
→ thêm một vòng khứ hồi và
lộ URL S3 ra ngoài
⚠ Và phương án B cũng dựa trên hiểu lầm đó:
B nói ALB listener kiểm tra header
rồi "chuyển tiếp tới bucket S3"
↓
Cùng một vấn đề: ALB không
có kiểu target là S3
⚠ Và phương án D thay CloudFront bằng Global Accelerator:
Global Accelerator hoạt động ở
TẦNG MẠNG
↓
Không cache, không hiểu HTTP
path, không định tuyến theo
đường dẫn
↓
Và nó không phục vụ được S3
bucket
↓
Đây là dịch vụ giải quyết bài
toán khác hẳn
| Tiêu chí | CloudFront | Global Accelerator |
|---|---|---|
| Cache nội dung | CÓ | KHÔNG |
| Định tuyến theo path | CÓ | không |
| Giao thức | HTTP/HTTPS | TCP, UDP |
| IP tĩnh | không | CÓ, anycast |
| Chuyển Region khi hỏng | origin failover | tự động, vài giây |
⚠ Và OAC cần thêm quyền cho behavior mới hoạt động:
{"Effect": "Allow",
"Principal": {"Service": "cloudfront.amazonaws.com"},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::tai-nguyen/*",
"Condition": {"StringEquals": {
"AWS:SourceArn":
"arn:aws:cloudfront::111122223333:distribution/E1ABCDEF"}}}
⚠ Điều kiện AWS:SourceArn là thứ OAC có mà OAI không có:
OAI: bucket policy trỏ tới một
principal đặc biệt
↓
OAC: dùng service principal
+ điều kiện SourceArn
→ chỉ ĐÚNG distribution đó
đọc được
↓
Và OAC hỗ trợ SSE-KMS, OAI
thì không
⚠ Và cache policy cho tài nguyên tĩnh nên khác cho nội dung động: | Loại | Cache policy | |---|---| | Tài nguyên tĩnh | CachingOptimized — TTL dài, nén | | Nội dung động từ ALB | CachingDisabled hoặc TTL ngắn |
Dùng chung một policy
→ hoặc không cache được gì
→ hoặc cache cả trang động
và trả nội dung sai cho
người dùng khác
Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Một tên miền phục vụ cả tĩnh lẫn động | | | Tài nguyên tĩnh cache ở biên, rất nhanh | | | Bucket vẫn riêng tư, chỉ CloudFront đọc được | |
⚠ Và một tên miền duy nhất tránh được vấn đề CORS:
Tài nguyên tĩnh ở tên miền khác
→ trình duyệt áp CORS
→ phải cấu hình header
↓
Cùng tên miền qua CloudFront
→ không có vấn đề CORS
Vì sao các phương án khác sai
- **E. Sửa listener của ALB thêm quy tắc theo đường dẫn để chuyển yêu cầu tài nguyên tĩnh tới bucket S3 — đây là phương án gần nhất và định tuyến theo đường dẫn là ý đúng, nhưng ALB không có kiểu target là S3; nó chỉ chuyển tới instance, IP hoặc Lambda.
- **B. Sửa listener ALB kiểm tra header xem có phải từ CloudFront rồi chuyển tới S3 — cùng vấn đề: ALB không chuyển tiếp được tới S3.
- **D. Thay CloudFront bằng Global Accelerator — dịch vụ tầng mạng, không cache, không định tuyến theo đường dẫn HTTP, và không phục vụ được bucket S3.
Ghi nhớ
⚠ Bốn thành phần của CloudFront distribution — bảng phải thuộc: | Thành phần | Vai trò | |---|---| | Origin | nguồn lấy nội dung | | Cache behavior | path pattern → origin nào, cache thế nào | | Cache policy | khoá cache: header, cookie, query string | | Origin request policy | cái gì được chuyển tiếp tới origin |
⚠ Cache policy và origin request policy khác nhau:
Cache policy: quyết định KHOÁ CACHE
→ thêm header vào đây làm
cache phân mảnh
↓
Origin request policy: quyết định
cái gì ĐI TỚI origin
→ không ảnh hưởng khoá cache
↓
Origin cần header mà không
cần phân mảnh cache
→ dùng origin request policy
Từ khoá nhận diện:
"static assets 404 behind CloudFront" → thiếu origin và behavior "route by path to different backends" → cache behavior theo path pattern "restrict S3 to CloudFront only" → OAC "static IP, TCP/UDP, multi-region failover" → Global Accelerator
Ba lưu ý về OAC: | Lưu ý | Chi tiết | |---|---| | Thay thế OAI, hỗ trợ SSE-KMS | | | Bucket policy phải có AWS:SourceArn | | | Hỗ trợ cả PUT và DELETE qua CloudFront | |
Ba lưu ý về cache behavior: | Lưu ý | Chi tiết | |---|---| | Xét theo thứ tự, cái khớp đầu thắng | | | Default behavior (*) luôn ở cuối | | | Mỗi behavior có cache policy riêng | |
Ba lưu ý về vô hiệu hoá cache: | Lưu ý | Chi tiết | |---|---| | 1.000 đường dẫn invalidation miễn phí mỗi tháng | | | Dùng tên tệp có mã băm thì không cần invalidate | | | Invalidation mất vài phút | |
⚠ Tên tệp có mã băm là cách đúng:
style.css → style.a3f9c2.css
↓
Đổi nội dung → đổi tên
→ URL mới, không cần
invalidate gì
↓
Và bản cũ vẫn cache được lâu
cho người đang mở trang
Ba lưu ý về origin failover: | Lưu ý | Chi tiết | |---|---| | Origin group gồm origin chính và dự phòng | | | Chuyển khi origin chính trả mã lỗi khai trước | | | Chỉ áp cho GET, HEAD, OPTIONS | |
Ba lưu ý về hàm ở biên: | Loại | Chạy ở | Hợp với | |---|---|---| | CloudFront Functions | điểm biên | viết lại URL, header đơn giản | | Lambda@Edge | Regional edge cache | logic phức tạp, gọi dịch vụ khác |
⚠ CloudFront Functions rẻ và nhanh hơn nhiều:
Functions: dưới 1 mili giây,
rẻ hơn 1/6
↓
Nhưng chỉ JavaScript hạn chế,
không gọi mạng được
↓
Viết lại đường dẫn, kiểm tra
header → Functions
Ba lưu ý về giám sát: | Chỉ số | Ý nghĩa | |---|---| | CacheHitRate | tỷ lệ phục vụ từ cache | | 4xxErrorRate | lỗi phía client, gồm 404 | | OriginLatency | origin phản hồi chậm không |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | curl -I xem header X-Cache | | | Thử một đường dẫn tĩnh và một động | | | Gọi thẳng URL S3 — phải bị từ chối | |
Và một lời khuyên: hãy đặt behavior cụ thể lên trước behavior mặc định. CloudFront xét theo thứ tự và dừng ở cái khớp đầu tiên, nên một behavior * đặt nhầm lên đầu sẽ nuốt hết mọi yêu cầu — và triệu chứng giống hệt việc chưa cấu hình gì cả.
A computer hardware manufacturer has a supply chain application that is written in NodeJS. The application is deployed on an Amazon EC2 Reserved instance which has been provisioned with an IAM Role that provides access to data files stored in an S3 bucket.
In this architecture, which of the following IAM policies control access to the data files in S3? (Select TWO.)
-
A
An IAM trust policy that allows the Amazon S3 service to assume an EC2 instance role.
-
B
A bucket policy that allows the EC2 role to list objects in the S3 bucket.
-
C
An IAM trust policy that allows the NodeJS supply chain application running on the EC2 instance to access the data files stored in the S3 bucket.
-
D
An IAM trust policy that allows the Amazon EC2 service to assume an EC2 instance role.
-
E
An IAM permissions policy that allows the EC2 role to access S3 objects.
Xem giải thích
Đáp án
**D và E — Một trust policy cho phép dịch vụ Amazon EC2 giả nhận vai trò của instance, và một permissions policy cho phép vai trò đó truy cập object trong S3.
Vì sao đúng
Mọi IAM role đều có hai chính sách, và chúng trả lời hai câu hỏi khác nhau: | Chính sách | Câu hỏi | Ai được ghi vào Principal | |---|---|---| | Trust policy | AI được giả nhận vai trò này | ec2.amazonaws.com | | Permissions policy | Vai trò này LÀM ĐƯỢC GÌ | không có Principal |
⚠ Đây là cấu trúc phải thuộc, và nó giải thích mọi phương án:
Trust policy thiếu
→ EC2 không giả nhận được
vai trò
→ instance không có credential
nào cả
↓
Permissions policy thiếu
→ có credential nhưng không
làm được gì
Trust policy:
{"Version": "2012-10-17", "Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"}]}
Permissions policy:
{"Version": "2012-10-17", "Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::du-lieu-chuoi-cung-ung/*"}]}
⚠ Và vì sao phương án A sai — chiều giả nhận bị đảo ngược:
A nói: trust policy cho phép
DỊCH VỤ S3 giả nhận vai trò EC2
↓
S3 không giả nhận vai trò của
instance
→ chính EC2 mới là bên giả nhận
↓
Chiều đúng: EC2 → vai trò →
gọi S3
⚠ Và vì sao phương án C sai — ứng dụng không phải principal:
C nói trust policy cho phép
"ứng dụng NodeJS" truy cập S3
↓
IAM không biết gì về ứng dụng
NodeJS
→ principal của IAM là dịch vụ
AWS, tài khoản, hoặc IAM
entity
↓
Và trust policy không cấp
quyền truy cập S3 — đó là
việc của permissions policy
⚠ Và vì sao phương án B không cần thiết:
Bucket policy CHỈ cần khi:
- truy cập LIÊN TÀI KHOẢN
- hoặc muốn từ chối tường minh
- hoặc cấp quyền cho người
ẩn danh
↓
Cùng tài khoản: IAM policy
một mình đủ
⚠ Đây là điểm khác biệt giữa S3 và KMS: | Dịch vụ | IAM policy một mình đủ (cùng tài khoản) | |---|---| | S3 | ĐỦ | | KMS | KHÔNG — luôn cần key policy |
Luồng credential thật sự:
Instance profile gắn vào EC2
↓
EC2 giả nhận vai trò (nhờ
trust policy)
↓
Credential tạm xuất hiện ở
metadata service
↓
SDK tự lấy và tự làm mới
↓
Gọi S3 với quyền của
permissions policy
Đọc credential từ IMDSv2:
TOKEN=$(curl -sX PUT http://169.254.169.254/latest/api/token \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
⚠ IMDSv2 nên bắt buộc, IMDSv1 là rủi ro SSRF:
aws ec2 modify-instance-metadata-options --instance-id i-0abc \
--http-tokens required --http-put-response-hop-limit 1
IMDSv1: một lời gọi GET đơn giản
→ lỗ hổng SSRF trong ứng dụng
web đọc được credential
↓
IMDSv2: bắt buộc PUT lấy token
trước
→ SSRF thông thường không làm
được
⚠ Và instance profile khác role — chi tiết dễ nhầm:
Instance profile là VỎ BỌC chứa
đúng một role
↓
Console tự tạo profile cùng
tên với role
↓
Dùng CLI thì phải tạo riêng
aws iam create-instance-profile --instance-profile-name vai-tro-ung-dung
aws iam add-role-to-instance-profile \
--instance-profile-name vai-tro-ung-dung --role-name vai-tro-ung-dung
Ba lợi ích của vai trò so với access key: | Lợi ích | Chi tiết | |---|---| | Credential tạm, tự xoay vòng | | | Không có bí mật nào trên đĩa | | | Đổi quyền không cần khởi động lại máy | |
⚠ Và điểm cuối rất tiện trong vận hành:
Sửa permissions policy của vai trò
→ có hiệu lực gần như ngay
↓
Không cần đổi cấu hình, không
cần khởi động lại ứng dụng
Vì sao các phương án khác sai
- **B. Một bucket policy cho phép vai trò EC2 liệt kê object trong bucket — đây là phương án gần nhất và bucket policy thật sự là một cách kiểm soát truy cập S3, nhưng khi vai trò và bucket cùng một tài khoản thì IAM policy một mình đã đủ; bucket policy chỉ bắt buộc cho truy cập liên tài khoản.
- **A. Trust policy cho phép dịch vụ S3 giả nhận vai trò của EC2 — đảo ngược chiều; chính EC2 mới là bên giả nhận vai trò.
- **C. Trust policy cho phép ứng dụng NodeJS truy cập tệp trong S3 — IAM không có khái niệm principal là một ứng dụng; và trust policy không cấp quyền truy cập tài nguyên.
Ghi nhớ
⚠ Hai loại chính sách của một IAM role — bảng phải thuộc: | Loại | Có Principal | Trả lời | |---|---|---| | Trust policy | CÓ | ai giả nhận được | | Permissions policy | không | làm được gì |
Từ khoá nhận diện:
"who can assume the role" → trust policy "what the role can do" → permissions policy "cross-account access to bucket" → cần cả bucket policy "EC2 accessing S3 same account" → chỉ cần role + permissions policy
⚠ Sáu loại principal trong trust policy: | Principal | Ví dụ | |---|---| | Service | ec2.amazonaws.com | | AWS account | arn:aws:iam::111122223333:root | | IAM role/user | arn:aws:iam::...:role/Ten | | Federated (OIDC) | accounts.google.com | | Federated (SAML) | ARN của SAML provider | | * | bất kỳ ai — nguy hiểm |
Ba lưu ý về instance profile: | Lưu ý | Chi tiết | |---|---| | Chứa đúng MỘT role | | | Console tự tạo, CLI phải tạo tay | | | Thay được khi instance đang chạy | |
Ba lưu ý về IMDS: | Lưu ý | Chi tiết | |---|---| | Địa chỉ 169.254.169.254 | | | Bắt buộc IMDSv2 (http-tokens required) | | | Đặt hop-limit 1 để container không đọc được | |
⚠ Hop limit là chi tiết quan trọng với container:
Hop limit mặc định 1
→ container qua bridge network
là 2 hop
→ không đọc được IMDS
↓
Đó là điều MONG MUỐN
→ container nên có vai trò
riêng (IRSA hoặc task role)
Ba lưu ý về quyền tối thiểu: | Lưu ý | Chi tiết | |---|---| | Giới hạn Resource tới đúng bucket và tiền tố | | | Tách ListBucket (trên bucket) và GetObject (trên object) | | | Dùng điều kiện s3:prefix nếu cần | |
⚠ ListBucket và GetObject có Resource khác nhau:
{"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::kho"},
{"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::kho/*"}
Nhầm hai cái này là lỗi rất
phổ biến
→ `ListBucket` trên `kho/*`
không bao giờ khớp
Ba lưu ý về chẩn đoán: | Công cụ | Việc | |---|---| | aws sts get-caller-identity | xem đang là ai | | CloudTrail | xem lời gọi bị từ chối | | Policy Simulator | thử trước khi triển khai |
Ba lưu ý về vai trò cho container: | Nền tảng | Cơ chế | |---|---| | ECS | task role | | EKS | IRSA hoặc Pod Identity | | Lambda | execution role |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | aws sts get-caller-identity trên instance | | | aws s3 ls s3://bucket thử | | | Thử hành động ngoài phạm vi — phải bị từ chối | |
Và một lời khuyên: hãy bắt buộc IMDSv2 trên mọi instance. Một lỗ hổng SSRF trong ứng dụng web biến IMDSv1 thành cửa để lấy credential của vai trò — và vai trò đó thường có quyền rộng hơn nhiều so với những gì kẻ tấn công đáng lẽ chạm tới được.