Ngân hàng đề — AWS Certified Developer Associate
Tìm thấy 1356 câu.
A developer must identify the public IP addresses of clients connecting to Amazon EC2 instances behind a public Application Load Balancer (ALB). The EC2 instances run an HTTP server that logs all requests to a log file.
How can the developer ensure the client public IP addresses are captured in the log files on the EC2 instances?
-
A
Install the AWS X-Ray daemon on the EC2 instances and configure request logging.
-
B
Install the Amazon CloudWatch Logs agent on the EC2 instances and configure logging.
-
C
Configure the HTTP server to add the x-forwarded-for request header to the logs.
-
D
Configure the HTTP server to add the x-forwarded-proto request header to the logs.
Xem giải thích
Đáp án
C — Cấu hình máy chủ HTTP ghi header X-Forwarded-For vào log.
Vì sao đúng
Vấn đề nằm ở cách load balancer hoạt động: ALB kết thúc kết nối từ client và mở một kết nối MỚI tới instance. Nên từ góc nhìn của instance, mọi request đều đến từ IP riêng của ALB:
Client (203.0.113.45) → ALB → EC2 thấy IP nguồn = 10.0.1.20 (chính ALB)
Để không mất thông tin đó, ALB thêm header X-Forwarded-For chứa IP thật của client:
X-Forwarded-For: 203.0.113.45
Nếu có nhiều proxy nối tiếp (ví dụ CloudFront rồi mới tới ALB), header thành danh sách:
X-Forwarded-For: 203.0.113.45, 70.41.3.18
↑ client thật ↑ proxy trung gian
Việc còn lại là cấu hình máy chủ web ghi header đó thay vì IP kết nối:
nginx:
log_format chinh '$http_x_forwarded_for - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent';
access_log /var/log/nginx/access.log chinh;
Apache — dùng %{X-Forwarded-For}i thay cho %h:
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" chinh
(Hoặc gọn hơn: bật module mod_remoteip với RemoteIPHeader X-Forwarded-For, khi đó %h tự trả về IP thật.)
Vì sao các phương án khác sai
- D. Ghi header
X-Forwarded-Proto— sai header, và khác biệt đáng nhớ:X-Forwarded-Protocho biết giao thức gốc làhttphayhttps— hữu ích để ứng dụng biết client dùng HTTPS dù ALB chuyển tiếp bằng HTTP. Nó không chứa địa chỉ IP nào. - B. Cài CloudWatch Logs agent — agent đẩy log lên CloudWatch, nhưng nó chỉ chuyển đi nội dung đã có sẵn trong tệp. Nếu tệp log đang ghi IP của ALB thì CloudWatch cũng chỉ nhận được IP của ALB.
- A. Cài X-Ray daemon — X-Ray dùng để theo dấu request qua các dịch vụ và phân tích hiệu năng. Nó không ghi IP client vào log của máy chủ web.
Ghi nhớ
Ba header mà ALB tự thêm: | Header | Nội dung | |---|---| | X-Forwarded-For | IP thật của client | | X-Forwarded-Proto | giao thức gốc: http hoặc https | | X-Forwarded-Port | cổng client kết nối tới |
Hai lưu ý quan trọng:
1. Cảnh báo bảo mật. X-Forwarded-For là header do client có thể tự đặt. Nếu instance nhận request trực tiếp (không qua ALB), kẻ tấn công giả mạo IP trong log được. Cách phòng: dùng security group chỉ cho phép traffic từ SG của ALB, và khi đọc header thì lấy giá trị bên phải cùng do proxy tin cậy thêm vào, không phải giá trị đầu tiên.
2. Với NLB thì khác. NLB hoạt động ở tầng 4 và không thêm header nào. Muốn giữ IP client với NLB, có hai cách: bật client IP preservation trên target group (IP nguồn được giữ nguyên), hoặc bật Proxy Protocol v2.
Và nếu chỉ cần phân tích chứ không cần log trên máy: bật ALB access log ghi thẳng vào S3, rồi truy vấn bằng Athena — không cần đụng tới cấu hình máy chủ web.
A Developer has created a task definition that includes the following JSON code:
"placementStrategy": [
{
"field": "attribute:ecs.availability-zone",
"type": "spread"
},
{
"field": "instanceId",
"type": "spread"
}
]
What is the effect of this task placement strategy?
-
A
It distributes tasks evenly across Availability Zones and then distributes tasks evenly across the instances within each Availability Zone
-
B
It distributes tasks evenly across Availability Zones and then distributes tasks randomly across instances within each Availability Zone
-
C
It distributes tasks evenly across Availability Zones and then bin packs tasks based on memory within each Availability Zone
-
D
It distributes tasks evenly across Availability Zones and then distributes tasks evenly across distinct instances within each Availability Zone
Xem giải thích
Đáp án
A — Phân bố task đều trên các Availability Zone, rồi phân bố đều trên các instance trong mỗi AZ.
Vì sao đúng
placementStrategy là một mảng có thứ tự — ECS áp dụng từng chiến lược lần lượt từ trên xuống:
"placementStrategy": [
{"field": "attribute:ecs.availability-zone", "type": "spread"}, ← áp dụng TRƯỚC
{"field": "instanceId", "type": "spread"} ← rồi mới tới cái này
]
Đọc từng phần: | Phần | Nghĩa | |---|---| | type: spread | rải đều | | field: attribute:ecs.availability-zone | theo Availability Zone | | field: instanceId | theo từng instance |
Nên toàn bộ nghĩa là: cân bằng số task giữa các AZ trước, sau đó trong mỗi AZ thì cân bằng giữa các instance.
Ví dụ với 6 task, 2 AZ, mỗi AZ 3 instance:
AZ-a: instance1 (1 task), instance2 (1 task), instance3 (1 task)
AZ-c: instance1 (1 task), instance2 (1 task), instance3 (1 task)
Đây là cấu hình được khuyến nghị cho dịch vụ cần sẵn sàng cao: một AZ sập vẫn còn một nửa số task, và một instance hỏng chỉ mất một phần nhỏ.
Vì sao các phương án khác sai
- D. "…rồi phân bố đều trên các instance RIÊNG BIỆT (distinct instances)" — đây là bẫy tinh vi nhất.
distinctInstancelà một CONSTRAINT, không phải strategy, và nó có nghĩa mạnh hơn hẳn: mỗi instance chỉ được có TỐI ĐA MỘT task. Cấu hình trong đề dùngspread— nó cân bằng số task, nhưng cho phép nhiều task trên cùng một instance."placementConstraints": [{"type": "distinctInstance"}] ← khác hẳn - B. "…rồi phân bố NGẪU NHIÊN trong mỗi AZ" —
randomlà một type hợp lệ, nhưng cấu hình ở đây ghi rõspreadcho cả hai tầng. Ngẫu nhiên và rải đều là hai thuật toán khác nhau. - C. "…rồi binpack theo bộ nhớ trong mỗi AZ" —
binpackcũng là type hợp lệ nhưng mục tiêu ngược lại: nó dồn task vào càng ít instance càng tốt để tiết kiệm chi phí. Cấu hình trong đề không hề nhắc tớibinpack.
Ghi nhớ
Ba strategy của ECS (quyết định ưu tiên chọn instance nào): | Type | Hành vi | Dùng khi | |---|---|---| | spread | rải đều theo một trường | sẵn sàng cao | | binpack | dồn chặt theo CPU hoặc memory | tiết kiệm chi phí | | random | ngẫu nhiên | không quan tâm |
Hai constraint của ECS (quyết định instance nào ĐƯỢC PHÉP): | Type | Hành vi | |---|---| | distinctInstance | mỗi instance tối đa một task | | memberOf | chỉ instance thoả biểu thức, ví dụ attribute:ecs.instance-type =~ t3.* |
Khác biệt cốt lõi: strategy là ưu tiên (sắp xếp), constraint là bộ lọc (loại bỏ). Constraint được áp trước để thu hẹp tập ứng viên, rồi strategy mới chọn trong tập đó.
Kết hợp hay dùng nhất cho production:
"placementStrategy": [
{"field": "attribute:ecs.availability-zone", "type": "spread"},
{"field": "instanceId", "type": "spread"}
]
— đúng cấu hình trong đề bài này.
A Developer has recently created an application that uses an AWS Lambda function, an Amazon DynamoDB table, and also sends notifications using Amazon SNS. The application is not working as expected and the Developer needs to analyze what is happening across all components of the application.
What is the BEST way to analyze the issue?
-
A
Enable X-Ray tracing for the Lambda function
-
B
Assess the application with Amazon Inspector
-
C
Monitor the application with AWS Trusted Advisor
-
D
Create an Amazon CloudWatch Events rule
Xem giải thích
Đáp án
A — Bật X-Ray tracing cho hàm Lambda.
Vì sao đúng
Đề mô tả một ứng dụng gồm ba thành phần — Lambda, DynamoDB, SNS — và yêu cầu phân tích chuyện gì đang xảy ra trên TẤT CẢ các thành phần.
Đó chính là bài toán mà X-Ray được thiết kế để giải: theo dấu một request qua toàn bộ chuỗi dịch vụ.
Bật rất đơn giản:
aws lambda update-function-configuration \
--function-name ung-dung --tracing-config Mode=Active
Cộng với quyền cho execution role:
{"Effect": "Allow",
"Action": ["xray:PutTraceSegments", "xray:PutTelemetryRecords"],
"Resource": "*"}
Điểm hay: với các dịch vụ AWS gọi qua SDK, X-Ray tự động tạo subsegment — không phải viết mã thủ công. Chỉ cần bọc SDK:
from aws_xray_sdk.core import patch_all
patch_all() # tự theo dấu mọi lời gọi boto3
# Từ đây, mọi lời gọi DynamoDB và SNS đều xuất hiện trong trace
Kết quả là service map hiển thị:
Lambda ──┬──→ DynamoDB (12 ms, OK)
└──→ SNS (2.400 ms, LỖI ← thấy ngay vấn đề ở đâu)
Nó cho biết chặng nào chậm, chặng nào lỗi, và lỗi cụ thể là gì — đúng thứ cần khi "ứng dụng không chạy như mong đợi" mà chưa rõ nguyên nhân.
Vì sao các phương án khác sai
- D. Tạo CloudWatch Events rule — EventBridge phản ứng với sự kiện (chạy hành động khi có điều gì đó xảy ra). Nó không phân tích và không cho thấy quan hệ giữa các thành phần.
- B. Amazon Inspector — công cụ quét lỗ hổng bảo mật trên EC2, container image và Lambda. Nó tìm CVE và cấu hình rủi ro, không gỡ lỗi hành vi ứng dụng.
- C. AWS Trusted Advisor — đưa khuyến nghị ở mức tài khoản về chi phí, hiệu năng, bảo mật, hạn mức. Nó không nhìn vào một request cụ thể và không biết ứng dụng của bạn làm gì.
Ghi nhớ
| Công cụ | Trả lời câu hỏi |
|---|---|
| X-Ray | Request đi qua đâu, chậm và lỗi ở CHẶNG NÀO? |
| CloudWatch Logs | Ứng dụng đã ghi ra gì? |
| CloudWatch Metrics | Có bao nhiêu lỗi, khi nào? |
| CloudTrail | Ai gọi API quản trị? |
| Inspector | Có lỗ hổng bảo mật nào? |
| Trusted Advisor | Tài khoản có gì chưa tối ưu? |
Nhận dạng nhanh: đề nói "across all components", "distributed", "which service is failing" ⇒ X-Ray.
Hai khái niệm cần thuộc: | Khái niệm | Nghĩa | |---|---| | Segment | dữ liệu về công việc của một dịch vụ | | Subsegment | chi tiết bên trong, ví dụ một lời gọi DynamoDB | | Annotation | cặp khoá–giá trị ĐƯỢC ĐÁNH CHỈ MỤC — lọc trace theo nó được | | Metadata | dữ liệu kèm theo, không đánh chỉ mục |
Muốn tìm trace theo order_id thì phải dùng annotation, không phải metadata — đây là chi tiết hay bị hỏi.
A critical application is hosted on AWS exposed by an HTTP API through Amazon API Gateway. The API is integrated with an AWS Lambda function and the application data is housed in an Amazon RDS for PostgreSQL DB instance, featuring 2 vCPUs and 16 GB of RAM.
The company has been receiving customer complaints about occasional HTTP 500 Internal Server Error responses from some API calls during unpredictable peak usage times. Amazon CloudWatch Logs has recorded "connection limit exceeded" errors. The company wants to ensure resilience in the application, with no unscheduled downtime for the database.
Which solution would best fit these requirements?
-
A
Use Amazon RDS Proxy and update the Lambda function to connect to the proxy.
-
B
Use AWS Lambda to create a connection pool for the RDS instance.
-
C
Double the RAM and vCPUs of the RDS instance.
-
D
Implement auto-scaling for the RDS instance based on connection count.
Xem giải thích
Đáp án
A — Dùng Amazon RDS Proxy và sửa hàm Lambda để kết nối qua proxy.
Vì sao đúng
Triệu chứng trong đề đã chỉ thẳng nguyên nhân: log ghi "connection limit exceeded" vào những lúc tải cao bất thường.
Đây là vấn đề kinh điển của cặp Lambda + CSDL quan hệ:
Đỉnh traffic → API Gateway gọi 500 hàm Lambda đồng thời
→ mỗi hàm mở MỘT kết nối riêng tới PostgreSQL
→ 500 kết nối, vượt giới hạn của instance 2 vCPU / 16 GB
→ "connection limit exceeded" → HTTP 500
Lambda không có connection pool dùng chung — mỗi môi trường thực thi là một tiến trình riêng biệt, không chia sẻ được kết nối với nhau. Càng nhiều hàm chạy song song, càng nhiều kết nối.
RDS Proxy đứng giữa và giải quyết đúng chỗ đó:
500 hàm Lambda → RDS Proxy (gom và tái dùng) → khoảng 20 kết nối thật tới CSDL
| Lợi ích | Chi tiết |
|---|---|
| Gom kết nối | hàng trăm kết nối ứng dụng → vài chục kết nối thật |
| Giảm thời gian failover | tới 66% — proxy giữ kết nối trong lúc CSDL chuyển đổi |
| Không đụng mã | chỉ đổi endpoint trong chuỗi kết nối |
| Tích hợp Secrets Manager và IAM | không cần nhúng mật khẩu |
Vế "no unscheduled downtime" cũng được đáp ứng: khi CSDL failover, proxy giữ kết nối của ứng dụng và tự nối lại phía sau, nên client không thấy lỗi.
Việc phải làm chỉ là đổi host:
conn = psycopg2.connect(
host='proxy-cua-toi.proxy-abc123.ap-southeast-1.rds.amazonaws.com', # ← proxy
database='ungdung', user=..., password=...)
Vì sao các phương án khác sai
- B. Dùng Lambda để tạo connection pool cho RDS — không làm được theo cách có ý nghĩa: mỗi môi trường thực thi Lambda là một tiến trình độc lập. Bạn giữ được một kết nối tái dùng giữa các lần gọi trong cùng một môi trường (khai biến ngoài handler), nhưng không chia sẻ pool giữa các môi trường — mà chính số môi trường đồng thời mới là nguyên nhân.
- C. Tăng gấp đôi RAM và vCPU — có tăng
max_connections(giá trị này tính theo bộ nhớ), nhưng chỉ đẩy vấn đề đi xa hơn một chút: khi Lambda mở rộng tới 1.000 concurrent, không kích cỡ instance nào theo kịp. Và nó đòi khởi động lại — trái yêu cầu "no unscheduled downtime". - D. "Auto-scaling cho RDS instance theo số kết nối" — RDS không có tính năng này. RDS có storage autoscaling (dung lượng đĩa) và read replica auto scaling ở Aurora, nhưng không tự thay đổi kích cỡ instance theo metric. (Aurora Serverless v2 có co giãn năng lực tính toán, nhưng đó là dịch vụ khác chứ không phải RDS thường.)
Ghi nhớ
Chống cạn kiệt kết nối, theo thứ tự nên thử: | Cách | Hiệu quả | |---|---| | RDS Proxy | giải quyết tận gốc, không đụng mã | | Tái dùng kết nối ngoài handler | giảm số kết nối mới, không giải quyết đồng thời cao | | Reserved concurrency cho Lambda | chặn trần số hàm chạy song song | | Tăng max_connections | tạm thời, tốn RAM | | Chuyển sang Data API (Aurora Serverless) | HTTP, không có kết nối bền |
Mẫu tái dùng kết nối trong Lambda — nên làm dù đã có proxy:
import psycopg2
conn = None # ← ngoài handler, sống qua nhiều lần gọi
def lambda_handler(event, context):
global conn
if conn is None or conn.closed:
conn = psycopg2.connect(host=PROXY_ENDPOINT, ...)
...
Và nhớ: RDS Proxy phải nằm trong VPC, nên hàm Lambda cũng phải gắn vào VPC đó.
A company has implemented AWS CodePipeline to automate its release pipelines. The Development team is writing an AWS Lambda function that will send notifications for state changes of each of the actions in the stages.
Which steps must be taken to associate the Lambda function with the event source?
-
A
Create an event trigger and specify the Lambda function from the CodePipeline console
-
B
Create a trigger that invokes the Lambda function from the Lambda console by selecting CodePipeline as the event source
-
C
Create an Amazon CloudWatch alarm that monitors status changes in CodePipeline and triggers the Lambda function
-
D
Create an Amazon CloudWatch Events rule that uses CodePipeline as an event source
Xem giải thích
Đáp án
D — Tạo CloudWatch Events (EventBridge) rule dùng CodePipeline làm event source.
Vì sao đúng
CodePipeline phát sự kiện lên EventBridge ở mỗi lần đổi trạng thái, và EventBridge là nơi bạn bắt chúng để gọi Lambda.
Ba mức sự kiện, tương ứng ba mức chi tiết: | detail-type | Mức | |---|---| | CodePipeline Pipeline Execution State Change | cả pipeline | | CodePipeline Stage Execution State Change | từng stage | | CodePipeline Action Execution State Change | từng action ← đề cần cái này |
Đề nói rõ "state changes of each of the ACTIONS in the stages", nên rule phải bắt mức action:
{
"source": ["aws.codepipeline"],
"detail-type": ["CodePipeline Action Execution State Change"],
"detail": {
"state": ["FAILED", "SUCCEEDED", "STARTED"]
}
}
aws events put-rule --name theo-doi-pipeline \
--event-pattern file://mau-su-kien.json
aws events put-targets --rule theo-doi-pipeline \
--targets "Id"="1","Arn"="arn:aws:lambda:...:function:gui-thong-bao"
Đừng quên cấp quyền cho EventBridge gọi hàm:
aws lambda add-permission --function-name gui-thong-bao \
--statement-id EventBridgeInvoke \
--action lambda:InvokeFunction \
--principal events.amazonaws.com \
--source-arn arn:aws:events:...:rule/theo-doi-pipeline
Vì sao các phương án khác sai
- A. Tạo "event trigger" từ Console của CodePipeline — CodePipeline không có tính năng này. Nó có trigger để BẮT ĐẦU pipeline (khi mã nguồn thay đổi), nhưng không có chỗ khai hành động khi trạng thái đổi. Việc đó thuộc về EventBridge.
- B. Tạo trigger từ Console của Lambda, chọn CodePipeline làm event source — CodePipeline không nằm trong danh sách event source trực tiếp của Lambda. Các event source trực tiếp là SQS, Kinesis, DynamoDB Streams, MSK… CodePipeline chỉ nói chuyện với Lambda qua EventBridge. (Có một quan hệ ngược lại dễ gây nhầm: CodePipeline có invoke action gọi Lambda như một bước trong pipeline — nhưng đó là để làm việc gì đó, không phải để nhận thông báo trạng thái.)
- C. Tạo CloudWatch alarm theo dõi trạng thái CodePipeline — alarm hoạt động trên metric số, còn trạng thái pipeline là sự kiện rời rạc. Không có metric nào biểu diễn "action X vừa chuyển sang FAILED" để đặt ngưỡng lên.
Ghi nhớ
Phân biệt hai công cụ hay bị lẫn của CloudWatch: | | Alarm | EventBridge Rule | |---|---|---| | Đầu vào | metric (số) | sự kiện (JSON) | | Kích hoạt khi | vượt ngưỡng | khớp mẫu | | Ví dụ | CPU > 80% trong 5 phút | pipeline action chuyển sang FAILED |
Nhận dạng nhanh: "khi trạng thái X thay đổi" ⇒ EventBridge rule. "khi giá trị vượt ngưỡng" ⇒ CloudWatch alarm.
Một lựa chọn hiện đại hơn cho đúng nhu cầu này: AWS CodeStar Notifications (dịch vụ thông báo cho CodeCommit, CodeBuild, CodeDeploy, CodePipeline). Nó cho phép chọn loại sự kiện trong giao diện và gửi thẳng tới SNS hoặc AWS Chatbot (Slack, Teams) — bên dưới vẫn dùng EventBridge, nhưng ít việc cấu hình hơn.
An ecommerce company manages a storefront that uses an Amazon API Gateway API which exposes an AWS Lambda function. The Lambda functions processes orders and stores the orders in an Amazon RDS for MySQL database. The number of transactions increases sporadically during marketing campaigns, and then goes close to zero during quite times.
How can a developer increase the elasticity of the system MOST cost-effectively?
-
A
Create an Amazon SQS queue. Publish transactions to the queue and set the queue to invoke the Lambda function. Set the reserved concurrency of the Lambda function to be equal to the max number of database connections.
-
B
Create an Amazon SNS topic. Publish transactions to the topic configure an SQS queue as a destination. Configure Lambda to process transactions from the queue.
-
C
Migrate from Amazon RDS to Amazon Aurora MySQL. Use an Aurora Auto Scaling policy to scale read replicas based on average connections of Aurora Replicas.
-
D
Migrate from Amazon RDS to Amazon Aurora MySQL. Use an Aurora Auto Scaling policy to scale read replicas based on average CPU utilization.
Xem giải thích
Đáp án
C — Chuyển từ RDS sang Aurora MySQL, dùng Aurora Auto Scaling để co giãn read replica theo số kết nối trung bình của các Aurora Replica.
Vì sao đúng
Đề mô tả tải rất thất thường: tăng vọt trong các chiến dịch marketing, rồi gần như bằng không lúc yên ắng. Yêu cầu là tăng độ đàn hồi với chi phí thấp nhất.
Aurora Auto Scaling thêm và bớt read replica tự động theo metric, nên bạn chỉ trả tiền cho replica khi thật sự cần:
{
"TargetValue": 700,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "RDSReaderAverageDatabaseConnections"
},
"ScaleInCooldown": 300,
"ScaleOutCooldown": 300
}
Aurora Auto Scaling chỉ hỗ trợ đúng hai metric, và việc chọn giữa chúng là trọng tâm của câu hỏi: | Metric | Phản ánh | |---|---| | RDSReaderAverageCPUUtilization | mức bận của CPU | | RDSReaderAverageDatabaseConnections | số kết nối đang mở |
Với tải đột biến theo lượng truy cập (nhiều người vào cùng lúc trong chiến dịch), số kết nối tăng ngay lập tức, trong khi CPU tăng trễ hơn — nó chỉ leo lên sau khi các truy vấn đã bắt đầu chạy và chồng lên nhau. Chọn metric kết nối cho phản ứng sớm hơn, tránh việc replica mới chỉ sẵn sàng khi đỉnh đã qua.
Ngoài ra Aurora phù hợp với mô tả vì lưu trữ tự co giãn (10 GB → 128 TB) và replica dùng chung volume, nên thêm replica rất nhanh (thường dưới vài phút) và không phải sao chép dữ liệu.
Vì sao các phương án khác sai
- D. Aurora Auto Scaling theo CPU utilization — cùng kiến trúc, chỉ khác metric. Đây là phương án gần nhất, và trong nhiều tình huống nó là lựa chọn đúng. Nhưng với đỉnh đột ngột và ngắn, CPU là chỉ báo trễ; số kết nối phản ánh áp lực đến sớm hơn.
- A. SQS làm đệm + reserved concurrency bằng số kết nối tối đa — hợp lý về mặt kỹ thuật cho việc bảo vệ CSDL, nhưng nó không tăng độ đàn hồi của CSDL chút nào — chỉ giới hạn tốc độ ghi vào. Và nó biến việc đặt hàng thành bất đồng bộ, thay đổi hẳn trải nghiệm người dùng của một storefront.
- B. SNS → SQS → Lambda — thêm một tầng SNS không giải quyết gì: vẫn cùng vấn đề CSDL không co giãn, chỉ thêm một dịch vụ nữa vào đường đi.
Ghi nhớ
Aurora Auto Scaling: | Thuộc tính | Giá trị | |---|---| | Đối tượng | chỉ read replica (không phải writer) | | Số replica | 0 – 15 | | Metric | CPU trung bình hoặc số kết nối trung bình | | Cooldown | mặc định 300 giây mỗi chiều |
Ghi chú về chất lượng câu hỏi
Có một điểm đáng nói mà đáp án nguồn không đề cập: read replica chỉ mở rộng năng lực ĐỌC. Nghiệp vụ mà đề mô tả — "processes orders and stores the orders" — chủ yếu là GHI, và không replica nào giúp được cho ghi.
Nếu đây là bài toán thật, giải pháp đúng nhất cho tải cực kỳ thất thường, gần bằng không lúc rảnh là Aurora Serverless v2: nó co giãn chính năng lực của writer theo ACU và giảm xuống rất thấp khi không có tải — đúng mô tả "goes close to zero during quiet times". Bộ phương án không có lựa chọn đó.
Trong bốn phương án đã cho, C vẫn là lựa chọn hợp lý nhất (Aurora đàn hồi hơn RDS thường, và tự động thêm replica giúp phần đọc của storefront), nhưng nên biết rằng nó không xử lý được nút thắt ghi — chỗ mà đề thật sự mô tả.
A company has an application that logs all information to Amazon S3. Whenever there is a new log file, an AWS Lambda function is invoked to process the log files. The code works, gathering all of the necessary information. However, when checking the Lambda function logs, duplicate entries with the same request ID are found.
What is the BEST explanation for the duplicate entries?
-
A
The application stopped intermittently and then resumed
-
B
The Lambda function failed, and the Lambda service retried the invocation with a delay
-
C
There was an S3 outage, which caused duplicate entries of the same log file
-
D
The S3 bucket name was specified incorrectly
Xem giải thích
Đáp án
B — Hàm Lambda đã thất bại, và dịch vụ Lambda thử lại lần gọi đó sau một khoảng chờ.
Vì sao đúng
Manh mối quyết định nằm ở ba chữ: "same request ID".
Mỗi lần gọi (invocation) có một request ID riêng. Nếu S3 gửi hai sự kiện khác nhau, ta sẽ thấy hai request ID khác nhau. Thấy cùng một request ID xuất hiện nhiều lần nghĩa là cùng một lần gọi đã chạy nhiều lần — tức là thử lại.
Sự kiện S3 gọi Lambda theo kiểu bất đồng bộ, và với kiểu này Lambda có cơ chế thử lại tích hợp sẵn:
Lần gọi thất bại → chờ ~1 phút → thử lại lần 1
→ chờ ~2 phút → thử lại lần 2
→ vẫn hỏng → gửi vào DLQ / on-failure destination (nếu có cấu hình)
Tổng cộng 3 lần chạy cho một sự kiện, và cả ba dùng chung một request ID — nên log có ba mục trùng nhau.
Đây cũng là lý do hàm xử lý sự kiện bất đồng bộ phải idempotent: cùng một sự kiện có thể được xử lý nhiều lần, và mã phải chịu được điều đó.
def lambda_handler(event, context):
ma_su_kien = event['Records'][0]['responseElements']['x-amz-request-id']
if da_xu_ly(ma_su_kien): # kiểm tra trong DynamoDB
return {'status': 'bo qua - da xu ly'}
xu_ly(event)
danh_dau_da_xu_ly(ma_su_kien)
Vì sao các phương án khác sai
- A. Ứng dụng dừng rồi chạy lại — nếu ứng dụng ghi lại tệp log, S3 sẽ tạo sự kiện MỚI và Lambda sinh ra request ID MỚI. Không giải thích được việc trùng request ID.
- C. S3 gặp sự cố gây trùng lặp — cũng vậy: mỗi sự kiện S3 tạo ra một lần gọi riêng với ID riêng. Ngoài ra, S3 event notification được thiết kế at-least-once, nhưng khi nó gửi trùng thì đó vẫn là hai lần gọi khác nhau.
- D. Tên bucket khai sai — sai tên bucket thì không có sự kiện nào tới cả, và hàm sẽ không chạy lần nào. Triệu chứng ngược hẳn với điều đề mô tả.
Ghi nhớ
Cơ chế thử lại theo từng kiểu gọi — bảng này đáng thuộc: | Kiểu gọi | Ví dụ nguồn | Thử lại | |---|---|---| | Đồng bộ | API Gateway, ALB | KHÔNG — lỗi trả thẳng về client | | Bất đồng bộ | S3, SNS, EventBridge | 2 lần thêm (tổng 3), rồi vào DLQ | | Poll-based | SQS, Kinesis, DynamoDB Streams | tới khi hết hạn giữ message hoặc hết số lần cấu hình |
Điều chỉnh số lần thử lại cho gọi bất đồng bộ:
aws lambda put-function-event-invoke-config --function-name xu-ly \
--maximum-retry-attempts 1 \
--maximum-event-age-in-seconds 3600 \
--destination-config '{"OnFailure":{"Destination":"arn:aws:sqs:...:hang-doi-loi"}}'
Nguyên tắc thiết kế quan trọng nhất rút ra từ câu này: mọi hàm Lambda xử lý sự kiện đều phải viết theo hướng idempotent. Không chỉ vì thử lại — mà còn vì hầu hết nguồn sự kiện của AWS đảm bảo at-least-once, tức là có thể gửi trùng ngay cả khi không có lỗi nào.
A Development team would use a GitHub repository and would like to migrate their application code to AWS CodeCommit.
What needs to be created before they can migrate a cloned repository to CodeCommit over HTTPS?
-
A
A set of Git credentials generated with IAM
-
B
A public and private SSH key file
-
C
A GitHub secure authentication token
-
D
An Amazon EC2 IAM role with CodeCommit permissions
Xem giải thích
Đáp án
A — Một bộ Git credentials sinh ra từ IAM.
Vì sao đúng
CodeCommit không dùng tài khoản Git riêng — nó xác thực qua IAM. Với giao thức HTTPS, cách chuẩn là sinh Git credentials cho một IAM user:
IAM Console → Users → chọn user → Security credentials
→ HTTPS Git credentials for AWS CodeCommit → Generate
→ nhận username + password (CHỈ HIỆN MỘT LẦN)
Cặp này dùng như tài khoản Git thông thường:
git clone https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/kho-cua-toi
# Username: ten-user-at-123456789012
# Password: <mật khẩu sinh ra>
Quy trình di trú từ GitHub:
git clone --mirror https://github.com/cong-ty/kho-cu.git kho-tam
cd kho-tam
git remote add codecommit https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/kho-moi
git push codecommit --all
git push codecommit --tags
--mirror giữ toàn bộ nhánh, tag và lịch sử.
IAM user cũng cần policy AWSCodeCommitPowerUser hoặc quyền tương đương.
Vì sao các phương án khác sai
- B. Cặp khoá SSH công khai/riêng tư — cách hợp lệ nhưng cho giao thức KHÁC. Đề nói rõ "over HTTPS". SSH dùng khi bạn tải public key lên IAM user và clone qua
ssh://git-codecommit.... - C. GitHub authentication token — dùng để xác thực với GitHub, không phải với AWS. Sau khi đã clone kho về máy thì token GitHub không còn vai trò gì trong việc đẩy lên CodeCommit.
- D. IAM role gắn vào EC2 với quyền CodeCommit — cách hợp lệ nhưng cho tình huống khác: nó dùng khi thao tác chạy trên một instance EC2 và bạn cài
git-remote-codecommithoặc credential helper để lấy credential tạm thời từ role. Đề mô tả một lập trình viên đẩy kho từ máy của họ.
Ghi nhớ
Bốn cách xác thực với CodeCommit: | Cách | Giao thức | Dùng khi | |---|---|---| | Git credentials (IAM) | HTTPS | đơn giản nhất cho người dùng | | SSH key | SSH | quen dùng SSH, không muốn nhập mật khẩu | | git-remote-codecommit | HTTPS (grc://) | dùng được với IAM role, SSO, MFA | | Credential helper của AWS CLI | HTTPS | trên EC2, CodeBuild — dùng role |
git-remote-codecommit là cách được AWS khuyến nghị hiện nay vì nó hoạt động với role và liên kết danh tính, không cần IAM user cố định:
pip install git-remote-codecommit
git clone codecommit://ho-so-aws@kho-cua-toi
(Ghi chú thời sự: từ tháng 7/2024, AWS ngừng cho khách hàng mới tạo repository trên CodeCommit; các tài khoản đã dùng vẫn tiếp tục hoạt động. Với dự án mới, AWS hướng người dùng sang GitHub, GitLab, hoặc CodeCatalyst. Câu hỏi này vẫn còn giá trị cho kỳ thi và cho các hệ thống đang chạy, nhưng đừng chọn CodeCommit làm nơi lưu mã cho dự án mới.)
An organization is selling memorabilia that is illegal in specific countries. How can a developer restrict access to the website to countries where the memorabilia are illegal?
-
A
Create a Web ACL in AWS WAF with a rule that matches the specified countries and blocks access.
-
B
Create a Web ACL in AWS WAF with a rule that matches the specified countries and triggers an SNS notification.
-
C
Create a Web ACL in AWS Shield with a rule that matches the specified countries and blocks access.
-
D
Create a Web ACL in AWS Shield with a rule that matches the specified countries and triggers an SNS notification.
Xem giải thích
Đáp án
A — Tạo Web ACL trong AWS WAF với rule khớp các quốc gia đó và chặn truy cập.
Vì sao đúng
Có hai quyết định, và mỗi phương án sai hỏng ở một trong hai.
1. Dịch vụ: WAF, không phải Shield. | | AWS WAF | AWS Shield | |---|---|---| | Việc | lọc request theo rule tuỳ chỉnh | chống tấn công DDoS | | Có Web ACL | ✅ | ❌ | | Lọc theo quốc gia | ✅ geo match | ❌ |
Shield không có khái niệm Web ACL — đó là cấu trúc của WAF. Shield Standard tự động bảo vệ chống DDoS tầng 3/4; Shield Advanced thêm giám sát và hỗ trợ, và dùng WAF cho các rule tầng 7.
2. Hành động: chặn, không phải thông báo. Đề nói hàng hoá bất hợp pháp ở các nước đó — vậy phải ngăn truy cập, chứ gửi thông báo thì vi phạm vẫn xảy ra.
{
"Name": "ChanTheoQuocGia",
"Priority": 0,
"Statement": {
"GeoMatchStatement": {
"CountryCodes": ["CN", "RU", "KP"]
}
},
"Action": {"Block": {}}
}
WAF xác định quốc gia bằng cơ sở dữ liệu GeoIP dựa trên địa chỉ IP nguồn, và gắn được vào CloudFront, ALB, API Gateway, AppSync, Cognito user pool.
Vì sao các phương án khác sai
- B. WAF với rule khớp quốc gia rồi gửi thông báo SNS — đúng dịch vụ, sai hành động. WAF có ba action:
Allow,Block,Count. Nó không gửi SNS trực tiếp; muốn cảnh báo thì phải qua CloudWatch metric và alarm. Và dù có gửi được, thông báo không ngăn được truy cập. - C và D. Tạo Web ACL trong AWS Shield — Shield không có Web ACL. Cả hai phương án gán cho Shield một tính năng của WAF.
Ghi nhớ
Bốn loại statement hay dùng của WAF: | Statement | Khớp theo | |---|---| | GeoMatchStatement | quốc gia | | IPSetReferenceStatement | danh sách IP/CIDR | | RateBasedStatement | số request mỗi IP trong 5 phút | | ByteMatchStatement | chuỗi trong header, body, URI |
Ba action: | Action | Kết quả | |---|---| | Block | từ chối, mặc định trả 403 | | Allow | cho qua | | Count | chỉ đếm, không chặn — dùng để thử rule trước khi bật thật |
Mẹo triển khai an toàn: luôn bật rule mới ở chế độ Count trước, xem metric vài ngày để biết nó sẽ chặn nhầm những gì, rồi mới chuyển sang Block. Chặn nhầm cả một quốc gia là sự cố rất khó phát hiện từ phía bạn — người dùng ở đó chỉ đơn giản là không vào được và không ai báo cho bạn biết.
Và một hạn chế cần biết về geo blocking: VPN và proxy vượt qua được dễ dàng. Nó là biện pháp tuân thủ pháp lý ("chúng tôi đã có nỗ lực hợp lý để chặn"), không phải biện pháp bảo mật chống lại người cố tình vượt rào.
A Developer has used a third-party tool to build, bundle, and package a software package on-premises. The software package is stored in a local file system and must be deployed to Amazon EC2 instances.
How can the application be deployed onto the EC2 instances?
-
A
Upload the bundle to an Amazon S3 bucket and specify the S3 location when doing a deployment using AWS CodeDeploy.
-
B
Use AWS CodeBuild to commit the package and automatically deploy the software package.
-
C
Use AWS CodeDeploy and point it to the local file system to deploy the software package.
-
D
Create a repository using AWS CodeCommit to automatically trigger a deployment to the EC2 instances.
Xem giải thích
Đáp án
A — Tải gói lên S3 bucket và chỉ định vị trí S3 đó khi triển khai bằng CodeDeploy.
Vì sao đúng
Điểm mấu chốt: CodeDeploy chỉ lấy gói triển khai từ hai nơi — Amazon S3 hoặc GitHub. Không có nguồn nào khác.
Gói đang nằm trên file system tại chỗ, nên bước bắt buộc là đưa nó lên S3:
# Đóng gói cùng appspec.yml rồi đẩy lên S3
aws deploy push \
--application-name UngDungCuaToi \
--s3-location s3://kho-trien-khai/ung-dung.zip \
--source /duong/dan/goi-phan-mem
# Triển khai
aws deploy create-deployment \
--application-name UngDungCuaToi \
--deployment-group-name NhomProduction \
--s3-location bucket=kho-trien-khai,key=ung-dung.zip,bundleType=zip
Lệnh aws deploy push tiện ở chỗ nó đóng gói và tải lên trong một bước, đồng thời in ra sẵn lệnh create-deployment tương ứng.
Gói phải chứa appspec.yml ở thư mục gốc để CodeDeploy biết đặt tệp ở đâu và chạy script gì:
version: 0.0
os: linux
files:
- source: /
destination: /var/www/ung-dung
hooks:
ApplicationStop: [{location: scripts/dung.sh}]
AfterInstall: [{location: scripts/cai-dat.sh}]
ApplicationStart: [{location: scripts/khoi-dong.sh}]
ValidateService: [{location: scripts/kiem-tra.sh}]
Điểm hay của phương án này: nó giữ nguyên công cụ build của bên thứ ba — bạn không phải chuyển sang CodeBuild hay đổi quy trình đóng gói.
Vì sao các phương án khác sai
- C. Trỏ CodeDeploy vào file system tại chỗ — không làm được. CodeDeploy agent chạy trên các instance đích và tự tải gói về từ S3 hoặc GitHub; nó không có cách nào đọc ổ đĩa trên máy của lập trình viên.
- B. Dùng CodeBuild để "commit gói và tự động triển khai" — hiểu sai chức năng: CodeBuild BIÊN DỊCH và ĐÓNG GÓI mã nguồn, nó không commit gì và không triển khai gì. Ngoài ra, gói đã được dựng sẵn bằng công cụ bên thứ ba — không cần dựng lại.
- D. Tạo repository CodeCommit để "tự động kích hoạt triển khai" — CodeCommit lưu mã nguồn, không phải gói đã dựng. Và bản thân nó không kích hoạt triển khai; muốn vậy phải có CodePipeline ở giữa. Đây cũng là cách làm sai: đưa tệp nhị phân đã đóng gói vào kho Git là thực hành kém.
Ghi nhớ
Nguồn gói triển khai của CodeDeploy: | Nguồn | Hỗ trợ | |---|---| | Amazon S3 | ✅ | | GitHub | ✅ | | Bitbucket, GitLab | ❌ (phải qua CodePipeline) | | File system tại chỗ | ❌ |
Ba nền tảng đích và định dạng gói tương ứng: | Nền tảng | Gói | |---|---| | EC2 / On-premises | ZIP, tar, tar.gz + appspec.yml | | ECS | appspec.yaml trỏ tới task definition | | Lambda | appspec.yaml trỏ tới version của hàm |
Và điều kiện để instance nhận được triển khai:
- Đã cài CodeDeploy agent
- Có IAM instance profile với quyền đọc bucket S3 đó
- Được gắn tag khớp với deployment group