Ngân hàng đề — AWS Certified Developer Associate
Tìm thấy 1356 câu.
A Developer is creating a social networking app for games that uses a single Amazon DynamoDB table. All users’ saved game data is stored in the single table, but users should not be able to view each other’s data.
How can the Developer restrict user access so they can only view their own data?
-
A
Use separate access keys for each user to call the API and restrict access to specific items based on access key ID
-
B
Read records from DynamoDB and discard irrelevant data client-side
-
C
Use an identity-based policy that restricts read access to the table to specific principals
-
D
Restrict access to specific items based on certain primary key values
Xem giải thích
Đáp án
D — Giới hạn truy cập tới các item cụ thể dựa trên giá trị của primary key.
Vì sao đúng
DynamoDB có một khoá điều kiện IAM dành riêng cho việc này: dynamodb:LeadingKeys. Nó giới hạn người dùng chỉ thao tác được trên item có partition key khớp danh tính của họ:
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:Query"],
"Resource": "arn:aws:dynamodb:ap-southeast-1:123456789012:table/DuLieuGame",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]
}
}
}
Điểm hay nhất: biến ${cognito-identity.amazonaws.com:sub} được thay bằng ID thật của người đăng nhập ngay lúc đánh giá policy. Nên một policy duy nhất phục vụ mọi người dùng, và không ai chạm được vào dữ liệu người khác.
Kết quả:
Người dùng A (sub = abc-123) → chỉ thấy item có user_id = "abc-123"
Người dùng B (sub = def-456) → chỉ thấy item có user_id = "def-456"
Việc lọc diễn ra ở tầng dịch vụ AWS, trước khi dữ liệu rời khỏi DynamoDB — nên nó không thể bị lách bởi mã client.
Và bạn thu hẹp thêm được tới từng cột bằng dynamodb:Attributes:
"dynamodb:Attributes": ["user_id", "diem_so", "cap_do"]
Vì sao các phương án khác sai
- B. Đọc bản ghi từ DynamoDB rồi loại bỏ dữ liệu không liên quan ở phía client — lỗ hổng bảo mật nghiêm trọng: dữ liệu của người khác đã được truyền tới máy client rồi mới bị ẩn. Ai mở DevTools hoặc chặn request đều đọc được. Lọc ở client không bao giờ là biện pháp bảo mật.
- A. Dùng access key riêng cho mỗi người dùng, giới hạn theo access key ID — không mở rộng được: giới hạn 5.000 IAM user mỗi tài khoản, và nhúng access key vào ứng dụng là bị lộ hoàn toàn. Ngoài ra không có khoá điều kiện nào lọc theo access key ID để giới hạn item.
- C. Dùng identity-based policy giới hạn quyền đọc bảng theo principal cụ thể — giới hạn ở mức BẢNG, không phải mức ITEM: nó quyết định ai đọc được bảng, không quyết định đọc được dòng nào.
Ghi nhớ
Các khoá điều kiện dành riêng cho DynamoDB — chúng cho phép phân quyền tới từng dòng và từng cột: | Khoá | Giới hạn | |---|---| | dynamodb:LeadingKeys | chỉ item có partition key khớp | | dynamodb:Attributes | chỉ những thuộc tính được liệt kê | | dynamodb:Select | ép dùng SPECIFIC_ATTRIBUTES | | dynamodb:ReturnValues | giới hạn dữ liệu trả về |
Ba toán tử tập hợp, và chọn đúng rất quan trọng: | Toán tử | Nghĩa | |---|---| | ForAllValues:StringEquals | MỌI giá trị trong request phải nằm trong danh sách cho phép | | ForAnyValue:StringEquals | ít nhất một giá trị khớp — quá lỏng cho mục đích này |
Các biến thay thế theo nguồn danh tính:
${cognito-identity.amazonaws.com:sub} Cognito identity pool
${www.amazon.com:user_id} Login with Amazon
${graph.facebook.com:id} Facebook
${accounts.google.com:sub} Google
${aws:userid} danh tính IAM
Kiến trúc đầy đủ cho ứng dụng di động như đề mô tả:
Người dùng đăng nhập → Cognito User Pool → JWT
↓
Cognito Identity Pool → credential AWS tạm thời (gắn với sub của họ)
↓
Gọi thẳng DynamoDB → policy với LeadingKeys tự lọc theo sub
Cách này không cần backend nào cả — ứng dụng gọi trực tiếp DynamoDB, và AWS đảm bảo cô lập dữ liệu.
Và lưu ý quan trọng: LeadingKeys chỉ hoạt động với Query và GetItem, không hoạt động với Scan — vì Scan không nêu partition key. Nên policy này cũng gián tiếp ngăn người dùng quét cả bảng.
A Developer is migrating Docker containers to Amazon ECS. A large number of containers will be deployed onto an existing ECS cluster that uses container instances of different instance types.
Which task placement strategy can be used to minimize the number of container instances used based on available memory?
-
A
binpack
-
B
spread
-
C
random
-
D
distinctInstance
Xem giải thích
Đáp án
A — binpack.
Vì sao đúng
Đề nêu hai yêu cầu, và cả hai đều là mô tả của binpack:
- Giảm thiểu số container instance được dùng
- Dựa trên bộ nhớ khả dụng
binpack đặt task vào instance đã có ít tài nguyên rảnh nhất nhưng vẫn đủ chỗ — tức là lấp đầy từng máy trước khi động tới máy tiếp theo:
"placementStrategy": [
{"field": "memory", "type": "binpack"}
]
So sánh trực quan với 6 task và 3 instance:
binpack: instance1 [████████] 4 task
instance2 [████ ] 2 task
instance3 [ ] 0 task ← có thể thu hồi, tiết kiệm tiền
spread: instance1 [████ ] 2 task
instance2 [████ ] 2 task
instance3 [████ ] 2 task ← cả ba đều phải chạy
Chọn field theo tài nguyên là nút thắt: | field | Dồn theo | |---|---| | memory | bộ nhớ — đúng yêu cầu của đề | | cpu | đơn vị CPU |
Và chi tiết "instance types khác nhau" trong đề càng làm binpack hợp lý: nó tự tính lượng bộ nhớ còn lại của từng instance cụ thể, nên tận dụng được cả máy lớn lẫn máy nhỏ.
Kết hợp với ECS capacity provider có managed scaling, những instance rỗng sẽ được tự động thu hồi.
Vì sao các phương án khác sai
- B.
spread— mục tiêu ngược lại: rải task đều để tăng tính sẵn sàng. Nó dùng nhiều instance nhất có thể, đúng thứ đề muốn tránh. - C.
random— đặt ngẫu nhiên, không tối ưu gì cả. Kết quả trung bình sẽ dàn trải chứ không dồn chặt. - D.
distinctInstance— không phải strategy mà là CONSTRAINT, và nó có nghĩa ngược hẳn: mỗi instance chỉ được có TỐI ĐA MỘT task. Đó là cách dùng nhiều instance nhất có thể.
Phương án D là bẫy tốt vì nó trộn hai tầng khái niệm của ECS.
Ghi nhớ
Ba strategy của ECS (ưu tiên — sắp xếp): | Type | Mục tiêu | |---|---| | binpack | ít instance nhất — TIẾT KIỆM CHI PHÍ | | spread | phân tán đều — SẴN SÀNG CAO | | random | không mục tiêu cụ thể |
Hai constraint của ECS (bộ lọc — loại bỏ): | Type | Hành vi | |---|---| | distinctInstance | mỗi instance tối đa một task | | memberOf | chỉ instance thoả biểu thức Cluster Query Language |
Khác biệt cốt lõi: strategy là ưu tiên, constraint là bộ lọc. Constraint áp trước để thu hẹp tập ứng viên, rồi strategy mới chọn trong tập đó.
Cách chọn theo từ khoá trong đề: | Đề nói | Chọn | |---|---| | "minimize the number of instances", "reduce cost" | binpack | | "high availability", "distribute evenly" | spread | | "each task on a DIFFERENT instance" | constraint distinctInstance | | "only on instance type X" | constraint memberOf |
Đánh đổi cần cân nhắc trong thực tế: binpack tập trung rủi ro. Nếu instance đang chứa 4 task hỏng, bạn mất 4 task cùng lúc.
Cách dung hoà là kết hợp cả hai theo thứ tự ưu tiên:
"placementStrategy": [
{"field": "attribute:ecs.availability-zone", "type": "spread"},
{"field": "memory", "type": "binpack"}
]
Rải đều giữa các AZ trước (giữ khả năng chịu lỗi AZ), rồi dồn chặt trong mỗi AZ (tiết kiệm máy) — cấu hình rất hay dùng trong thực tế.
A Developer is deploying an Amazon EC2 update using AWS CodeDeploy. In the appspec.yml file, which of the following is a valid structure for the order of hooks that should be specified?
-
A
BeforeBlockTraffic > AfterBlockTraffic > BeforeAllowTraffic > AfterAllowTraffic
-
B
BeforeInstall > AfterInstall > AfterAllowTestTraffic > BeforeAllowTraffic > AfterAllowTraffic
-
C
BeforeInstall > AfterInstall > ApplicationStart > ValidateService
-
D
BeforeAllowTraffic > AfterAllowTraffic
Xem giải thích
Đáp án
C — BeforeInstall → AfterInstall → ApplicationStart → ValidateService.
Vì sao đúng
Đề nói rõ đây là triển khai lên Amazon EC2 — và mỗi nền tảng của CodeDeploy có bộ hook riêng.
Với EC2/On-premises kiểu in-place, các hook phản ánh đúng vòng đời của việc cập nhật phần mềm trên một máy chủ:
ApplicationStop ← dừng ứng dụng đang chạy
DownloadBundle ← (CodeDeploy tự làm, không có hook)
BeforeInstall ← trước khi chép tệp
Install ← (CodeDeploy tự làm)
AfterInstall ← sau khi chép tệp — cấu hình, đặt quyền
ApplicationStart ← khởi động ứng dụng
ValidateService ← kiểm tra ứng dụng chạy đúng
version: 0.0
os: linux
files:
- source: /
destination: /var/www/ung-dung
hooks:
ApplicationStop: [{location: scripts/dung.sh, timeout: 300}]
BeforeInstall: [{location: scripts/sao-luu.sh}]
AfterInstall: [{location: scripts/cai-dat-phu-thuoc.sh}]
ApplicationStart: [{location: scripts/khoi-dong.sh}]
ValidateService: [{location: scripts/kiem-tra.sh, timeout: 300}]
Bốn hook trong đáp án là các hook chính do bạn khai; ApplicationStop cũng có nhưng nó chạy trước tất cả, và ba bước DownloadBundle, Install do CodeDeploy tự thực hiện.
Vì sao các phương án khác sai
- D.
BeforeAllowTraffic→AfterAllowTraffic— bộ hook của AWS Lambda, chỉ có hai. Lambda không có bước cài đặt (version đã tồn tại sẵn) và không có ứng dụng để start/stop. - B.
BeforeInstall→AfterInstall→AfterAllowTestTraffic→BeforeAllowTraffic→AfterAllowTraffic— bộ hook của Amazon ECS. Nhận ra ngay bằngAfterAllowTestTraffic— hook này chỉ có ở ECS. - A.
BeforeBlockTraffic→AfterBlockTraffic→BeforeAllowTraffic→AfterAllowTraffic— bộ hook của EC2/On-premises có load balancer (blue/green hoặc in-place với LB): rút instance khỏi LB, cập nhật, rồi đưa lại vào. Nó là tập bổ sung, không phải bộ hook cơ bản mà đề hỏi.
Ghi nhớ
Bảng hook theo nền tảng — đáng thuộc vì đề hay hỏi: | Nền tảng | Hook | |---|---| | EC2 in-place | ApplicationStop, BeforeInstall, AfterInstall, ApplicationStart, ValidateService | | EC2 với load balancer | thêm BeforeBlockTraffic, AfterBlockTraffic, BeforeAllowTraffic, AfterAllowTraffic | | ECS | BeforeInstall, AfterInstall, AfterAllowTestTraffic, BeforeAllowTraffic, AfterAllowTraffic | | Lambda | BeforeAllowTraffic, AfterAllowTraffic (chỉ hai) |
Ba mẹo nhận dạng nhanh: | Thấy hook | Nền tảng | |---|---| | ApplicationStop / ApplicationStart / ValidateService | EC2/on-premises | | AfterAllowTestTraffic | chỉ có ở ECS | | Chỉ hai hook *AllowTraffic | Lambda |
Một chi tiết quan trọng về ApplicationStop: nó chạy từ revision TRƯỚC ĐÓ, không phải từ revision mới. Nên ở lần triển khai đầu tiên, hook này không chạy (chưa có revision cũ nào). Đây là nguồn của nhiều nhầm lẫn khi gỡ lỗi.
Và AppSpec cho EC2 có hai ràng buộc riêng: | Ràng buộc | Chi tiết | |---|---| | Định dạng | CHỈ YAML (ECS và Lambda thì YAML hoặc JSON) | | Tên và vị trí | appspec.yml ở THƯ MỤC GỐC của gói triển khai |
Sai một trong hai là CodeDeploy báo lỗi không tìm thấy AppSpec — lỗi rất phổ biến khi đóng gói.
An application includes multiple Auto Scaling groups of Amazon EC2 instances. Each group corresponds to a different subdomain of example.com, including forum.example.com and myaccount.example.com. An Elastic Load Balancer will be used to distribute load from a single HTTPS listener.
Which type of Elastic Load Balancer MUST a Developer use in this scenario?
-
A
Classic Load Balancer
-
B
Task Load Balancer
-
C
Network Load Balancer
-
D
Application Load Balancer
Xem giải thích
Đáp án
D — Application Load Balancer.
Vì sao đúng
Đề nêu yêu cầu quyết định: một listener HTTPS duy nhất phải phân phối tải tới nhiều Auto Scaling group khác nhau, mỗi nhóm ứng với một subdomain.
Đó là định tuyến theo nội dung request (host-based routing), và chỉ ALB làm được — vì nó hoạt động ở tầng 7, tức là đọc được HTTP header bao gồm cả Host:
┌─ Host: forum.example.com → target group: forum
Client → ALB :443 ──┼─ Host: myaccount.example.com → target group: myaccount
└─ (mặc định) → target group: web
{
"Conditions": [{"Field": "host-header",
"HostHeaderConfig": {"Values": ["forum.example.com"]}}],
"Actions": [{"Type": "forward", "TargetGroupArn": "arn:...:targetgroup/forum"}],
"Priority": 10
}
Và với một listener HTTPS duy nhất phục vụ nhiều tên miền, ALB còn có SNI: gắn nhiều chứng chỉ ACM trên cùng một listener, ALB tự chọn chứng chỉ đúng theo tên miền client yêu cầu.
Vì sao các phương án khác sai
- C. Network Load Balancer — hoạt động ở tầng 4 (TCP/UDP). Nó không đọc được HTTP header, nên không định tuyến theo hostname được. NLB dùng khi cần thông lượng cực cao, IP tĩnh, hoặc giao thức không phải HTTP.
- A. Classic Load Balancer — thế hệ cũ, không hỗ trợ host-based hay path-based routing. Nó chỉ phân phối tới một nhóm instance duy nhất cho mỗi listener. (AWS đã khuyến nghị chuyển sang ALB hoặc NLB từ lâu.)
- B. "Task Load Balancer" — không tồn tại. AWS có ba loại: Application, Network, và Gateway Load Balancer (cộng với Classic đã cũ).
Ghi nhớ
Bốn loại load balancer của AWS: | Loại | Tầng | Định tuyến theo | Dùng khi | |---|---|---|---| | ALB | 7 | host, path, header, method, query, source IP | HTTP/HTTPS, microservice, nhiều tên miền | | NLB | 4 | cổng | thông lượng cực cao, IP tĩnh, TCP/UDP | | GWLB | 3 | — | thiết bị bảo mật ảo (tường lửa, IDS) | | Classic | 4 và 7 | — | cũ, không dùng cho thiết kế mới |
Các điều kiện định tuyến của ALB listener rule: | Điều kiện | Ví dụ | |---|---| | host-header | forum.example.com, *.example.com | | path-pattern | /api/*, /img/* | | http-header | Cookie, User-Agent, header tuỳ chỉnh | | http-request-method | GET, POST | | query-string | ?version=beta | | source-ip | 203.0.113.0/24 |
Một rule kết hợp tối đa 5 điều kiện, và mỗi ALB có tối đa 100 rule.
Hai chi tiết đáng nhớ về khớp hostname:
*chỉ khớp MỘT nhãn —*.example.comkhớpforum.example.comnhưng không khớpa.b.example.com, và không khớpexample.com.- Muốn phục vụ cả tên miền gốc lẫn subdomain, phải khai hai giá trị:
example.comvà*.example.com.
Và với kiến trúc trong đề, mỗi subdomain trỏ tới một target group riêng — nhưng tất cả dùng chung một ALB, nên bạn chỉ trả phí cho một load balancer thay vì ba.
A solution requires a serverless service for receiving streaming data and loading it directly into an Amazon Elasticsearch datastore. Which AWS service would be suitable for this requirement?
-
A
Amazon Kinesis Data Streams
-
B
Amazon Kinesis Data Analytics
-
C
Amazon Simple Queue Service (SQS)
-
D
Amazon Kinesis Data Firehose
Xem giải thích
Đáp án
D — Amazon Kinesis Data Firehose.
Vì sao đúng
Đề nêu ba yêu cầu, và Firehose khớp cả ba:
- Serverless
- Nhận dữ liệu luồng (streaming data)
- Nạp TRỰC TIẾP vào Amazon OpenSearch (Elasticsearch)
Từ "directly" là chìa khoá: Firehose có OpenSearch làm đích được hỗ trợ sẵn — bạn khai đích và nó tự lo phần còn lại:
aws firehose create-delivery-stream \
--delivery-stream-name nap-vao-opensearch \
--amazon-opensearch-service-destination-configuration '{
"DomainARN": "arn:aws:es:ap-southeast-1:123456789012:domain/tim-kiem",
"IndexName": "nhat-ky",
"RoleARN": "arn:aws:iam::123456789012:role/FirehoseRole",
"BufferingHints": {"SizeInMBs": 5, "IntervalInSeconds": 60},
"S3BackupMode": "FailedDocumentsOnly",
"S3Configuration": {"BucketARN": "arn:aws:s3:::sao-luu-firehose", "RoleARN": "..."}
}'
| Việc | Firehose tự làm |
|---|---|
| Gom lô | theo kích thước hoặc thời gian |
| Thử lại khi lỗi | có backoff |
| Sao lưu bản ghi hỏng | vào S3 (S3BackupMode) |
| Biến đổi bằng Lambda | làm sạch dữ liệu trên đường đi |
| Co giãn | tự động, không có shard nào để quản |
Dòng "sao lưu bản ghi hỏng" đáng chú ý: những document mà OpenSearch từ chối được ghi vào S3 để bạn điều tra — không bị mất im lặng.
Vì sao các phương án khác sai
- A. Kinesis Data Streams — luồng thô, không tự nạp vào đích nào: bạn phải tự viết consumer (KCL hoặc Lambda) để đọc và ghi vào OpenSearch, tự lo gom lô và thử lại. Và nó không serverless hoàn toàn — phải quản lý shard (trừ chế độ on-demand).
- B. Kinesis Data Analytics — PHÂN TÍCH luồng đang chảy bằng SQL hoặc Apache Flink. Nó xử lý dữ liệu, không phải nạp và lưu trữ. Nó thường đứng giữa một stream và một đích, không thay thế được vai trò nạp.
- C. Amazon SQS — hàng đợi tin nhắn, không có đích nào được tích hợp sẵn. Bạn phải tự viết consumer, và nó không phải dịch vụ nạp luồng.
Ghi nhớ
So sánh hai dịch vụ Kinesis hay bị lẫn: | | Data Firehose | Data Streams | |---|---|---| | Mục đích | NẠP vào đích lưu trữ | luồng thô cho nhiều consumer | | Quản lý shard | ❌ không có | ✅ phải tính (trừ on-demand) | | Độ trễ | ~60 giây (gom lô) | dưới giây | | Phát lại | ❌ | ✅ tới 365 ngày | | Nhiều consumer độc lập | ❌ | ✅ | | Tính tiền | theo lượng dữ liệu nạp | theo shard-giờ |
Cách chọn: | Nhu cầu | Chọn | |---|---| | Nạp thẳng vào S3/Redshift/OpenSearch, serverless | Firehose ← câu này | | Dưới giây, nhiều consumer, phát lại được | Data Streams | | Phân tích liên tục trên luồng | Data Analytics / Managed Flink | | Hàng đợi công việc | SQS |
Các đích mà Firehose hỗ trợ: | Đích | Ghi chú | |---|---| | Amazon S3 | phổ biến nhất | | Amazon OpenSearch Service | tìm kiếm và trực quan hoá | | Amazon Redshift | qua S3 rồi COPY | | Splunk, Datadog, New Relic, MongoDB | HTTP endpoint | | Apache Iceberg trên S3 | định dạng bảng mở |
Và một mẫu kiến trúc phổ biến kết hợp cả hai dịch vụ:
Nguồn → Data Streams ─┬→ Firehose → OpenSearch (tìm kiếm)
├→ Firehose → S3 (lưu trữ, Athena)
└→ Lambda → xử lý thời gian thực
Cách này cho cả độ trễ thấp cho xử lý tức thì lẫn nhiều đích lưu trữ — điều mà Firehose một mình không làm được vì nó chỉ có một đích cho mỗi delivery stream.
An Amazon RDS database is experiencing a high volume of read requests that are slowing down the database. Which fully managed, in-memory AWS database service can assist with offloading reads from the RDS database?
-
A
Amazon RDS Read Replica
-
B
Amazon ElastiCache Redis
-
C
Amazon Aurora Serverless
-
D
Memcached on Amazon EC2
Xem giải thích
Đáp án
B — Amazon ElastiCache Redis.
Vì sao đúng
Đề nêu ba yêu cầu, và ElastiCache Redis khớp cả ba:
- Được quản lý hoàn toàn (fully managed)
- CSDL trong bộ nhớ (in-memory)
- Giảm tải đọc cho RDS
Cách nó giảm tải:
Trước: Ứng dụng ──mọi truy vấn đọc──→ RDS (quá tải)
Sau: Ứng dụng ─┬→ ElastiCache (cache hit) → dưới mili giây, KHÔNG chạm RDS
└→ RDS (cache miss) → chỉ khi cần
Với ứng dụng đọc nhiều, tỷ lệ trúng cache thường trên 90% — nghĩa là RDS chỉ còn phải xử lý một phần nhỏ số truy vấn ban đầu.
Và Redis được chọn thay vì Memcached vì nó có nhân bản và tự động failover — quan trọng khi cache trở thành thành phần trọng yếu:
aws elasticache create-replication-group \
--replication-group-id cache-doc \
--engine redis --cache-node-type cache.r6g.large \
--num-node-groups 2 --replicas-per-node-group 2 \
--automatic-failover-enabled --multi-az-enabled
Vì sao các phương án khác sai
- A. Amazon RDS Read Replica — đây là phương án đáng bàn nhất: nó THẬT SỰ giảm tải đọc cho RDS và là giải pháp rất phổ biến. Nhưng nó KHÔNG PHẢI CSDL trong bộ nhớ — nó là một bản sao RDS chạy trên đĩa, nên độ trễ vẫn ở mức mili giây, không phải microsecond. Đề nói rõ "in-memory", và đó là điểm loại.
- D. Memcached trên Amazon EC2 — không được quản lý: bạn phải tự cài, tự vá, tự lo sao lưu, tự dựng failover. Trái yêu cầu "fully managed". (ElastiCache for Memcached thì được quản lý — nhưng phương án nói rõ là chạy trên EC2.)
- C. Amazon Aurora Serverless — là CSDL quan hệ co giãn tự động, không phải cache trong bộ nhớ. Chuyển sang nó nghĩa là di trú cả CSDL, và nó vẫn xử lý truy vấn đọc chứ không giảm tải cho ai.
Ghi nhớ
Ba cách giảm tải đọc cho RDS — thường dùng kết hợp: | Cách | Đặc điểm | |---|---| | ElastiCache | cache trong bộ nhớ, dưới mili giây, không chạm CSDL | | Read replica | bản sao đọc được, tới 15 cái, hỗ trợ mọi truy vấn | | Tối ưu truy vấn và index | rẻ nhất, nên làm trước tiên |
Cách chọn theo từ khoá: | Đề nói | Chọn | |---|---| | "in-memory", "microsecond", "sub-millisecond" | ElastiCache | | "read scaling", "offload reads" (không nêu in-memory) | read replica | | "cần cả hai" | dùng cả hai |
So sánh hai engine của ElastiCache: | | Redis | Memcached | |---|---|---| | Nhân bản, Multi-AZ failover | ✅ | ❌ | | Lưu bền (snapshot, AOF) | ✅ | ❌ | | Mã hoá | ✅ | ❌ | | Cấu trúc dữ liệu | hash, list, set, sorted set, stream | chỉ chuỗi | | Đa luồng | Redis 6+ có I/O đa luồng | ✅ đầy đủ |
Quy tắc: hễ đề nhắc tới sẵn sàng cao, failover, mã hoá, hay bền vững ⇒ Redis.
Và ba chiến lược cache cần biết khi triển khai: | Chiến lược | Đặc điểm | |---|---| | Lazy loading | cache nhỏ (chỉ dữ liệu được đọc), nhưng có dữ liệu cũ | | Write-through | luôn mới, nhưng cache phình to | | Cache invalidation | xoá mục khi ghi — kết hợp với lazy loading là mẫu tốt nhất |
Trong thực tế, mẫu phổ biến nhất là lazy loading + TTL + invalidation khi ghi — vừa giữ cache nhỏ vừa tránh dữ liệu lỗi thời.
(Lưu ý: Valkey — bản fork mã nguồn mở của Redis — hiện cũng được ElastiCache hỗ trợ và thường rẻ hơn, với cùng bộ tính năng.)
A Developer has created a task definition that includes the following JSON code:
"placementConstraints": [
{
"expression": "attribute:ecs.instance-type =~ t2.*",
"type": "memberOf"
}
]
What will be the effect for tasks using this task definition?
-
A
They will be added to distinct instances using the T2 instance type
-
B
They will be spread across all instances except for T2 instances
-
C
They will be placed only on container instances of T2 or T3 instance types
-
D
They will be placed only on container instances using the T2 instance type
Xem giải thích
Đáp án
D — Task sẽ chỉ được đặt lên container instance dùng instance type T2.
Vì sao đúng
Đọc từng phần của cấu hình:
{
"expression": "attribute:ecs.instance-type =~ t2.*",
"type": "memberOf"
}
| Phần | Nghĩa |
|---|---|
type: memberOf |
BỘ LỌC — chỉ chấp nhận instance thoả biểu thức |
attribute:ecs.instance-type |
thuộc tính dựng sẵn: loại instance |
=~ |
toán tử khớp biểu thức chính quy |
t2.* |
bắt đầu bằng t2. |
Ghép lại: chỉ đặt task lên instance có loại bắt đầu bằng t2. — tức là t2.micro, t2.small, t2.medium, t2.large…
Đây là ràng buộc tuyệt đối: nếu không có instance T2 nào trống, task ở trạng thái PENDING thay vì được đặt lên máy khác.
Vì sao các phương án khác sai
- C. Chỉ đặt trên instance T2 hoặc T3 — sai vì biểu thức chỉ khớp
t2.. Muốn khớp cả hai họ thì phải viếtt[23].*hoặc dùng toán tửin. - B. Rải trên mọi instance TRỪ T2 — đảo ngược ý nghĩa:
memberOflà bao gồm, không phải loại trừ. Muốn loại trừ thì dùng!=hoặcnot_in. - A. Đặt trên các instance riêng biệt (distinct) dùng T2 — thêm một ràng buộc không có trong cấu hình:
distinctInstancelà một constraint riêng, và nó không xuất hiện ở đây. Cấu hình này cho phép nhiều task trên cùng một instance T2.
Ghi nhớ
Hai constraint của ECS (bộ lọc): | Type | Hành vi | |---|---| | distinctInstance | mỗi instance tối đa một task | | memberOf | chỉ instance thoả biểu thức Cluster Query Language |
Các toán tử của Cluster Query Language: | Toán tử | Nghĩa | Ví dụ | |---|---|---| | ==, != | bằng, khác | attribute:ecs.os-type == linux | | >, <, >=, <= | so sánh số | attribute:ecs.cpu-architecture | | =~ | khớp biểu thức chính quy | attribute:ecs.instance-type =~ t2.* | | !~ | không khớp regex | | | in, not_in | thuộc/không thuộc tập | attribute:ecs.availability-zone in [ap-southeast-1a, ap-southeast-1c] | | exists, not_exists | có/không có thuộc tính | attribute:loai-may exists |
Các thuộc tính dựng sẵn hay dùng:
attribute:ecs.instance-type t3.medium
attribute:ecs.availability-zone ap-southeast-1a
attribute:ecs.os-type linux | windows
attribute:ecs.cpu-architecture x86_64 | arm64
attribute:ecs.ami-id ami-xxxxx
Và bạn tự gắn thuộc tính tuỳ chỉnh được:
aws ecs put-attributes --cluster cum-chinh \
--attributes name=loai-may,value=csdl,targetId=<arn-container-instance>
Ba strategy của ECS (ưu tiên — khác với constraint): | Type | Mục tiêu | |---|---| | spread | rải đều — sẵn sàng cao | | binpack | dồn chặt — tiết kiệm chi phí | | random | ngẫu nhiên |
Thứ tự áp dụng: constraint chạy trước để thu hẹp tập ứng viên, rồi strategy mới chọn trong tập đó — nên hai cơ chế kết hợp được. Và với Fargate, cả hai đều không dùng được vì không có instance nào để lọc.
The manager of a development team is setting up a shared S3 bucket for team members. The manager would like to use a single policy to allow each user to have access to their objects in the S3 bucket. Which feature can be used to generalize the policy?
-
A
Principal
-
B
Resource
-
C
Condition
-
D
Variable
Xem giải thích
Đáp án
D — Variable (biến thay thế trong policy).
Vì sao đúng
Yêu cầu: một policy duy nhất cho phép mỗi người dùng chỉ truy cập object của chính mình.
IAM policy variable làm đúng điều đó — nó là chỗ giữ chỗ được thay bằng giá trị thật ngay lúc đánh giá policy:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::kho-chung/${aws:username}/*"
}]
}
Khi Nguyễn Văn A gọi API, AWS thay ${aws:username} bằng nguyen-van-a:
Nguyễn Văn A → arn:aws:s3:::kho-chung/nguyen-van-a/* ✓
Trần Thị B → arn:aws:s3:::kho-chung/tran-thi-b/* ✓
Một policy phục vụ cả đội, và không ai chạm được vào thư mục người khác. Thêm người mới chỉ cần đưa vào group — không phải viết policy mới.
Đó chính là nghĩa của "generalize the policy" trong đề.
Vì sao các phương án khác sai
- A.
Principal— khai AI được cấp quyền, và nó chỉ có trong resource-based policy. Muốn dùng nó để phân biệt từng người thì phải liệt kê từng người — ngược hẳn với việc "khái quát hoá". - B.
Resource— khai tài nguyên nào. Nó là nơi biến được ĐẶT VÀO, nhưng bản thân nó không phải cơ chế khái quát hoá. Không có biến thì bạn phải viết ARN cụ thể cho từng người. - C.
Condition— thêm điều kiện để statement có hiệu lực (IP nguồn, MFA, thời gian). Nó thu hẹp quyền theo ngữ cảnh, nhưng không tự động thay thế giá trị theo người dùng. (Biến vẫn dùng được bên trongCondition— nhưng cơ chế khái quát hoá là biến, không phảiCondition.)
Ghi nhớ
Các biến thay thế hay dùng trong IAM policy: | Biến | Giá trị | |---|---| | ${aws:username} | tên IAM user | | ${aws:userid} | ID duy nhất của danh tính | | ${aws:PrincipalTag/ten-tag} | giá trị tag gắn vào principal | | ${cognito-identity.amazonaws.com:sub} | ID người dùng Cognito | | ${saml:sub} | danh tính SAML | | ${www.amazon.com:user_id} | Login with Amazon |
Biến dùng được ở hai chỗ:
// Trong Resource
"Resource": "arn:aws:s3:::kho-chung/${aws:username}/*"
// Trong Condition
"Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}}
Và với S3, để người dùng liệt kê được thư mục của mình cần thêm một statement ở mức bucket:
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::kho-chung",
"Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}}
}
Đây là điểm hay bị bỏ sót: ListBucket là action ở mức BUCKET (ARN không có /*), còn GetObject ở mức object (ARN có /*).
Ba lưu ý khi dùng policy variable:
- Chỉ hoạt động với
Version: "2012-10-17"— phiên bản cũ hơn không hỗ trợ. ${aws:username}không có giá trị với IAM role — với role thì dùng${aws:userid}hoặc tag-based access control (${aws:PrincipalTag/...}).- Tên user chứa ký tự đặc biệt có thể gây bất ngờ — nên đặt quy ước tên đơn giản.
Cùng cơ chế này áp cho DynamoDB với dynamodb:LeadingKeys — cho phép mỗi người chỉ đọc dòng của chính mình bằng một policy duy nhất.
A website delivers images stored in an Amazon S3 bucket. The site uses Amazon Cognito-enabled and guest users without logins need to be able to view the images from the S3 bucket..
How can a Developer enable access for guest users to the AWS resources?
-
A
Create a new user pool, disable authentication access, and grant access to AWS resources
-
B
Create a new identity pool, enable access to unauthenticated identities, and grant access to AWS resources
-
C
Create a new user pool, enable access to unauthenticated identities, and grant access to AWS resources
-
D
Create a blank user ID in a user pool, add to the user group, and grant access to AWS resources
Xem giải thích
Đáp án
B — Tạo một identity pool mới, bật truy cập cho unauthenticated identities, và cấp quyền vào tài nguyên AWS.
Vì sao đúng
Đề có một dữ kiện quyết định: người dùng khách KHÔNG đăng nhập, nhưng vẫn cần xem ảnh trong S3.
Chỉ identity pool có khái niệm người dùng chưa xác thực (unauthenticated) — user pool thì không:
Ứng dụng mở lên (không ai đăng nhập)
↓
Identity Pool cấp identity ID cho thiết bị đó
↓ sts:AssumeRoleWithWebIdentity
Credential AWS TẠM THỜI với quyền của UNAUTHENTICATED ROLE
↓
Gọi s3:GetObject trong phạm vi cho phép
// Không có 'logins' — nghĩa là người dùng khách
const credentials = fromCognitoIdentityPool({
identityPoolId: 'ap-southeast-1:xxxx-xxxx'
});
const s3 = new S3Client({ credentials });
Identity pool có hai role riêng biệt, và bạn cấu hình quyền khác nhau cho mỗi loại: | Role | Cho ai | Quyền | |---|---|---| | Unauthenticated | người dùng khách | tối thiểu — chỉ ảnh công khai | | Authenticated | người đã đăng nhập | rộng hơn |
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::kho-anh/cong-khai/*"
}
Vì sao các phương án khác sai
- C. Tạo user pool mới và bật truy cập cho unauthenticated identities — user pool KHÔNG có khái niệm unauthenticated: nó là thư mục người dùng, mọi người trong đó đều phải có tài khoản. Thiết lập này không tồn tại.
- A. Tạo user pool mới, tắt xác thực, rồi cấp quyền — không có thiết lập "tắt xác thực" cho user pool. Và kể cả nếu có, user pool chỉ phát ra JWT — nó không cấp credential AWS để gọi S3.
- D. Tạo một user ID trống trong user pool, thêm vào group, rồi cấp quyền — cách làm chắp vá và không an toàn: bạn sẽ phải chia sẻ một tài khoản chung cho mọi khách, mất hết khả năng truy vết, và vẫn vướng vấn đề user pool không cấp credential AWS.
Ghi nhớ
| User Pool | Identity Pool | |
|---|---|---|
| Là gì | thư mục người dùng | bộ đổi danh tính lấy credential AWS |
| Phát ra | JWT | credential AWS tạm thời |
| Người dùng khách | ❌ | ✅ unauthenticated role |
| Gọi thẳng S3/DynamoDB | ❌ | ✅ |
| Chức năng | đăng ký, đăng nhập, MFA, quên mật khẩu | cấp quyền vào dịch vụ AWS |
Cách chọn: | Đề nói | Chọn | |---|---| | "guest users", "without logins", "unauthenticated" | identity pool ← câu này | | "đăng ký, đăng nhập, quản lý người dùng" | user pool | | cả hai nhu cầu | dùng cả hai |
Cảnh báo quan trọng về unauthenticated role: nó cấp credential cho bất kỳ ai trên Internet — chỉ cần biết identity pool ID, vốn nằm trong mã ứng dụng và ai cũng đọc được. Nên:
- Giữ quyền ở mức tối thiểu tuyệt đối — chỉ đọc, chỉ đúng prefix công khai.
- Không bao giờ cấp quyền ghi cho role này.
- Tắt hẳn unauthenticated access nếu ứng dụng không thực sự cần chế độ khách.
Và một cách thay thế đáng cân nhắc cho bài toán này: nếu ảnh hoàn toàn công khai, dùng CloudFront + S3 với Origin Access Control còn đơn giản và rẻ hơn — không cần Cognito chút nào. Cognito identity pool chỉ cần thiết khi bạn muốn phân biệt khách với người đã đăng nhập và cho họ quyền khác nhau.
A Java based application generates email notifications to customers using Amazon SNS. The emails must contain links to access data in a secured Amazon S3 bucket. What is the SIMPLEST way to maintain security of the bucket whilst allowing the customers to access specific objects?
-
A
Use the AWS SDK for Java to update the bucket Access Control List to allow the customers to access the bucket
-
B
Use the AWS SDK for Java with
GeneratePresignedUrlRequestto create a presigned URL -
C
Use the AWS SDK for Java with the AWS STS service to gain temporary security credentials
-
D
Use the AWS SDK for Java to assume a role with AssumeRole to gain temporary security credentials
Xem giải thích
Đáp án
B — Dùng AWS SDK for Java với GeneratePresignedUrlRequest để tạo pre-signed URL.
Vì sao đúng
Yêu cầu: bucket vẫn được bảo mật, nhưng khách hàng truy cập được object cụ thể qua link trong email — với cách ĐƠN GIẢN NHẤT.
Pre-signed URL làm đúng việc đó: một URL mang chữ ký và thời hạn, cho phép tải đúng một object mà không cần mở bucket ra công khai và không cần người nhận có tài khoản AWS:
Date hetHan = new Date(System.currentTimeMillis() + 3600 * 1000); // 1 giờ
GeneratePresignedUrlRequest request =
new GeneratePresignedUrlRequest("kho-bao-mat", "bao-cao/khach-123.pdf")
.withMethod(HttpMethod.GET)
.withExpiration(hetHan);
URL url = s3Client.generatePresignedUrl(request);
snsClient.publish(topicArn, "Báo cáo của bạn: " + url);
| Đặc điểm | Chi tiết |
|---|---|
| Bucket vẫn riêng tư | không mở public chút nào |
| Có thời hạn | tối đa 7 ngày với SigV4 |
| Quyền kế thừa | không vượt quá quyền của bên tạo URL |
| Người nhận | không cần tài khoản AWS |
| Công sức | một lời gọi SDK |
Dòng cuối là lý do nó là cách "SIMPLEST": khách hàng chỉ việc bấm vào link trong email — không đăng nhập, không cài gì.
Vì sao các phương án khác sai
- C. Dùng AWS STS lấy credential tạm thời và D. Dùng
AssumeRolelấy credential tạm thời — cả hai đều đòi khách hàng có công cụ để DÙNG credential AWS: họ phải cài AWS CLI hoặc SDK, cấu hình credential, rồi gọi API. Với khách hàng cuối nhận email, đó là rào cản không thể chấp nhận được. - A. Cập nhật Access Control List của bucket để cho khách hàng truy cập — sai vì ba lẽ: ACL cấp quyền cho danh tính AWS, mà khách hàng không có; nó không có thời hạn; và từ tháng 4/2023, AWS tắt ACL theo mặc định cho bucket mới, khiến chúng hoàn toàn không có tác dụng.
Ghi nhớ
Các cơ chế kiểm soát truy cập S3, theo phạm vi: | Cơ chế | Phạm vi | Thời hạn | Người nhận cần tài khoản AWS? | |---|---|---|---| | Pre-signed URL | một object, một người | có, tối đa 7 ngày | ❌ KHÔNG | | Bucket policy | cả bucket hoặc prefix | tĩnh | thường có | | IAM policy | theo danh tính AWS | tĩnh | ✅ CÓ | | CloudFront signed URL/cookie | qua CDN | có, kèm giới hạn IP | ❌ | | ACL | từng object | không | ✅ (và đã lỗi thời) |
So sánh hai loại signed URL: | | S3 pre-signed | CloudFront signed | |---|---|---| | Tạo bằng | credential IAM | cặp khoá riêng | | Thời hạn tối đa | 7 ngày | không giới hạn | | Giới hạn theo IP | ❌ | ✅ | | Qua CDN | ❌ | ✅ nhanh hơn cho tệp lớn | | Signed cookie (nhiều tệp) | ❌ | ✅ |
Ba lưu ý khi dùng pre-signed URL:
- Thời hạn kế thừa từ credential tạo URL. URL tạo bằng credential tạm thời của một role sẽ hết hiệu lực khi credential đó hết hạn — thường sớm hơn
Expirationbạn đặt. Với link gửi qua email cần sống lâu, hãy tạo bằng credential dài hạn hoặc dùng CloudFront signed URL. - Đặt thời hạn ngắn nhất chấp nhận được — URL bị chuyển tiếp thì ai cầm cũng dùng được trong khoảng đó.
- Sinh URL ở phía máy chủ, không bao giờ để logic ký nằm trong mã client.
Và mẹo hiệu năng: dùng pre-signed URL cho PutObject để client tải tệp thẳng lên S3 — tránh giới hạn payload và giảm tải cho máy chủ.