Ngân hàng đề — AWS Certified Developer Associate
Tìm thấy 1356 câu.
An application is using Amazon DynamoDB as its data store and needs to be able to read 100 items per second as strongly consistent reads. Each item is 5 KB in size.
What value should be set for the table's provisioned throughput for reads?
-
A
50 Read Capacity Units
-
B
200 Read Capacity Units
-
C
500 Read Capacity Units
-
D
250 Read Capacity Units
Xem giải thích
Đáp án
B — 200 Read Capacity Units.
Vì sao đúng
Phép tính RCU gồm ba bước, và bước đầu tiên là chỗ hay sai nhất.
Bước 1 — làm tròn LÊN bội số của 4 KB:
Item 5 KB → 5 / 4 = 1,25 → làm tròn lên → 2 đơn vị
Đây là điểm mấu chốt: item 5 KB tốn đúng như item 8 KB. DynamoDB không tính theo phần lẻ.
Bước 2 — nhân với hệ số theo loại đọc: | Loại đọc | Hệ số | |---|---| | Strongly consistent | × 1 | | Eventually consistent | × 0,5 | | Transactional | × 2 |
Đề yêu cầu strongly consistent:
2 đơn vị × 1 = 2 RCU cho mỗi lần đọc
Bước 3 — nhân với số lần đọc mỗi giây:
2 RCU × 100 lần/giây = 200 RCU
Vì sao các phương án khác sai
- A. 50 — kết quả nếu quên làm tròn lên và dùng eventually consistent:
1,25 × 0,5 × 100 ≈ 62, hoặc100 × 0,5 = 50nếu tính nhầm item vừa 4 KB. - D. 250 — có thể do dùng
5/4 = 1,25rồi nhân× 2 × 100, tức là làm tròn sai chỗ. - C. 500 — có thể do nhân với transactional read (× 2) trên nền 250, hoặc tính
5 KB × 100rồi chia sai.
Ghi nhớ
Hai công thức cần thuộc, và chúng không đối xứng:
RCU — đơn vị 4 KB:
Strongly consistent : ceil(size / 4 KB) × số_lần_đọc
Eventually consistent: ceil(size / 4 KB) ÷ 2 × số_lần_đọc
Transactional : ceil(size / 4 KB) × 2 × số_lần_đọc
WCU — đơn vị 1 KB:
Ghi thường : ceil(size / 1 KB) × số_lần_ghi
Transactional : ceil(size / 1 KB) × 2 × số_lần_ghi
Ba lỗi phổ biến nhất khi làm dạng bài này:
- Nhầm đơn vị: RCU dùng 4 KB, WCU dùng 1 KB.
- Quên làm tròn LÊN: item 4,1 KB tốn như 8 KB.
- Bỏ qua chữ "strongly" hay "eventually" trong đề — nó quyết định nhân hay chia đôi.
Áp lại bài này để kiểm tra: 5 KB → làm tròn lên 2 đơn vị → strongly nên × 1 → 2 RCU/lần → 100 lần/giây → 200 RCU. Nếu đề đổi thành eventually consistent thì đáp án sẽ là 100 RCU.
Và một ghi chú thực tế: với bảng có tải khó dự đoán, on-demand mode loại bỏ hẳn việc tính toán này — bạn chỉ trả tiền theo số request thật. Đổi lại là đơn giá cao hơn khi tải đều đặn.
AWS CodeBuild builds code for an application, creates a Docker image, pushes the image to Amazon Elastic Container Registry (ECR), and tags the image with a unique identifier.
If the Developers already have AWS CLI configured on their workstations, how can the Docker images be pulled to the workstations?
-
A
Run the following:
docker pull REPOSITORY URI : TAG -
B
Run the output of the following:
aws ecr get-download-url-for-layer, and then run:docker pull REPOSITORY URI : TAG -
C
Run the following:
aws ecr get-login-password, and then run:docker pull REPOSITORY URI : TAG -
D
Run the output of the following:
aws ecr get-login-password, and then run:docker pull REPOSITORY URI : TAG
Xem giải thích
Đáp án
D — Chạy kết quả đầu ra của aws ecr get-login-password, rồi chạy docker pull REPOSITORY_URI:TAG.
Vì sao đúng
ECR là registry riêng tư, nên phải xác thực trước khi kéo image. Nhưng ECR 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
Điểm phân biệt của phương án D nằm ở ba chữ "the output of": 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
- C. Chạy
aws ecr get-login-passwordrồi chạydocker pull— đây là bẫy chính, và nó chỉ khác đáp án đúng ở cụm "the output of". Chạy lệnh đó một mình chỉ in token ra màn hình — Docker không hề biết gì về nó, vàdocker pullsẽ thất bại với lỗi xác thực. - A. 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. - B. Chạy kết quả của
aws ecr get-download-url-for-layerrồidocker pull— API này có thật nhưng dùng ở tầng thấp: nó trả về URL đã ký để tải một layer cụ thể, phục vụ cho các công cụ tự cài đặt giao thức registry. Nó không thay thế đượcdocker login, và người dùng thông thường không bao giờ gọi tới.
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.
(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 hoàn chỉnh để 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.)
An application is running on an Amazon EC2 Linux instance. The instance needs to make AWS API calls to several AWS services. What is the MOST secure way to provide access to the AWS services with MINIMAL management overhead?
-
A
Use AWS KMS to store and retrieve credentials
-
B
Use EC2 instance profiles
-
C
Store the credentials in AWS CloudHSM
-
D
Store the credentials in the ~/.aws/credentials file
Xem giải thích
Đáp án
B — Dùng EC2 instance profile.
Vì sao đúng
Đề đòi hai thứ cùng lúc: an toàn nhất và ít công sức quản lý nhất — và instance profile thắng ở cả hai.
Instance profile là vỏ bọc chứa một IAM role, gắn vào EC2 instance. Ứng dụng trên máy đó tự động nhận credential tạm thời qua Instance Metadata Service:
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=UngDungWebProfile
Từ đó AWS SDK tự tìm và dùng credential — mã ứng dụng không cần biết gì:
import boto3
s3 = boto3.client('s3') # SDK tự lấy credential từ metadata service
Vì sao đây là cách an toàn nhất: | Lợi ích | Chi tiết | |---|---| | Không có credential dài hạn nào | không có access key nằm trên đĩa hay trong mã | | Tự động xoay vòng | AWS làm mới credential trước khi hết hạn | | Không thể bị commit nhầm vào Git | không có gì để commit | | Đổi quyền tức thì | sửa policy của role, có hiệu lực ngay, không phải triển khai lại | | Vết kiểm toán rõ | CloudTrail ghi cả role lẫn instance |
Và vế "minimal management overhead": bạn không phải tạo, phân phối, hay xoay vòng bất cứ khoá nào.
Vì sao các phương án khác sai
- D. Lưu credential trong tệp
~/.aws/credentials— kém an toàn nhất: đó là access key dài hạn nằm trên đĩa. Ai đọc được ổ đĩa (hoặc snapshot của nó, hoặc AMI tạo từ nó) là có credential. Cộng thêm gánh nặng xoay vòng thủ công định kỳ. - A. Dùng KMS để lưu và lấy credential — sai chức năng: KMS quản lý KHOÁ MÃ HOÁ, không phải kho lưu trữ bí mật. Bạn có thể dùng KMS để mã hoá credential rồi lưu nơi khác, nhưng khi đó vẫn còn credential dài hạn, và cần credential nào đó để gọi KMS — vòng luẩn quẩn.
- C. Lưu credential trong CloudHSM — CloudHSM là module bảo mật phần cứng cho khoá mã hoá, dùng khi có yêu cầu tuân thủ FIPS 140-2 Level 3. Nó đắt, phức tạp vận hành, và vẫn không giải quyết vấn đề "có credential dài hạn phải bảo vệ".
Ghi nhớ
Nguyên tắc bao trùm: ứng dụng chạy trên AWS thì KHÔNG BAO GIỜ dùng access key dài hạn. Luôn dùng role phù hợp với nơi mã chạy: | Nơi chạy | Cơ chế | |---|---| | 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 hoặc SSM hybrid activation | | Máy của lập trình viên | IAM Identity Center (SSO), hoặc profile với MFA |
Dòng cuối cùng đáng chú ý: kể cả ngoài AWS, giờ cũng có cách tránh access key dài hạn.
Một khuyến nghị bảo mật quan trọng cho EC2: bắt buộc dùng IMDSv2, vốn yêu cầu token và chống được tấn công SSRF lấy credential từ metadata service:
aws ec2 modify-instance-metadata-options \
--instance-id i-xxx --http-tokens required --http-endpoint enabled
Đây là biện pháp một dòng, và nó chặn được một trong những đường tấn công phổ biến nhất vào ứng dụng web trên EC2.
A developer is creating a microservices application that includes and AWS Lambda function. The function generates a unique file for each execution and must commit the file to an AWS CodeCommit repository.
How should the developer accomplish this?
-
A
Use an AWS SDK to instantiate a CodeCommit client. Invoke the PutFile method to add the file to the repository and execute a commit with CreateCommit.
-
B
Upload the new file to an Amazon S3 bucket. Create an AWS Step Function to accept S3 events. Use AWS Lambda functions in the Step Function, to add the file to the repository and commit the change.
-
C
After the new file is created in Lambda, use CURL to invoke the CodeCommit API. Send the file to the repository and automatically commit the change.
-
D
Send a message to an Amazon SQS queue with the file attached. Configure an AWS Step Function as a destination for messages in the queue. Configure the Step Function to add the new file to the repository and commit the change.
Xem giải thích
Đáp án
A — Dùng AWS SDK tạo client của CodeCommit, gọi PutFile để thêm tệp và CreateCommit để thực hiện commit.
Vì sao đúng
CodeCommit có API đầy đủ để thao tác với tệp và commit mà không cần Git client. Đây là điều rất hợp với Lambda, nơi bạn không có sẵn Git và không muốn cài thêm.
import boto3
codecommit = boto3.client('codecommit')
def lambda_handler(event, context):
noi_dung = tao_tep()
codecommit.put_file(
repositoryName='kho-du-lieu',
branchName='main',
fileContent=noi_dung.encode('utf-8'),
filePath=f'bao-cao/{context.aws_request_id}.json',
commitMessage='Thêm báo cáo tự động',
name='Lambda Bot',
email='bot@congty.com'
)
Đáng chú ý: PutFile tự tạo commit — bạn không phải gọi CreateCommit riêng cho trường hợp một tệp. CreateCommit cần đến khi muốn nhiều thay đổi trong một commit:
codecommit.create_commit(
repositoryName='kho-du-lieu',
branchName='main',
parentCommitId=commit_cha,
putFiles=[
{'filePath': 'a.json', 'fileContent': noi_dung_a},
{'filePath': 'b.json', 'fileContent': noi_dung_b}
],
deleteFiles=[{'filePath': 'cu.json'}]
)
Cách này đơn giản nhất trong bốn phương án: một lời gọi SDK, không có dịch vụ trung gian nào.
Vì sao các phương án khác sai
- C. Dùng CURL để gọi API của CodeCommit — về lý thuyết làm được, nhưng bạn phải tự cài đặt ký SigV4 — băm payload, dựng canonical request, tính chữ ký HMAC nhiều bước. Hàng chục dòng mã dễ sai cho việc mà SDK làm sẵn. Và trong Lambda,
curlcòn chưa chắc có sẵn. - B. Tải lên S3 → Step Functions → Lambda ghi vào CodeCommit — thêm hai dịch vụ mà không giải quyết được gì: cuối cùng vẫn phải có một Lambda gọi API CodeCommit, tức là vẫn cần phương án A. Nhiều thành phần hơn, nhiều chỗ hỏng hơn, độ trễ cao hơn.
- D. Gửi message vào SQS "với tệp đính kèm" → Step Functions — sai cả về kỹ thuật lẫn kiến trúc: SQS không có khái niệm đính kèm tệp (message tối đa 256 KB, chỉ là văn bản), và Step Functions không đăng ký làm destination của SQS queue theo cách mô tả. Ngoài ra vẫn là đường vòng không cần thiết.
Ghi nhớ
Các API thao tác tệp của CodeCommit — chúng cho phép làm việc với kho mã hoàn toàn không cần Git: | API | Việc | |---|---| | PutFile | thêm hoặc sửa MỘT tệp (tự tạo commit) | | CreateCommit | nhiều thay đổi trong một commit | | DeleteFile | xoá tệp | | GetFile | đọc nội dung tệp | | GetBranch, CreateBranch | quản lý nhánh | | CreatePullRequest, MergePullRequestByFastForward | pull request |
Quyền cần cho execution role:
{"Effect": "Allow",
"Action": ["codecommit:PutFile", "codecommit:GetBranch", "codecommit:CreateCommit"],
"Resource": "arn:aws:codecommit:ap-southeast-1:123456789012:kho-du-lieu"}
Hai lưu ý thực tế:
- Xung đột commit song song: nếu nhiều lần gọi Lambda cùng ghi vào một nhánh,
PutFilecó thể thất bại vìparentCommitIdđã lỗi thời. Hãy thử lại với exponential backoff, hoặc cho mỗi lần chạy ghi vào đường dẫn riêng như trong ví dụ trên. - Kho mã không phải nơi lưu dữ liệu vận hành. Nếu tệp sinh ra ở mọi lần chạy chỉ là dữ liệu chứ không phải mã nguồn, S3 mới là chỗ đúng — Git sẽ phình to rất nhanh và không có cơ chế dọn.
A Developer is storing sensitive documents in Amazon S3. The documents must be encrypted at rest and company policy mandates that the encryption keys must be rotated annually. What is the EASIEST way to achieve this?
-
A
Use AWS KMS with automatic key rotation
-
B
Export a key from AWS KMS to encrypt the data
-
C
Encrypt the data before sending it to Amazon S3
-
D
Import a custom key into AWS KMS with annual rotation enabled
Xem giải thích
Đáp án
A — Dùng AWS KMS với tự động xoay vòng khoá.
Vì sao đúng
Đề hỏi cách DỄ NHẤT để thoả chính sách "khoá mã hoá phải được xoay vòng hằng năm", và KMS có sẵn đúng tính năng đó — bật bằng một lời gọi:
aws kms enable-key-rotation --key-id arn:aws:kms:...:key/abc-123
Từ đó KMS tự tạo vật liệu khoá mới mỗi năm (mặc định 365 ngày), hoàn toàn tự động.
Điểm quan trọng nhất — và cũng là lý do nó "dễ nhất": việc xoay vòng hoàn toàn trong suốt với ứng dụng.
| Điều xảy ra | Chi tiết |
|---|---|
| Key ID và ARN không đổi | mọi tham chiếu tới khoá vẫn hoạt động |
| Vật liệu khoá cũ được giữ lại | dữ liệu cũ vẫn giải mã được bình thường |
| Dữ liệu mới dùng vật liệu mới | tự động |
| Không phải mã hoá lại gì cả | không có job di trú nào |
Dòng thứ hai là chỗ nhiều người hiểu nhầm: xoay vòng không làm hỏng dữ liệu cũ. KMS giữ lại mọi phiên bản vật liệu khoá và tự chọn đúng phiên bản khi giải mã, dựa vào thông tin nhúng trong ciphertext.
Kết hợp với S3 thì chỉ cần khai khoá:
aws s3api put-bucket-encryption --bucket tai-lieu-mat \
--server-side-encryption-configuration '{
"Rules": [{"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:...:key/abc-123"},
"BucketKeyEnabled": true}]}'
Vì sao các phương án khác sai
- D. Nhập khoá tuỳ chỉnh vào KMS với xoay vòng hằng năm — khoá nhập từ ngoài (imported key material) KHÔNG hỗ trợ tự động xoay vòng. Bạn phải tự sinh và tự nhập vật liệu mới mỗi lần — hoàn toàn thủ công, trái yêu cầu "EASIEST".
- B. Xuất khoá từ KMS để mã hoá dữ liệu — không xuất được: nguyên tắc nền tảng của KMS là CMK không bao giờ rời khỏi dịch vụ. Thứ bạn lấy ra được là data key, không phải CMK.
- C. Mã hoá dữ liệu trước khi gửi lên S3 (client-side) — làm được, nhưng nhiều việc nhất: bạn phải tự viết mã mã hoá, tự quản lý khoá, và tự cài đặt cơ chế xoay vòng — chính là thứ đề muốn tránh.
Ghi nhớ
Hỗ trợ xoay vòng theo loại khoá: | Loại khoá | Tự động xoay vòng | |---|---| | Customer managed CMK | ✅ bật được, mặc định 365 ngày | | AWS managed key | ✅ tự động (mỗi năm), không tắt được | | Khoá nhập từ ngoài | ❌ phải tự nhập lại | | Khoá trong custom key store (CloudHSM) | ❌ |
(Ghi chú: từ 2024, KMS cho phép tuỳ chỉnh chu kỳ xoay vòng từ 90 ngày đến 2560 ngày, thay vì cố định 365 như trước — hữu ích khi chính sách công ty đòi chu kỳ ngắn hơn.)
Phân biệt hai khái niệm hay bị lẫn: | | Xoay vòng vật liệu khoá | Đổi sang khoá mới hoàn toàn | |---|---|---| | Key ID | không đổi | đổi | | Dữ liệu cũ | vẫn giải mã được | phải ReEncrypt | | Công sức | bằng không | phải di trú |
Và một tối ưu chi phí đáng bật khi dùng SSE-KMS với S3: BucketKeyEnabled: true — nó giảm số lời gọi KMS tới 99% bằng cách dùng một bucket-level key thay vì gọi KMS cho từng object.
A development team manage a high-traffic e-Commerce site with dynamic pricing that is updated in real-time. There have been incidents where multiple updates occur simultaneously and cause an original editor’s updates to be overwritten. How can the developers ensure that overwriting does not occur?
-
A
Use concurrent writes
-
B
Use batch operations
-
C
Use atomic counters
-
D
Use conditional writes
Xem giải thích
Đáp án
D — Dùng conditional write (ghi có điều kiện).
Vì sao đúng
Vấn đề trong đề là lost update — kinh điển trong hệ thống có nhiều người ghi đồng thời:
Thời điểm 1: Người A đọc giá = 100.000đ
Thời điểm 2: Người B đọc giá = 100.000đ
Thời điểm 3: Người A ghi giá = 120.000đ ✓
Thời điểm 4: Người B ghi giá = 90.000đ ✗ ← ghi đè mất cập nhật của A
Conditional write ngăn chuyện này bằng cách chỉ cho ghi nếu điều kiện còn đúng — DynamoDB kiểm tra điều kiện và thực hiện ghi trong cùng một thao tác nguyên tử:
table.update_item(
Key={'san_pham_id': 'SP-001'},
UpdateExpression='SET gia = :gia_moi, phien_ban = :pb_moi',
ConditionExpression='phien_ban = :pb_cu', # ← chỉ ghi nếu chưa ai đổi
ExpressionAttributeValues={
':gia_moi': 90000,
':pb_cu': 5,
':pb_moi': 6
}
)
Nếu ai đó đã tăng phien_ban lên 6 trong lúc đó, điều kiện sai và DynamoDB từ chối với ConditionalCheckFailedException. Ứng dụng bắt lỗi này rồi đọc lại giá trị mới và thử lại:
from botocore.exceptions import ClientError
try:
cap_nhat_gia(...)
except ClientError as e:
if e.response['Error']['Code'] == 'ConditionalCheckFailedException':
doc_lai_va_thu_lai()
Đây gọi là optimistic locking: giả định xung đột hiếm xảy ra, không khoá gì trước, chỉ phát hiện và xử lý khi thật sự đụng nhau.
Vì sao các phương án khác sai
- C. Atomic counter — dùng cho phép tăng/giảm một số một cách nguyên tử:
Nó tránh mất cập nhật cho phép cộng dồn, nhưng ở đây nghiệp vụ là đặt một giá trị mới (giá bán), không phải cộng thêm. Atomic counter không kiểm tra được điều kiện nào.UpdateExpression='SET so_luot_xem = so_luot_xem + :n' - A. "Dùng concurrent writes" — không phải tính năng nào cả, mà chính là mô tả của vấn đề: nhiều lần ghi đồng thời đang gây ra lỗi.
- B. Dùng batch operation —
BatchWriteItemgom nhiều thao tác vào một lời gọi để giảm số request, nhưng nó không nguyên tử và không hỗ trợ điều kiện. Nó không giúp gì cho vấn đề ghi đè.
Ghi nhớ
Các toán tử dùng trong ConditionExpression: | Toán tử | Ví dụ | |---|---| | So sánh | gia < :max, phien_ban = :pb | | attribute_exists | chỉ ghi nếu item ĐÃ tồn tại | | attribute_not_exists | chỉ ghi nếu item CHƯA tồn tại — chống trùng khoá | | begins_with, contains | với chuỗi | | IN, BETWEEN | tập hợp và khoảng |
Mẫu chống tạo trùng bằng attribute_not_exists:
table.put_item(
Item={'don_hang_id': 'DH-001', ...},
ConditionExpression='attribute_not_exists(don_hang_id)'
)
Đây là cách gọn nhất để đảm bảo không tạo đè lên đơn hàng đã có.
Ba cơ chế xử lý đồng thời trong DynamoDB: | Cơ chế | Dùng khi | |---|---| | Conditional write | cập nhật một item, chống ghi đè | | Atomic counter | cộng/trừ một số (lượt xem, tồn kho) | | TransactWriteItems | nhiều item, tất cả hoặc không |
Và điểm cần biết về chi phí: conditional write vẫn tốn WCU ngay cả khi điều kiện thất bại — nên nếu tỷ lệ xung đột rất cao, hãy xem lại thiết kế thay vì thử lại mãi.
A Developer wants to debug an application by searching and filtering log data. The application logs are stored in Amazon CloudWatch Logs. The Developer creates a new metric filter to count exceptions in the application logs. However, no results are returned from the logs.
What is the reason that no filtered results are being returned?
-
A
The log group for CloudWatch Logs should be first streamed to Amazon Elasticsearch Service before filtering returns the results
-
B
Metric data points to logs groups can be filtered only after they are exported to an Amazon S3 bucket
-
C
A setup of the Amazon CloudWatch interface VPC endpoint is required for filtering the CloudWatch Logs in the VPC
-
D
CloudWatch Logs only publishes metric data for events that happen after the filter is created
Xem giải thích
Đáp án
D — CloudWatch Logs chỉ phát dữ liệu metric cho các sự kiện xảy ra SAU KHI filter được tạo.
Vì sao đúng
Đây là hành vi rất hay gây bối rối: metric filter không quét lại log cũ.
Nó hoạt động như một bộ lọc đặt trên dòng chảy: khi một dòng log mới tới, filter kiểm tra và phát ra điểm dữ liệu metric nếu khớp. Với những dòng đã nằm sẵn trong log group từ trước, filter hoàn toàn không đụng tới.
Timeline:
10:00 ─ log ghi 50 exception ──→ (chưa có filter) → không có metric nào
11:00 ─ TẠO metric filter
11:05 ─ log ghi 3 exception ──→ khớp filter → metric = 3 ✓
Nên nếu vừa tạo filter mà chưa có sự kiện mới nào, biểu đồ metric hoàn toàn trống — đúng triệu chứng trong đề.
Cách kiểm tra filter có đúng không mà không phải chờ: dùng chức năng test trên dữ liệu đã có:
aws logs test-metric-filter \
--filter-pattern '{ $.level = "ERROR" }' \
--log-event-messages '{"level":"ERROR","msg":"loi ket noi"}'
Và để phân tích log CŨ, dùng CloudWatch Logs Insights — nó truy vấn được toàn bộ dữ liệu đã lưu:
fields @timestamp, @message
| filter @message like /Exception/
| stats count() by bin(1h)
Đây là phân công đúng giữa hai công cụ: Insights nhìn về quá khứ, metric filter nhìn về tương lai.
Vì sao các phương án khác sai
- A. Phải stream log group sang Elasticsearch trước khi lọc — không cần: metric filter hoạt động trực tiếp trên CloudWatch Logs. Việc stream sang OpenSearch là để tìm kiếm và trực quan hoá nâng cao, hoàn toàn tuỳ chọn.
- B. Chỉ lọc được sau khi export sang S3 — cũng không cần: export sang S3 dùng để lưu trữ dài hạn hoặc phân tích bằng Athena, không phải điều kiện để metric filter chạy.
- C. Cần VPC interface endpoint cho CloudWatch — VPC endpoint chỉ cần khi tài nguyên trong private subnet gọi API của CloudWatch mà không có đường ra Internet. Nó không ảnh hưởng gì tới việc metric filter có sinh dữ liệu hay không.
Ghi nhớ
Phân công giữa hai công cụ — điểm quan trọng nhất của câu này: | | Metric filter | Logs Insights | |---|---|---| | Áp cho dữ liệu | CHỈ log MỚI, từ lúc tạo | TOÀN BỘ log đã lưu | | Chạy | liên tục, tự động | theo yêu cầu | | Kết quả | metric — đặt alarm được | bảng kết quả để xem | | Chi phí | phí custom metric | tính theo lượng dữ liệu quét |
Nhận dạng nhanh: cần cảnh báo liên tục ⇒ metric filter. Cần điều tra sự cố đã xảy ra ⇒ Logs Insights.
Vài mẫu filter pattern hay dùng:
ERROR # log dạng text thuần
"Exception" -"NullPointer" # có Exception nhưng loại trừ NullPointer
{ $.level = "ERROR" } # log JSON
{ $.duration > 1000 } # so sánh số trong JSON
[ip, user, ts, req, status=5*] # log dạng cột, mã 5xx
Một chi tiết đáng biết khi tạo filter: đặt defaultValue: 0 cho metric transformation. Nếu không, những khoảng thời gian không có dòng nào khớp sẽ không có điểm dữ liệu (thay vì có điểm bằng 0) — khiến alarm rơi vào INSUFFICIENT_DATA và biểu đồ bị đứt quãng.
A Developer needs to create an instance profile for an Amazon EC2 instance using the AWS CLI. How can this be achieved? (Select THREE.)
-
A
Run the
AssignInstanceProfileAPI -
B
Run the
aws ec2 associate-instance-profilecommand -
C
Run the
aws iam add-role-to-instance-profilecommand -
D
Run the
aws iam create-instance-profilecommand -
E
Run the
AddRoleToInstanceProfileAPI -
F
Run the
CreateInstanceProfileAPI
Xem giải thích
Đáp án
B, C và D — ba lệnh AWS CLI:
- D —
aws iam create-instance-profile - C —
aws iam add-role-to-instance-profile - B —
aws ec2 associate-instance-profile
Vì sao đúng
Điểm phân biệt của câu này rất đơn giản: đề hỏi làm bằng AWS CLI, nên đáp án phải là lệnh CLI (chữ thường, có dấu gạch nối), không phải tên API (kiểu PascalCase).
Và quy trình gồm đúng ba bước, theo thứ tự bắt buộc:
Bước 1 — tạo instance profile (vỏ chứa role):
aws iam create-instance-profile --instance-profile-name UngDungWebProfile
Bước 2 — đưa role vào profile:
aws iam add-role-to-instance-profile \
--instance-profile-name UngDungWebProfile \
--role-name RoleUngDungWeb
Bước 3 — gắn profile vào instance:
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=UngDungWebProfile
Vì sao cần cả instance profile lẫn role: EC2 không gắn trực tiếp được IAM role. Instance profile là lớp bọc trung gian, và mỗi profile chỉ chứa được đúng MỘT role.
(Trong Console thì bạn không thấy bước này — Console tự tạo instance profile cùng tên khi bạn tạo role cho EC2. Chỉ khi làm bằng CLI hay API mới phải làm tay cả ba bước, và đó là điều câu hỏi kiểm tra.)
Vì sao các phương án khác sai
- F.
CreateInstanceProfile, E.AddRoleToInstanceProfile, A.AssignInstanceProfile— E và F là TÊN API thật (dùng khi gọi qua SDK), nhưng đề hỏi lệnh CLI. Còn A thì không tồn tại ở cả hai dạng — API đúng tên làAssociateIamInstanceProfile.
Ghi chú về chất lượng câu hỏi
Phương án B viết là aws ec2 associate-instance-profile, nhưng lệnh thật là aws ec2 associate-iam-instance-profile — thiếu chữ iam. Đây là lỗi chính tả trong nguồn, không phải một lệnh khác.
Dù vậy B vẫn là lựa chọn đúng, vì ý định của câu hỏi rõ ràng là phân biệt lệnh CLI với tên API, và trong ba phương án còn lại không có lệnh CLI nào khác cho bước gắn vào instance. Khi gõ thật thì nhớ đủ chữ iam.
Ghi nhớ
Đối chiếu tên CLI và tên API: | Lệnh CLI | Tên API | |---|---| | aws iam create-instance-profile | CreateInstanceProfile | | aws iam add-role-to-instance-profile | AddRoleToInstanceProfile | | aws ec2 associate-iam-instance-profile | AssociateIamInstanceProfile | | aws ec2 replace-iam-instance-profile-association | ReplaceIamInstanceProfileAssociation |
Quy tắc chuyển đổi: tên API là PascalCase, lệnh CLI là chữ thường có gạch nối — và luôn có tiền tố là tên dịch vụ (aws iam, aws ec2).
Ba điểm cần nhớ về instance profile:
- Một profile chứa đúng một role.
- Đổi role của instance đang chạy được — dùng
replace-iam-instance-profile-association, không cần khởi động lại máy. - Thay đổi quyền có hiệu lực gần như ngay lập tức — credential được làm mới định kỳ từ metadata service, nên sửa policy là có tác dụng trong vài phút mà không phải triển khai lại gì.
An application runs on a fleet of Amazon EC2 instances and stores data in a Microsoft SQL Server database hosted on Amazon RDS. The developer wants to avoid storing database connection credentials the application code. The developer would also like a solution that automatically rotates the credentials.
What is the MOST secure way to store and access the database credentials?
-
A
Use AWS Systems Manager Parameter store to store the credentials. Enable automatic rotation of the credentials.
-
B
Create an IAM role that has permissions to access the database. Attach the role to the EC2 instance.
-
C
Use AWS Secrets Manager to store the credentials. Retrieve the credentials from Secrets Manager as needed.
-
D
Store the credentials in an encrypted source code repository. Retrieve the credentials from AWS CodeCommit as needed.
Xem giải thích
Đáp án
C — Dùng AWS Secrets Manager để lưu credential và lấy ra khi cần.
Vì sao đúng
Đề nêu hai yêu cầu, và Secrets Manager là dịch vụ duy nhất đáp ứng cả hai:
- Không lưu credential trong mã ứng dụng
- Tự động xoay vòng credential
import boto3, json, pymssql
sm = boto3.client('secretsmanager')
bi_mat = json.loads(sm.get_secret_value(SecretId='prod/sqlserver/ung-dung')['SecretString'])
conn = pymssql.connect(server=bi_mat['host'], user=bi_mat['username'],
password=bi_mat['password'], database=bi_mat['dbname'])
Mã không chứa mật khẩu nào, và AWS cung cấp sẵn Lambda xoay vòng cho Microsoft SQL Server trên RDS — bạn không phải viết mã xoay vòng:
aws secretsmanager rotate-secret \
--secret-id prod/sqlserver/ung-dung \
--rotation-lambda-arn arn:aws:lambda:...:function:SecretsManagerRDSSQLServerRotation \
--rotation-rules '{"ScheduleExpression": "rate(30 days)"}'
Chiến lược "alternating users" (hai tài khoản luân phiên) khiến việc xoay vòng không gây gián đoạn: ứng dụng dùng tài khoản A trong khi B đang được đổi mật khẩu, rồi mới chuyển.
Và EC2 truy cập Secrets Manager bằng instance profile — nên vẫn không có credential dài hạn nào trên máy.
Vì sao các phương án khác sai
- A. Systems Manager Parameter Store với "bật tự động xoay vòng" — đây là phương án gần nhất, và điểm loại rất dứt khoát: Parameter Store KHÔNG có tính năng xoay vòng tự động. Nó lưu được giá trị mã hoá (
SecureString), nhưng muốn xoay vòng thì phải tự viết Lambda và tự lên lịch. - B. Tạo IAM role có quyền truy cập CSDL rồi gắn vào EC2 — đúng hướng nhưng không đủ cho SQL Server: RDS chỉ hỗ trợ IAM database authentication cho MySQL, PostgreSQL và MariaDB — không hỗ trợ SQL Server. Với engine trong đề, bạn buộc phải dùng username và password. (Nếu đề nói PostgreSQL thì đây lại là phương án rất mạnh, vì token IAM chỉ sống 15 phút và không có mật khẩu nào để xoay vòng.)
- D. Lưu credential trong kho mã đã mã hoá rồi lấy từ CodeCommit — sai lầm bảo mật: bí mật nằm trong lịch sử Git vĩnh viễn, ai đọc được kho mã đều thấy, và đổi mật khẩu thì phải commit và triển khai lại.
Ghi nhớ
| Secrets Manager | Parameter Store | |
|---|---|---|
| Xoay vòng tự động | ✅ có Lambda dựng sẵn cho RDS | ❌ |
| Mã hoá | luôn có | tuỳ chọn (SecureString) |
| Chi phí | ~0,40 USD/secret/tháng | standard miễn phí |
| Kích thước | 64 KB | 4 KB / 8 KB |
| Sao chép sang Region khác | ✅ | ❌ |
Cách chọn: cần xoay vòng ⇒ Secrets Manager. Chỉ là cấu hình không nhạy cảm ⇒ Parameter Store.
Hỗ trợ IAM database authentication của RDS — bảng đáng nhớ vì nó quyết định phương án B đúng hay sai: | Engine | Hỗ trợ | |---|---| | MySQL, PostgreSQL, MariaDB | ✅ | | SQL Server, Oracle | ❌ | | Aurora MySQL, Aurora PostgreSQL | ✅ |
Và một tối ưu quan trọng: cache giá trị bí mật trong bộ nhớ ứng dụng, đừng gọi get_secret_value ở mỗi request — vừa tốn tiền theo lời gọi API, vừa thêm độ trễ. AWS có sẵn thư viện caching cho Java, Python và .NET, và chúng tự làm mới khi bí mật được xoay vòng.
An engineer is constructing a web-based application that uses Amazon DynamoDB for storing data. The data is distributed across two tables: 'authors' and 'books'. The 'authors' table uses 'authorName' as its partition key, while the 'books' table has 'bookTitle' as the partition key and 'authorName' as the sort key.
The application requires the ability to fetch multiple books and authors simultaneously in a single database operation for effective performance. The engineer is seeking a solution that maximizes application efficiency and reduces network traffic.
What strategy should the engineer employ to achieve these requirements?
-
A
Execute individual GetItem operations for each book and author to be retrieved.
-
B
First query the 'books' table using 'bookTitle' as a key condition, then separately query the 'authors' table using 'authorName'.
-
C
Utilize the DynamoDB BatchGetItem operation to fetch multiple items from both tables in a single network round trip.
-
D
Use a DynamoDB Scan operation to fetch the required items from both tables.
Xem giải thích
Đáp án
C — Dùng BatchGetItem để lấy nhiều item từ cả hai bảng trong một lần đi mạng.
Vì sao đúng
Yêu cầu của đề rất khớp với đặc điểm của BatchGetItem: lấy nhiều sách và nhiều tác giả cùng lúc, giảm lưu lượng mạng.
BatchGetItem gom nhiều thao tác GetItem — kể cả trên nhiều bảng khác nhau — vào một request duy nhất:
response = dynamodb.batch_get_item(
RequestItems={
'books': {
'Keys': [
{'bookTitle': {'S': 'Sách A'}, 'authorName': {'S': 'Nguyễn Văn A'}},
{'bookTitle': {'S': 'Sách B'}, 'authorName': {'S': 'Trần Thị B'}}
]
},
'authors': {
'Keys': [
{'authorName': {'S': 'Nguyễn Văn A'}},
{'authorName': {'S': 'Trần Thị B'}}
]
}
}
)
Một request thay vì bốn — đúng vế "single network round trip" và "reduces network traffic".
Lưu ý về bảng books: nó có composite key (bookTitle + authorName), nên mỗi Keys phải nêu đủ cả hai — thiếu sort key là lỗi ngay.
Giới hạn cần biết: | Giới hạn | Giá trị | |---|---| | Số item mỗi lời gọi | 100 | | Kích thước dữ liệu trả về | 16 MB | | Vượt quá | trả về trong UnprocessedKeys để bạn thử lại |
Trường UnprocessedKeys rất quan trọng: BatchGetItem không đảm bảo lấy được hết — nếu bị throttle hoặc vượt 16 MB, nó trả về phần còn lại ở đó và bạn phải gọi lại (nên kèm exponential backoff).
Vì sao các phương án khác sai
- A. Gọi
GetItemriêng cho từng sách và từng tác giả — cho kết quả đúng nhưng tốn nhiều lần đi mạng nhất: mỗi item là một request. Với 20 sách và 20 tác giả là 40 lần đi mạng, độ trễ cộng dồn rất lớn. Trái yêu cầu tối ưu. - B. Query bảng
booksrồi query riêng bảngauthors— tốt hơn A nhưng vẫn là hai lần đi mạng, vàQuerychỉ hợp khi cần nhiều item có cùng partition key. Ở đây ta biết chính xác từng item cần lấy, nênBatchGetItemlà công cụ đúng. - D. Dùng
Scanđể lấy item từ cả hai bảng — tệ nhất về hiệu năng và chi phí:Scanđọc TOÀN BỘ bảng rồi mới lọc, tốn RCU cho mọi item dù bạn chỉ cần vài cái. Ngoài raScankhông quét được hai bảng cùng lúc — vẫn phải gọi hai lần.
Ghi nhớ
Bốn cách đọc dữ liệu từ DynamoDB, theo hiệu quả giảm dần: | Thao tác | Dùng khi | Chi phí | |---|---|---| | GetItem | biết chính xác khoá của MỘT item | thấp nhất | | BatchGetItem | biết khoá của NHIỀU item, có thể nhiều bảng | thấp | | Query | nhiều item CÙNG partition key | trung bình | | Scan | không có lựa chọn nào khác | cao nhất |
So sánh hai API batch: | | BatchGetItem | BatchWriteItem | |---|---|---| | Số item | 100 | 25 | | Kích thước | 16 MB | 16 MB | | Nguyên tử | ❌ | ❌ | | Phần chưa xong | UnprocessedKeys | UnprocessedItems |
Cả hai đều không nguyên tử — cần "tất cả hoặc không" thì phải dùng TransactGetItems / TransactWriteItems (giới hạn 100 item, tốn gấp đôi capacity).
Hai mẹo thực dụng với BatchGetItem:
- Dùng
ProjectionExpressionđể chỉ lấy các thuộc tính cần — giảm cả RCU lẫn dữ liệu truyền. - Luôn xử lý
UnprocessedKeys— bỏ qua nó nghĩa là ứng dụng thỉnh thoảng thiếu dữ liệu mà không có lỗi nào.