Ngân hàng đề — AWS Certified Developer Associate
Tìm thấy 1356 câu.
A developer has created a Docker image and uploaded it to an Amazon Elastic Container Registry (ECR) repository. How can the developer pull the image to his workstation using the docker client?
-
A
Run
aws ecr get-login-passworduse the output to login in then issue adocker pullcommand specifying the image name usingregistry/repository[:tag] -
B
Run
aws ecr describe-images --repository-name repositoryname -
C
Run
docker loginwith an IAM key pair then issue a docker pull command specifying the image name usingregistry/repository[@digest] -
D
Run the
docker pullcommand specifying the image name usingregistry/repository[:tag]
Xem giải thích
Đáp án
A — Chạy aws ecr get-login-password, dùng kết quả để đăng nhập, rồi chạy docker pull với tên image dạng registry/repository[:tag].
Vì sao đúng
ECR là registry riêng tư, nên phải xác thực trước khi kéo image. Và nó không nhận thông tin xác thực AWS trực tiếp — nó cần một token tạm thời có hạn 12 giờ, đổi từ IAM.
Quy trình đúng gồm hai bước:
# 1. Lấy token và đưa cho Docker
aws ecr get-login-password --region ap-southeast-1 | \
docker login --username AWS --password-stdin \
123456789012.dkr.ecr.ap-southeast-1.amazonaws.com
# 2. Kéo image
docker pull 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/ung-dung:v1.2.3
Chi tiết quan trọng: get-login-password chỉ IN RA một chuỗi token — nó không tự đăng nhập. Bạn phải đưa chuỗi đó cho docker login, thường bằng cách nối ống (|) như trên.
Định dạng URI của ECR:
<account-id>.dkr.ecr.<region>.amazonaws.com/<repository>:<tag>
Vì sao các phương án khác sai
- D. Chỉ chạy
docker pull— thiếu hẳn bước đăng nhập. Với repository riêng tư, kết quả là lỗino basic auth credentials. - C. Chạy
docker loginvới một cặp khoá IAM — ECR KHÔNG nhận access key làm mật khẩu Docker. Nó chỉ nhận token tạm thời lấy từget-login-password. Đây là bẫy hợp lý nhất trong các phương án sai. - B. Chạy
aws ecr describe-images --repository-name— chỉ liệt kê thông tin về các image trong repository (tag, digest, kích thước, ngày đẩy). Nó không kéo image nào về máy.
Ghi nhớ
Quy trình đầy đủ với ECR:
# Đăng nhập (token sống 12 giờ)
aws ecr get-login-password --region <region> | \
docker login --username AWS --password-stdin $ECR_URI
# Kéo về
docker pull $ECR_URI/ung-dung:v1
# Đẩy lên
docker tag ung-dung:latest $ECR_URI/ung-dung:v2
docker push $ECR_URI/ung-dung:v2
Quyền IAM cần cho từng thao tác: | Thao tác | Quyền | |---|---| | Đăng nhập | ecr:GetAuthorizationToken (bắt buộc Resource: "*") | | Kéo | BatchGetImage, GetDownloadUrlForLayer, BatchCheckLayerAvailability | | Đẩy | thêm InitiateLayerUpload, UploadLayerPart, CompleteLayerUpload, PutImage |
ecr:GetAuthorizationToken là quyền bị bỏ sót nhiều nhất — thiếu nó thì hỏng ngay từ bước docker login, và thông báo lỗi không nói rõ nguyên nhân.
Hai cách tham chiếu image: | Dạng | Ví dụ | Đặc điểm | |---|---|---| | Tag | ung-dung:v1.2.3 | dễ đọc, nhưng tag có thể bị ghi đè | | Digest | ung-dung@sha256:abc123... | bất biến tuyệt đối |
Với production, digest an toàn hơn — nó đảm bảo bạn chạy đúng image đã kiểm thử, kể cả khi ai đó đẩy lại cùng tag.
(Ghi chú về cú pháp cũ: aws ecr get-login --no-include-email là lệnh của AWS CLI v1 — nó in ra nguyên một lệnh docker login để chạy bằng $(...). CLI v2 đã bỏ lệnh này và thay bằng get-login-password, an toàn hơn vì token không xuất hiện trong lịch sử shell.)
A Developer is creating an application that uses Amazon EC2 instances and must be highly available and fault tolerant. How should the Developer configure the VPC?
-
A
Create an Internet Gateway for every availability zone
-
B
Create a subnet in each availability zone in the region
-
C
Create a cluster placement group for the EC2 instances
-
D
Create multiple subnets within a single availability zone in the region
Xem giải thích
Đáp án
B — Tạo một subnet ở mỗi Availability Zone trong Region.
Vì sao đúng
Nguyên tắc nền tảng của tính sẵn sàng cao trên AWS: trải tài nguyên qua nhiều Availability Zone.
Mỗi AZ là một hoặc nhiều trung tâm dữ liệu riêng biệt, có nguồn điện, làm mát và mạng độc lập. Một AZ sập không kéo theo AZ khác.
Và điểm mấu chốt về VPC: subnet nằm trong đúng MỘT AZ. Nên muốn đặt instance ở nhiều AZ, bạn bắt buộc phải có subnet ở mỗi AZ đó:
VPC (10.0.0.0/16)
├── subnet-a (10.0.1.0/24) → ap-southeast-1a ← EC2 ở đây
├── subnet-b (10.0.2.0/24) → ap-southeast-1b ← và ở đây
└── subnet-c (10.0.3.0/24) → ap-southeast-1c ← và ở đây
Từ đó mới dựng được kiến trúc chịu lỗi:
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name nhom-ung-dung \
--vpc-zone-identifier "subnet-a,subnet-b,subnet-c" \
--min-size 2 --max-size 10 --desired-capacity 3 \
--health-check-type ELB --health-check-grace-period 300
ASG tự rải instance đều giữa các AZ và tự thay thế khi có máy hỏng.
Vì sao các phương án khác sai
- D. Tạo nhiều subnet trong MỘT AZ — không cải thiện tính sẵn sàng chút nào: mọi subnet đó nằm trong cùng một AZ, nên AZ sập là mất hết. Nhiều subnet trong một AZ chỉ dùng để phân tách về mặt mạng (public/private, theo tầng ứng dụng).
- A. Tạo Internet Gateway cho mỗi AZ — không làm được và không cần: mỗi VPC chỉ có MỘT Internet Gateway, và nó đã sẵn sàng cao và dư thừa theo thiết kế — AWS quản lý, không có điểm hỏng đơn lẻ. (NAT Gateway thì ngược lại — nó nằm trong một AZ, nên cần một cái mỗi AZ nếu muốn chịu lỗi.)
- C. Tạo cluster placement group — đi ngược mục tiêu: cluster placement group dồn instance vào cùng một rack để có băng thông cao và độ trễ thấp giữa chúng (dùng cho HPC). Nó tăng rủi ro tương quan — một sự cố phần cứng ảnh hưởng tất cả.
Ghi nhớ
Phạm vi của các tài nguyên trong VPC: | Tài nguyên | Phạm vi | |---|---| | VPC | Region | | Subnet | MỘT AZ | | Internet Gateway | VPC (đã dư thừa sẵn) | | NAT Gateway | MỘT AZ — cần một cái mỗi AZ để chịu lỗi | | Route table | VPC (gắn vào subnet) | | Security group | VPC |
Dòng NAT Gateway đáng nhớ: nhiều người trải subnet qua ba AZ nhưng chỉ đặt một NAT Gateway — và khi AZ chứa NAT đó sập, cả ba AZ đều mất Internet.
Ba loại placement group — chọn theo mục tiêu: | Loại | Mục tiêu | |---|---| | Cluster | độ trễ thấp, băng thông cao — CÙNG một rack | | Spread | tách instance ra phần cứng khác nhau — chịu lỗi tối đa | | Partition | nhóm instance theo phân vùng phần cứng — cho HDFS, Cassandra |
Danh sách kiểm cho kiến trúc VPC sẵn sàng cao:
- Subnet ở tối thiểu 2 AZ (nên 3)
- ASG trải qua các subnet đó,
min-size ≥ 2 - ALB bật đủ các AZ — thiếu bước này thì instance ở AZ mới không nhận traffic
- NAT Gateway ở mỗi AZ kèm route table riêng cho từng private subnet
HealthCheckType: ELBđể ASG thay cả máy có ứng dụng chết- RDS Multi-AZ cho tầng dữ liệu
A developer is creating a multi-tier web application. The front-end will place messages in an Amazon SQS queue for the back-end to process. Each job includes a file that is 1GB in size. What MUST the developer do to ensure this works as expected?
-
A
Store the large files in DynamoDB and use the SQS Extended Client Library for Java to manage SQS messages
-
B
Store the large files in Amazon S3 and use the SQS Extended Client Library for Java to manage SQS messages
-
C
Create a FIFO queue that supports large files
-
D
Increase the maximum message size of the queue from 256KB to 1GB
Xem giải thích
Đáp án
B — Lưu tệp lớn trên Amazon S3 và dùng SQS Extended Client Library for Java để quản lý message.
Vì sao đúng
Vấn đề: mỗi công việc kèm một tệp 1 GB, nhưng SQS giới hạn message ở 256 KB.
SQS Extended Client Library giải quyết bằng mẫu claim check: lưu payload lớn ở nơi khác, chỉ gửi con trỏ qua hàng đợi:
Producer → tải tệp 1 GB lên S3
→ gửi message chứa {bucket, key} vào SQS ← chỉ vài trăm byte
↓
Consumer → đọc message → lấy con trỏ → tải tệp từ S3
Thư viện làm việc này hoàn toàn trong suốt với mã ứng dụng:
AmazonSQSExtendedClient sqsExtended = new AmazonSQSExtendedClient(
AmazonSQSClientBuilder.defaultClient(),
new ExtendedClientConfiguration()
.withPayloadSupportEnabled(s3Client, "kho-payload")
.withAlwaysThroughS3(true)
);
// Gửi như message thường — thư viện tự đẩy payload lên S3
sqsExtended.sendMessage(new SendMessageRequest(queueUrl, noiDungRatLon));
// Nhận cũng như thường — thư viện tự tải từ S3 về
List<Message> messages = sqsExtended.receiveMessage(receiveRequest).getMessages();
Nó còn tự xoá object trên S3 khi message được xoá khỏi hàng đợi — nên không để lại rác.
Vì sao các phương án khác sai
- D. Tăng kích thước message tối đa của hàng đợi từ 256 KB lên 1 GB — không làm được: 256 KB là giới hạn CỨNG của SQS, không cấu hình vượt qua được.
MaximumMessageSizechỉ chỉnh được trong khoảng 1 KB đến 256 KB. - A. Lưu tệp lớn trong DynamoDB rồi dùng Extended Client Library — DynamoDB giới hạn item 400 KB, còn nhỏ hơn cả nhu cầu. Và thư viện này chỉ hỗ trợ S3 làm kho lưu trữ payload.
- C. Tạo FIFO queue "hỗ trợ tệp lớn" — FIFO không thay đổi giới hạn kích thước: nó vẫn là 256 KB. FIFO khác standard queue ở thứ tự và khử trùng lặp, không ở dung lượng.
Ghi nhớ
Các giới hạn của SQS: | Giới hạn | Giá trị | |---|---| | Kích thước message | 256 KB (cứng) | | Số message trong hàng đợi | không giới hạn | | Thời gian giữ | 60 giây – 14 ngày | | SendMessageBatch | 10 message, tổng 256 KB | | Thông lượng standard queue | gần như không giới hạn | | Thông lượng FIFO | 300 message/giây (3.000 với batching) |
Mẫu claim check — đáng nhớ vì nó áp dụng cho nhiều dịch vụ, không riêng SQS:
Payload lớn → S3
Message nhỏ chứa con trỏ → SQS / SNS / EventBridge / Step Functions
Ba dịch vụ có thư viện extended client tương tự: | Dịch vụ | Giới hạn gốc | Thư viện | |---|---|---| | SQS | 256 KB | SQS Extended Client (Java, Python) | | SNS | 256 KB | SNS Extended Client | | Step Functions | 256 KB mỗi state | dùng con trỏ S3 thủ công |
Và một cách khác cho cùng bài toán, đáng cân nhắc: bỏ hẳn SQS ở bước này và dùng S3 Event Notification — khi tệp được tải lên, S3 tự phát sự kiện gọi Lambda hoặc đẩy vào SQS:
Producer → tải tệp lên S3 → S3 event → SQS → Consumer
Cách này đơn giản hơn vì không cần thư viện đặc biệt, và bên gửi chỉ làm một việc là tải tệp lên.
Chọn cách nào tuỳ tình huống: Extended Client khi bên gửi cần kiểm soát nội dung message; S3 event khi việc tải tệp lên chính là sự kiện cần xử lý.
An organization has encrypted a large quantity of data. To protect their data encryption keys they are planning to use envelope encryption. Which of the following processes is a correct implementation of envelope encryption?
-
A
Encrypt plaintext data with a data key and then encrypt the data key with a top-level encrypted master key
-
B
Encrypt plaintext data with a data key and then encrypt the data key with a top-level plaintext master key.
-
C
Encrypt plaintext data with a master key and then encrypt the master key with a top-level plaintext data key
-
D
Encrypt plaintext data with a master key and then encrypt the master key with a top-level encrypted data key
Xem giải thích
Đáp án
B — Mã hoá dữ liệu bản rõ bằng data key, rồi mã hoá data key đó bằng master key ở dạng bản rõ.
Vì sao đúng
Envelope encryption là mẫu hai lớp khoá, và thứ tự rất quan trọng:
1. GenerateDataKey → KMS trả về: data key BẢN RÕ + data key ĐÃ MÃ HOÁ
2. Mã hoá dữ liệu lớn bằng data key BẢN RÕ (AES-256, tại chỗ)
3. XOÁ data key bản rõ khỏi bộ nhớ
4. Lưu: dữ liệu đã mã hoá + data key đã mã hoá
Điểm cần đọc kỹ trong phương án B: "top-level plaintext master key". Cụm này không có nghĩa là master key nằm ở dạng bản rõ trong tay bạn — nó mô tả vai trò của master key trong cấu trúc phân cấp: đó là khoá ở tầng cao nhất, và nó thực hiện việc mã hoá (chứ không phải bị mã hoá bởi khoá khác).
Với KMS, master key (CMK) không bao giờ rời khỏi dịch vụ — chính KMS dùng nó để mã hoá data key và trả về CiphertextBlob:
r = kms.generate_data_key(KeyId='alias/khoa-cua-toi', KeySpec='AES_256')
khoa_ban_ro = r['Plaintext'] # ← mã hoá dữ liệu bằng cái này
khoa_ban_ma = r['CiphertextBlob'] # ← chính là data key ĐÃ ĐƯỢC master key mã hoá
du_lieu_ma = ma_hoa_aes(du_lieu, khoa_ban_ro)
del khoa_ban_ro # xoá ngay
luu(du_lieu_ma, khoa_ban_ma)
Chiều ngược lại khi giải mã: gọi kms:Decrypt trên khoa_ban_ma (nhỏ, dưới 4 KB) để lấy lại data key, rồi dùng nó giải mã dữ liệu.
Vì sao các phương án khác sai
- A. Mã hoá dữ liệu bằng data key, rồi mã hoá data key bằng master key đã được mã hoá — sai về mặt logic: một khoá đã bị mã hoá thì không dùng để mã hoá gì được — nó chỉ là dữ liệu vô nghĩa cho tới khi được giải mã. Đây là bẫy tinh vi nhất, chỉ khác đáp án đúng một từ.
- C và D. Mã hoá dữ liệu bằng master key, rồi mã hoá master key bằng data key — đảo ngược hoàn toàn vai trò hai khoá. Và nó phá vỡ chính lý do envelope encryption tồn tại: master key có giới hạn 4 KB và không bao giờ rời khỏi KMS, nên không thể dùng nó mã hoá "một khối lượng lớn dữ liệu".
Ghi nhớ
Cấu trúc phân cấp khoá trong envelope encryption:
Master key (CMK) ← ở tầng CAO NHẤT, không bao giờ rời KMS
↓ mã hoá
Data key ← mã hoá dữ liệu, lưu ở dạng ĐÃ MÃ HOÁ
↓ mã hoá
Dữ liệu lớn
Ba lợi ích của mẫu này: | Lợi ích | Chi tiết | |---|---| | Không giới hạn kích thước | dữ liệu không đi qua mạng tới KMS | | Nhanh | AES cục bộ, không chờ mạng cho từng khối | | Thu hồi được | vô hiệu hoá CMK là mọi data key thành vô dụng |
Điểm cuối rất mạnh về mặt bảo mật: bạn không cần tìm và xoá từng data key — chỉ cần vô hiệu hoá một CMK là toàn bộ dữ liệu được bảo vệ bởi nó trở nên không giải mã được.
| API của KMS | Dùng khi | Giới hạn |
|---|---|---|
Encrypt |
dữ liệu nhỏ, khoá, mật khẩu | ≤ 4 KB |
GenerateDataKey |
dữ liệu lớn — envelope encryption | không giới hạn |
GenerateDataKeyWithoutPlaintext |
tạo sẵn khoá để dùng sau | — |
Decrypt |
giải mã data key | ≤ 4 KB |
Ba nguyên tắc khi cài đặt:
- Xoá data key bản rõ khỏi bộ nhớ ngay sau khi dùng.
- Lưu data key đã mã hoá cùng dữ liệu — mất nó là mất dữ liệu vĩnh viễn.
- Dùng encryption context để ràng buộc khoá với ngữ cảnh và có vết kiểm toán trong CloudTrail.
Và nhớ: SDK của S3, EBS, RDS và nhiều dịch vụ AWS đã tự làm envelope encryption bên dưới — bạn chỉ chỉ định CMK và không phải viết đoạn mã này.
A company is reviewing their security practices. According to AWS best practice how should access keys be managed to improve security? (Select TWO.)
-
A
Embed access keys directly into code
-
B
Use different access keys for different applications
-
C
Use the same access key in all applications for consistency
-
D
Rotate access keys daily
-
E
Delete all access keys for the root account IAM user
Xem giải thích
Đáp án
B và E.
- B — Dùng access key khác nhau cho các ứng dụng khác nhau
- E — Xoá mọi access key của tài khoản root
Vì sao đúng
B — mỗi ứng dụng một access key riêng. Đây là nguyên tắc cô lập phạm vi ảnh hưởng:
| Lợi ích | Chi tiết |
|---|---|
| Thu hồi độc lập | key của ứng dụng A bị lộ ⇒ xoá nó mà không ảnh hưởng B, C |
| Truy vết rõ ràng | CloudTrail cho biết chính xác ứng dụng nào gọi API nào |
| Đặc quyền tối thiểu | mỗi key gắn với danh tính chỉ có quyền nó cần |
| Xoay vòng độc lập | không phải cập nhật đồng loạt mọi ứng dụng |
E — xoá access key của tài khoản root. Đây là khuyến nghị bảo mật số một của AWS:
Root account có toàn quyền không giới hạn và không thể bị hạn chế bởi IAM policy hay SCP. Access key của nó bị lộ nghĩa là mất toàn bộ tài khoản — kẻ tấn công đóng được tài khoản, đổi phương thức thanh toán, xoá mọi thứ.
# Kiểm tra tài khoản root có access key không
aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'
# Trả về 0 là tốt, 1 là phải xử lý ngay
AWS khuyến nghị: tài khoản root chỉ dùng cho vài tác vụ bắt buộc (đổi phương thức thanh toán, đóng tài khoản, một số thay đổi ở cấp tổ chức), luôn bật MFA, và không bao giờ có access key.
Vì sao các phương án khác sai
- C. Dùng CÙNG một access key cho mọi ứng dụng để nhất quán — ngược hẳn với B: một key bị lộ là mọi ứng dụng phải đổi cùng lúc, và CloudTrail không phân biệt được ứng dụng nào đã làm gì.
- A. Nhúng access key trực tiếp vào mã — sai lầm bảo mật nghiêm trọng nhất: key nằm trong lịch sử Git vĩnh viễn, ai đọc được kho mã đều thấy. Đây là nguyên nhân của rất nhiều vụ lộ credential thực tế.
- D. Xoay vòng access key HẰNG NGÀY — quá cực đoan và phản tác dụng: gánh nặng vận hành rất lớn, và mỗi lần xoay vòng là một cơ hội gây gián đoạn. AWS khuyến nghị xoay vòng định kỳ hợp lý (thường 90 ngày), không phải hằng ngày. (Và giải pháp đúng hơn là loại bỏ hẳn access key.)
Ghi nhớ
Nguyên tắc quan trọng nhất về access key: ứng dụng chạy trên AWS thì KHÔNG BAO GIỜ dùng access key dài hạn. | Nơi chạy | Cơ chế thay thế | |---|---| | EC2 | instance profile | | Lambda | execution role | | ECS / Fargate | task role | | EKS | IAM Roles for Service Accounts (IRSA) | | Máy chủ on-premises | IAM Roles Anywhere, SSM hybrid activation | | Máy của lập trình viên | IAM Identity Center (SSO) |
Dòng cuối cùng đáng chú ý: kể cả lập trình viên cũng không cần access key nữa — SSO cấp credential tạm thời tự hết hạn.
Danh sách kiểm bảo mật cho IAM: | Nên | Không nên | |---|---| | Xoá access key của root, bật MFA cho root | để root có access key | | Dùng role cho ứng dụng | nhúng key vào mã | | Mỗi ứng dụng một danh tính riêng | dùng chung một key | | Gán quyền qua group | gán trực tiếp cho từng user | | Đặc quyền tối thiểu | cấp * cho tiện | | Xoay vòng key định kỳ (90 ngày) | giữ key nhiều năm, hoặc xoay hằng ngày |
Ba công cụ giúp phát hiện vấn đề: | Công cụ | Việc | |---|---| | IAM Credential Report | danh sách mọi credential và lần dùng cuối | | IAM Access Advisor | dịch vụ nào thật sự được dùng trong 400 ngày qua | | AWS Config rule | tự động cảnh báo khi có key quá cũ hoặc root có key |
Và AWS có một cơ chế bảo vệ tự động: khi phát hiện access key bị đăng công khai trên GitHub, AWS tự áp policy cách ly và gửi email cảnh báo — nhưng đừng trông vào nó.
An Amazon ElastiCache cluster has been placed in front of a large Amazon RDS database. To reduce cost the ElastiCache cluster should only cache items that are actually requested. How should ElastiCache be optimized?
-
A
Use a lazy loading caching strategy
-
B
Only cache database writes
-
C
Use a write-through caching strategy
-
D
Enable a TTL on cached data
Xem giải thích
Đáp án
A — Dùng chiến lược lazy loading.
Vì sao đúng
Đề nêu yêu cầu rất cụ thể: giảm chi phí, và cache chỉ chứa những item THỰC SỰ được yêu cầu.
Lazy loading (cache-aside) làm đúng điều đó — nó chỉ nạp vào cache khi có người đọc mà không thấy:
def doc(khoa):
gia_tri = cache.get(khoa)
if gia_tri is None: # CACHE MISS
gia_tri = csdl.get(khoa) # đọc từ RDS
cache.setex(khoa, 3600, gia_tri) # nạp vào cache
return gia_tri
Hệ quả trực tiếp: item chưa từng được đọc thì không bao giờ vào cache. Với một CSDL lớn mà chỉ một phần nhỏ dữ liệu được truy vấn thường xuyên, điều này tiết kiệm rất nhiều:
CSDL có 10 triệu bản ghi
Chỉ khoảng 50.000 bản ghi được đọc thường xuyên
⇒ Cache chỉ cần chứa 50.000 mục thay vì 10 triệu
⇒ Node cache nhỏ hơn nhiều lần, chi phí thấp hơn nhiều lần
Vì ElastiCache tính tiền theo kích thước node, đây là khác biệt rất lớn về hoá đơn.
Đánh đổi cần biết: | Nhược điểm | Chi tiết | |---|---| | Cache miss penalty | lần đọc đầu tiên chậm (phải xuống CSDL) | | Dữ liệu có thể cũ | cache không tự cập nhật khi CSDL đổi | | Cache mới tạo thì trống | phải "làm ấm" dần |
Vì sao các phương án khác sai
- C. Dùng write-through caching — ngược hẳn yêu cầu: nó ghi vào cache ở MỌI lần ghi CSDL, nên cache chứa cả những dữ liệu không ai đọc bao giờ. Đó chính là thứ làm cache phình to và tốn kém — điều đề muốn tránh.
- D. Bật TTL cho dữ liệu trong cache — thực hành tốt và nên làm, nhưng nó là cơ chế dọn dẹp, không phải chiến lược nạp. TTL quyết định dữ liệu ở lại bao lâu, không quyết định cái gì được đưa vào. (Trong thực tế, TTL thường dùng kèm lazy loading.)
- B. "Chỉ cache các lần ghi vào CSDL" — chính là mô tả của write-through, nên cùng vấn đề với C.
Ghi nhớ
So sánh ba chiến lược cache: | Chiến lược | Nạp vào cache khi | Kích thước cache | Dữ liệu cũ | |---|---|---|---| | Lazy loading | sau một lần đọc miss | nhỏ — chỉ dữ liệu được đọc | có, tới khi TTL hết | | Write-through | mỗi lần ghi CSDL | lớn — chứa cả dữ liệu không ai đọc | không | | Write-behind | cache trước, CSDL sau | lớn | không (nhưng rủi ro mất dữ liệu) |
Cách chọn theo từ khoá trong đề: | Đề nhấn mạnh | Chọn | |---|---| | "giảm chi phí", "chỉ cache item được yêu cầu" | lazy loading ← câu này | | "real-time", "dữ liệu phải luôn mới", "mọi item" | write-through | | Hỏi nhược điểm của lazy loading | cache miss penalty, dữ liệu cũ | | Hỏi nhược điểm của write-through | cache phình to, tốn tiền |
Mẫu thực hành tốt nhất trong sản xuất là kết hợp cả ba:
def doc(khoa):
gt = cache.get(khoa)
if gt is None: # lazy loading
gt = csdl.get(khoa)
cache.setex(khoa, 3600, gt) # + TTL
return gt
def ghi(khoa, gia_tri):
csdl.update(khoa, gia_tri)
cache.delete(khoa) # invalidation — tránh dữ liệu cũ
Cách này giữ được ưu điểm của lazy loading (cache nhỏ) mà loại bỏ vấn đề dữ liệu cũ — xoá mục khi ghi, để lần đọc sau nạp lại giá trị mới.
Và ba tham số nên cấu hình cho ElastiCache: maxmemory-policy (thường là allkeys-lru), TTL hợp lý cho từng loại dữ liệu, và giám sát CacheHitRate — tỷ lệ trúng thấp nghĩa là cache đang không mang lại lợi ích tương xứng chi phí.
A Developer is creating a script to automate the deployment process for a serverless application. The Developer wants to use an existing AWS Serverless Application Model (SAM) template for the application.
What should the Developer use for the project? (Select TWO.)
-
A
Create a ZIP package and upload it to Amazon S3. Call
aws cloudformation create-stackto create the application -
B
Call
sam packageto create the deployment package. Callsam deployto deploy the package afterward -
C
Call
aws s3 cpto upload the AWS SAM template to Amazon S3. Callaws lambda update-function-codeto create the application -
D
Call
aws cloudformation packageto create the deployment package. Callaws cloudformationdeploy to deploy the package afterward -
E
Create a ZIP package locally and call
aws serverlessrepo create-applicationto create the application
Xem giải thích
Đáp án
B và D.
- B —
sam packagerồisam deploy - D —
aws cloudformation packagerồiaws cloudformation deploy
Vì sao đúng
Template SAM khai mã nguồn bằng đường dẫn cục bộ (CodeUri: ./src), mà CloudFormation chỉ đọc mã từ S3. Nên phải có bước đóng gói và tải lên trước khi triển khai.
Có hai bộ lệnh tương đương làm việc đó.
D — bộ lệnh của CloudFormation:
aws cloudformation package \
--template-file template.yaml \
--s3-bucket kho-trien-khai \
--output-template-file da-dong-goi.yaml
aws cloudformation deploy \
--template-file da-dong-goi.yaml \
--stack-name ung-dung --capabilities CAPABILITY_IAM
B — bộ lệnh của SAM CLI:
sam package --output-template-file da-dong-goi.yaml --s3-bucket kho-trien-khai
sam deploy --template-file da-dong-goi.yaml --stack-name ung-dung --capabilities CAPABILITY_IAM
Cả hai làm cùng ba việc: nén thư mục mã, tải lên S3 với tên là mã băm nội dung, và sinh template mới với CodeUri trỏ tới đường dẫn S3.
(Việc dùng mã băm làm tên object rất tiện: mã không đổi thì tên không đổi, nên CloudFormation biết là không cần cập nhật hàm.)
Vì sao các phương án khác sai
- A. Tạo ZIP, tải lên S3, rồi gọi
aws cloudformation create-stack— bỏ qua bước biến đổi template:CodeUrivẫn trỏ vào đường dẫn cục bộ, nên CloudFormation không tìm thấy mã. Bạn phải tự sửa template trỏ vào S3 — tức là làm thủ công việc màpackagelàm sẵn. - C. Tải template SAM lên S3 rồi gọi
aws lambda update-function-code— nhầm hai thứ:update-function-codecập nhật mã của một hàm ĐÃ TỒN TẠI, nó không tạo stack và không hiểu template SAM. Và tải template lên S3 không có tác dụng gì — thứ cần tải lên là mã nguồn. - E. Tạo ZIP cục bộ rồi gọi
aws serverlessrepo create-application— sai mục đích: Serverless Application Repository là nơi CHIA SẺ ứng dụng serverless cho người khác dùng lại, không phải cách triển khai ứng dụng của bạn lên tài khoản của chính bạn.
Ghi nhớ
Đối chiếu hai bộ lệnh: | CloudFormation CLI | SAM CLI | |---|---| | aws cloudformation package | sam package | | aws cloudformation deploy | sam deploy | | — | sam build (biên dịch, cài phụ thuộc) | | — | sam local invoke (chạy cục bộ) |
Quy trình gọn nhất trong thực tế chỉ hai lệnh — SAM CLI tự tạo bucket và nhớ cấu hình:
sam build
sam deploy --guided # lần đầu; sau đó chỉ cần: sam deploy
Hai dòng bắt buộc ở đầu template SAM:
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31' # ← thiếu là SAM không hoạt động
Transform báo cho CloudFormation biến đổi cú pháp SAM thành tài nguyên thật — thiếu nó, AWS::Serverless::Function bị coi là loại tài nguyên không tồn tại.
Các tài nguyên mà lệnh package xử lý: | Tài nguyên | Thuộc tính được thay | |---|---| | AWS::Serverless::Function | CodeUri | | AWS::Lambda::Function | Code | | AWS::Serverless::Api | DefinitionUri | | AWS::Serverless::LayerVersion | ContentUri | | AWS::CloudFormation::Stack | TemplateURL |
Và nhớ --capabilities CAPABILITY_IAM ở bước deploy: template tạo IAM role nên CloudFormation đòi xác nhận tường minh — thiếu là lỗi ngay.
A developer is building a Docker application on Amazon ECS that will use an Application Load Balancer (ALB). The developer needs to configure the port mapping between the host port and container port. Where is this setting configured?
-
A
Container instance
-
B
Task definition
-
C
Host definition
-
D
Service scheduler
Xem giải thích
Đáp án
B — Task definition.
Vì sao đúng
Ánh xạ cổng được khai trong portMappings của container definition, và container definition nằm bên trong task definition:
{
"family": "ung-dung-web",
"containerDefinitions": [{
"name": "web",
"image": "...ecr.../app:v1",
"portMappings": [
{"containerPort": 80, "hostPort": 0, "protocol": "tcp"}
]
}]
}
Task definition mô tả container chạy như thế nào — image, CPU, bộ nhớ, biến môi trường, log, và ánh xạ cổng. Đó là "bản thiết kế" của container.
Với ALB, cấu hình phổ biến nhất là hostPort: 0 — kích hoạt dynamic port mapping:
Task 1: host:32768 → container:80
Task 2: host:32770 → container:80
Task 3: host:41234 → container:80
ECS tự chọn cổng còn trống trong dải ephemeral (32768–60999), nên chạy được nhiều task của cùng một service trên một instance mà không xung đột. ECS cũng báo cho ALB biết cổng động thực tế khi đăng ký target.
Điều kiện đi kèm: security group của instance phải mở dải ephemeral cho security group của ALB — quên bước này là mọi target đều unhealthy mà không rõ lý do.
Vì sao các phương án khác sai
- A. Container instance — là máy EC2 chạy ECS agent. Bạn cấu hình security group và IAM role ở đó, nhưng không cấu hình ánh xạ cổng của container.
- D. Service scheduler — quyết định bao nhiêu task chạy, ở đâu, và duy trì số lượng đó. Nó dùng thông tin từ task definition, nhưng không định nghĩa nó.
- C. "Host definition" — không tồn tại khái niệm này trong ECS.
Ghi nhớ
Phân biệt hai khái niệm cốt lõi của ECS — nhầm chỗ này là lỗi rất phổ biến: | | Task definition | Service definition | |---|---|---| | Mô tả | container chạy THẾ NÀO | bao nhiêu bản sao, Ở ĐÂU | | Nội dung | image, CPU, bộ nhớ, portMappings, biến môi trường, log, task role | desired count, load balancer, placement, deployment config |
Hành vi cổng theo network mode: | Network mode | hostPort | Ghi chú | |---|---|---| | bridge | 0 = động, hoặc cố định | mặc định trên EC2 | | awsvpc | phải bằng containerPort | mỗi task có ENI và IP riêng | | host | phải bằng containerPort | dùng thẳng mạng của host | | none | — | không có mạng ngoài |
Với Fargate, network mode luôn là awsvpc — mỗi task có IP riêng nên không có xung đột cổng, và câu hỏi về dynamic port mapping chỉ phát sinh với EC2 launch type + bridge mode.
Ba loại role của ECS, cũng khai trong task definition (trừ cái cuối): | Role | Ai dùng | Cho việc gì | |---|---|---| | Task role | mã trong container | gọi S3, DynamoDB… | | Task execution role | ECS agent | kéo image từ ECR, ghi log, đọc secret | | Instance profile | ECS agent trên host | đăng ký instance vào cluster |
Và xu hướng hiện nay là dùng awsvpc cả trên EC2: mỗi task có ENI và security group riêng, nên bảo mật rõ ràng hơn và không cần dynamic port mapping. Đổi lại, số ENI trên mỗi instance có giới hạn — dù ENI trunking nới rộng đáng kể.
A manufacturing company is creating a new RESTful API that their customers can use to query the status of orders. The endpoint for customer queries will be https://www.manufacturerdomain.com/status/customerID
Which of the following application designs will meet the requirements? (Select TWO.)
-
A
Elastic Load Balancing; Amazon EC2
-
B
Amazon S3; Amazon CloudFront
-
C
Amazon ElastiCache; Amazon Elacticsearch Service
-
D
Amazon API Gateway; AWS Lambda
-
E
Amazon SQS; Amazon SNS
Xem giải thích
Đáp án
A và D.
- D — API Gateway + AWS Lambda
- A — Elastic Load Balancing + Amazon EC2
Vì sao đúng
Đề mô tả một RESTful API phục vụ truy vấn trạng thái đơn hàng, với endpoint dạng:
https://www.manufacturerdomain.com/status/customerID
Đó là API động — mỗi customerID cho một kết quả khác nhau, được tính từ dữ liệu. Nên kiến trúc phải có tầng tính toán chạy mã.
D — API Gateway + Lambda (serverless):
Client → API Gateway (/status/{customerID}) → Lambda → truy vấn CSDL → trả JSON
| Đặc điểm | Chi tiết |
|---|---|
| Trả tiền theo request | không có máy chạy không |
| Tự co giãn | không cấu hình |
| Path parameter dựng sẵn | /status/{customerID} |
| Tên miền riêng | qua custom domain name + ACM |
A — ELB + EC2 (truyền thống):
Client → ALB (path /status/*) → EC2 chạy ứng dụng web → trả JSON
Phù hợp khi cần kiểm soát runtime, di trú ứng dụng có sẵn, hoặc tải cao và đều (khi đó rẻ hơn tính theo request).
Cả hai đều là kiến trúc web nhiều tầng đúng chuẩn, đáp ứng được yêu cầu.
Vì sao các phương án khác sai
- B. Amazon S3 + CloudFront — chỉ phục vụ được nội dung TĨNH. Nó không chạy mã, nên không tính được trạng thái đơn hàng theo từng khách hàng. (Trừ khi bạn sinh sẵn một tệp JSON cho mỗi khách hàng — nhưng đó không phải RESTful API và không cập nhật được theo thời gian thực.)
- C. ElastiCache + Elasticsearch Service — hai dịch vụ lưu trữ và tìm kiếm dữ liệu, không phải cửa ngõ API. Chúng có thể là thành phần phía sau một API, nhưng không tự phục vụ được request HTTP từ khách hàng.
- E. SQS + SNS — hai dịch vụ nhắn tin bất đồng bộ. RESTful API cần phản hồi ĐỒNG BỘ — khách hàng gửi request và chờ kết quả ngay. SQS và SNS không làm được điều đó.
Ghi nhớ
Một kiến trúc API luôn cần đủ ba tầng: | Tầng | Lựa chọn | |---|---| | Cửa ngõ | API Gateway, ALB, CloudFront | | Tính toán | Lambda, ECS/Fargate, EC2 trong ASG | | Dữ liệu | DynamoDB, RDS, Aurora, ElastiCache |
Thiếu tầng tính toán thì không có API — đó là điểm loại của B, C và E.
So sánh hai cửa ngõ trong đáp án: | | API Gateway | ALB | |---|---|---| | Chi phí | theo request, không phí cố định | phí giờ cố định + LCU | | Điểm hoà vốn | rẻ hơn khi tải thấp tới trung bình | rẻ hơn khi tải rất cao và đều | | Tính năng | throttling, caching, authorizer, usage plan, request validation | định tuyến theo host/path, WAF | | Đích | Lambda, HTTP, dịch vụ AWS, VPC link | EC2, ECS, Lambda, IP |
Và với endpoint có tên miền riêng như đề mô tả, cả hai đều làm được: | Cách | Cấu hình | |---|---| | API Gateway | custom domain name + chứng chỉ ACM + Route 53 alias | | ALB | chứng chỉ ACM trên listener + Route 53 alias |
Lưu ý về Region của chứng chỉ ACM: với API Gateway edge-optimized và CloudFront, chứng chỉ bắt buộc ở us-east-1; với regional endpoint và ALB thì cùng Region với tài nguyên.
Nhận dạng nhanh: đề mô tả RESTful API ⇒ đáp án phải có cửa ngõ HTTP + tầng tính toán. Mọi phương án chỉ có kho lưu trữ hoặc chỉ có dịch vụ nhắn tin đều sai.
An Auto Scaling Group (ASG) of Amazon EC2 instances is being created for processing messages from an Amazon SQS queue. To ensure the EC2 instances are cost-effective a Developer would like to configure the ASG to maintain aggregate CPU utilization at 70%.
Which type of scaling policy should the Developer choose?
-
A
Step Scaling Policy
-
B
Target Tracking Scaling Policy
-
C
Simple Scaling Policy
-
D
Scheduled Scaling Policy
Xem giải thích
Đáp án
B — Target Tracking Scaling Policy.
Vì sao đúng
Đề mô tả chính xác cách target tracking hoạt động: duy trì một metric ở một giá trị mục tiêu — ở đây là CPU trung bình 70%.
Bạn chỉ khai con số mục tiêu, và AWS lo phần còn lại:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name nhom-xu-ly \
--policy-name giu-cpu-70 \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {"PredefinedMetricType": "ASGAverageCPUUtilization"},
"TargetValue": 70.0
}'
Auto Scaling tự tạo và quản lý các CloudWatch alarm cần thiết, tự tính cần thêm bớt bao nhiêu instance, và tự điều chỉnh:
CPU trung bình lên 85% → thêm instance cho tới khi về gần 70%
CPU trung bình xuống 40% → bớt instance cho tới khi về gần 70%
Vì sao nó phù hợp với yêu cầu tiết kiệm chi phí trong đề: nó giữ mức sử dụng cao mà không quá tải — không để máy chạy ở 20% CPU (lãng phí) cũng không để chạm 100% (quá tải).
Ba đặc điểm đáng chú ý: | Đặc điểm | Chi tiết | |---|---| | Đơn giản nhất | chỉ khai một con số | | Tự quản alarm | không phải tạo và bảo trì alarm nào | | Thận trọng khi scale-in | ưu tiên tính sẵn sàng — giảm chậm hơn tăng |
Vì sao các phương án khác sai
- A. Step Scaling Policy — mạnh hơn nhưng cần cấu hình nhiều hơn hẳn: bạn phải tự tạo CloudWatch alarm và khai từng bậc hành động:
Nó hữu ích khi cần phản ứng khác nhau theo mức độ vượt ngưỡng, nhưng đề chỉ nói "duy trì ở 70%" — đó là target tracking.CPU 70–80% → thêm 1 instance CPU 80–90% → thêm 2 instance CPU > 90% → thêm 4 instance - C. Simple Scaling Policy — cách cũ nhất: một alarm, một hành động, rồi chờ hết cooldown mới làm gì tiếp. Nó phản ứng chậm và AWS khuyến nghị dùng target tracking hoặc step scaling thay thế.
- D. Scheduled Scaling Policy — co giãn theo lịch cố định (ví dụ tăng lúc 8 giờ sáng, giảm lúc 18 giờ). Nó không phản ứng với metric, nên không "duy trì CPU ở 70%" được.
Ghi nhớ
Bốn loại chính sách co giãn: | Loại | Cách hoạt động | Cấu hình | |---|---|---| | Target tracking | giữ metric ở mức mục tiêu | đơn giản nhất — một con số | | Step scaling | thêm/bớt theo bậc tuỳ mức vượt | phải tự tạo alarm và khai từng bậc | | Simple scaling | một hành động, có cooldown | cũ, phản ứng chậm | | Scheduled | theo lịch — biết trước giờ cao điểm | khai lịch | | Predictive | học mẫu tải rồi chuẩn bị TRƯỚC | bật là chạy |
Các metric dựng sẵn cho target tracking: | Metric | Dùng khi | |---|---| | ASGAverageCPUUtilization | tải phụ thuộc CPU ← câu này | | ASGAverageNetworkIn / NetworkOut | tải phụ thuộc mạng | | ALBRequestCountPerTarget | số request mỗi instance |
Và với kiến trúc trong đề (xử lý message từ SQS), có một metric tuỳ chỉnh thường tốt hơn CPU: độ dài hàng đợi:
--target-tracking-configuration '{
"CustomizedMetricSpecification": {
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Dimensions": [{"Name":"QueueName","Value":"hang-doi-xu-ly"}],
"Statistic": "Average"},
"TargetValue": 100}'
Lý do: độ dài hàng đợi phản ánh công việc tồn đọng trực tiếp, còn CPU là chỉ báo trễ — nó chỉ tăng sau khi instance đã bắt đầu quá tải.
Ba lưu ý khi cấu hình target tracking:
- Kết hợp nhiều policy được — Auto Scaling chọn hành động cho số instance lớn nhất, ưu tiên tính sẵn sàng.
DisableScaleIn: truenếu muốn chỉ tăng mà không tự giảm.- Đặt
min-sizehợp lý — target tracking không bao giờ giảm xuống dưới mức đó.