Ngân hàng đề — AWS Certified Developer Associate
Tìm thấy 1356 câu.
An application uses both Amazon EC2 instances and on-premises servers. The on-premises servers are a critical component of the application, and a developer wants to collect metrics and logs from these servers. The developer would like to use Amazon CloudWatch.
How can the developer accomplish this?
-
A
Install an AWS SDK on the on-premises servers that automatically sends logs to CloudWatch.
-
B
Install the CloudWatch agent on the on-premises servers and specify IAM credentials with permissions to CloudWatch.
-
C
Install the CloudWatch agent on the on-premises servers and specify an IAM role with permissions to CloudWatch.
-
D
Write a batch script that uses system utilities to collect performance metrics and application logs. Upload the metrics and logs to CloudWatch.
Xem giải thích
Đáp án
B — Cài CloudWatch agent trên máy chủ on-premises và khai IAM credentials có quyền với CloudWatch.
Vì sao đúng
Điểm mấu chốt: máy chủ ngoài AWS không thể dùng instance profile.
Instance profile hoạt động dựa trên Instance Metadata Service — một endpoint nội bộ (169.254.169.254) chỉ tồn tại trên EC2. Máy chủ trong trung tâm dữ liệu của bạn không có endpoint đó, nên không có cách nào tự lấy credential.
Vì vậy phải cấp credential tường minh. Quy trình chuẩn:
# 1. Trên AWS: tạo IAM user riêng cho việc này
aws iam create-user --user-name may-chu-on-prem
aws iam attach-user-policy --user-name may-chu-on-prem \
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
aws iam create-access-key --user-name may-chu-on-prem
# 2. Trên máy chủ on-premises: khai credential vào profile riêng
# /root/.aws/credentials
# [AmazonCloudWatchAgent]
# aws_access_key_id = AKIA...
# aws_secret_access_key = ...
# 3. Chạy agent với profile đó
amazon-cloudwatch-agent-ctl -a fetch-config -m onPremise \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/config.json -s
Chú ý cờ -m onPremise: agent có hai chế độ, và chế độ này bảo nó đọc credential từ tệp thay vì hỏi metadata service.
CloudWatch agent gửi được cả metric lẫn log — đúng cả hai thứ đề yêu cầu:
{
"metrics": {"metrics_collected": {
"mem": {"measurement": ["mem_used_percent"]},
"disk": {"measurement": ["used_percent"], "resources": ["/"]}}},
"logs": {"logs_collected": {"files": {"collect_list": [
{"file_path": "/var/log/ung-dung/*.log",
"log_group_name": "/on-prem/ung-dung"}]}}}
}
Vì sao các phương án khác sai
- C. Cài agent và khai IAM role — đây là bẫy chính, và nó chỉ khác đáp án đúng một từ. Máy chủ on-premises không assume được IAM role trực tiếp như EC2 làm — không có metadata service để lấy credential. (Có hai cách hiện đại để dùng role ngoài AWS: IAM Roles Anywhere với chứng chỉ X.509, và SSM hybrid activation. Cả hai đều cần thiết lập thêm và không phải điều phương án C mô tả.)
- A. Cài AWS SDK để "tự động gửi log lên CloudWatch" — SDK là thư viện lập trình, nó không tự thu thập hay gửi gì. Nó chỉ cung cấp hàm để mã của bạn gọi — bạn vẫn phải tự viết toàn bộ logic đọc tệp log và gửi lên.
- D. Viết script batch tự thu thập metric và log rồi tải lên — chạy được nhưng nhiều việc nhất: bạn phải tự thu thập, tự gom lô, tự xử lý lỗi và thử lại, tự xoay vòng vị trí đọc tệp. CloudWatch agent làm sẵn tất cả và được AWS bảo trì.
Ghi nhớ
Cách cấp quyền AWS theo nơi mã chạy: | Nơi chạy | Cơ chế | |---|---| | EC2 | instance profile | | Lambda | execution role | | ECS / Fargate | task role | | On-premises (cách cổ điển) | IAM user + access key | | On-premises (cách hiện đại) | IAM Roles Anywhere hoặc SSM hybrid activation |
Hai cách hiện đại đáng biết vì chúng loại bỏ access key dài hạn:
- IAM Roles Anywhere: máy chủ dùng chứng chỉ X.509 từ CA tin cậy để đổi lấy credential tạm thời.
- SSM hybrid activation: đăng ký máy chủ vào Systems Manager, máy nhận định danh
mi-xxxxxvà dùng được role như EC2 — đồng thời quản lý được bằng Run Command, Patch Manager.
Nếu buộc phải dùng access key, ba biện pháp giảm rủi ro:
- IAM user riêng cho từng mục đích, quyền tối thiểu (
CloudWatchAgentServerPolicy). - Xoay vòng khoá định kỳ và giám sát bằng IAM Access Advisor.
- Đặt điều kiện
aws:SourceIptrong policy để khoá chỉ dùng được từ dải IP của văn phòng.
A company runs an application on a fleet of web servers running on Amazon EC2 instances. The web servers are behind an Elastic Load Balancer (ELB) and use an Amazon DynamoDB table for storing session state. A Developer has been asked to implement a mechanism for automatically deleting session state data that is older than 24 hours.
What is the SIMPLEST solution to this requirement?
-
A
Add an attribute with the expiration time; name the attribute ItemExpiration
-
B
Write a script that deletes old records; schedule the scripts as a cron job on an Amazon EC2 instance
-
C
Each day, create a new table to hold session data; delete the previous day's table
-
D
Add an attribute with the expiration time; enable the Time To Live feature based on that attribute
Xem giải thích
Đáp án
D — Thêm một thuộc tính chứa thời điểm hết hạn và bật tính năng Time To Live (TTL) dựa trên thuộc tính đó.
Vì sao đúng
DynamoDB có sẵn tính năng TTL cho đúng nhu cầu này: tự động xoá item khi tới thời điểm hết hạn, hoàn toàn miễn phí.
Bật bằng một lời gọi:
aws dynamodb update-time-to-live \
--table-name phien-lam-viec \
--time-to-live-specification "Enabled=true, AttributeName=het_han"
Rồi khi ghi session, kèm theo mốc hết hạn:
import time
table.put_item(Item={
'session_id': sid,
'du_lieu': du_lieu,
'het_han': int(time.time()) + 86400 # 24 giờ sau
})
Ba đặc điểm khiến đây là giải pháp đơn giản nhất: | Đặc điểm | Chi tiết | |---|---| | Miễn phí | việc xoá KHÔNG tốn WCU nào | | Không cần hạ tầng | không có script, không có máy chủ, không có lịch | | Không ảnh hưởng hiệu năng | chạy nền, không tranh throughput với ứng dụng |
Định dạng bắt buộc: giá trị phải là Unix epoch tính bằng GIÂY, kiểu Number. Dùng mili giây hoặc chuỗi ISO 8601 thì TTL im lặng bỏ qua item đó — một lỗi rất khó phát hiện vì không có thông báo nào.
Và một lưu ý về thời gian: TTL xoá item trong vòng vài ngày sau thời điểm hết hạn, không phải đúng giây. Nếu ứng dụng không được phép thấy session đã hết hạn, hãy lọc thêm ở tầng đọc:
if item['het_han'] < time.time():
return None # coi như đã hết hạn dù chưa bị xoá
Vì sao các phương án khác sai
- A. Thêm thuộc tính hết hạn tên
ItemExpiration— thiếu bước quan trọng nhất: chỉ thêm thuộc tính mà không bật TTL thì nó chỉ là một con số nằm im, không có gì xoá item cả. (Tên thuộc tính không quan trọng — bạn khai tên nào cũng được khi bật TTL.) - B. Viết script xoá bản ghi cũ, chạy bằng cron trên EC2 — chạy được nhưng nhiều việc nhất: phải nuôi một EC2, viết và bảo trì script, và quét bảng để tìm bản ghi cũ sẽ tốn RCU rất lớn, còn xoá tốn WCU. Trái hẳn yêu cầu "SIMPLEST".
- C. Mỗi ngày tạo bảng mới, xoá bảng của ngày hôm trước — phức tạp và dễ hỏng: ứng dụng phải biết đang ghi vào bảng nào, phải xử lý thời điểm chuyển giao giữa hai ngày, và session tạo lúc 23:59 sẽ bị xoá sau vài phút thay vì sau 24 giờ.
Ghi nhớ
Yêu cầu để TTL hoạt động: | Yêu cầu | Chi tiết | |---|---| | Kiểu dữ liệu | Number | | Định dạng | Unix epoch tính bằng GIÂY | | Bật ở mức bảng | chỉ định tên thuộc tính | | Item thiếu thuộc tính đó | không bao giờ bị xoá | | Giá trị quá 5 năm trong quá khứ | bị bỏ qua |
Ba điều đáng biết thêm:
- Item bị TTL xoá vẫn xuất hiện trong DynamoDB Streams, với
userIdentity.principalId = "dynamodb.amazonaws.com"— nên bạn lưu trữ được dữ liệu hết hạn sang S3 hoặc xử lý hậu kỳ trước khi mất hẳn. - Item đã hết hạn nhưng chưa bị xoá vẫn xuất hiện trong
QueryvàScan— nhớ lọc ở tầng ứng dụng nếu cần chính xác. - TTL không đảm bảo thời điểm — thường trong vài giờ, nhưng AWS chỉ cam kết "trong vài ngày".
Các dịch vụ khác cũng có TTL tương tự, đáng nhớ để so sánh: | Dịch vụ | Cơ chế hết hạn | |---|---| | DynamoDB | thuộc tính TTL | | ElastiCache Redis | EXPIRE / SETEX | | S3 | lifecycle rule | | CloudWatch Logs | retention policy | | SQS | MessageRetentionPeriod |
A Development team has deployed several applications running on an Auto Scaling fleet of Amazon EC2 instances. The Operations team have asked for a display that shows a key performance metric for each application on a single screen for monitoring purposes.
What steps should a Developer take to deliver this capability using Amazon CloudWatch?
-
A
Create a custom alarm with a unique metric name for each application
-
B
Create a custom event with a unique metric name for each application
-
C
Create a custom dimension with a unique metric name for each application
-
D
Create a custom namespace with a unique metric name for each application
Xem giải thích
Đáp án
D — Tạo một custom namespace với tên metric riêng cho mỗi ứng dụng.
Vì sao đúng
Yêu cầu: hiển thị một metric quan trọng của MỖI ứng dụng trên cùng một màn hình.
Namespace là cơ chế phân nhóm cấp cao nhất của CloudWatch — nó tạo ra không gian tên riêng biệt cho metric, đảm bảo metric của các ứng dụng khác nhau không lẫn vào nhau dù trùng tên:
Namespace: UngDung/BanHang → metric "DonHangDangCho"
Namespace: UngDung/KhoVan → metric "DonHangDangCho" ← cùng tên, khác namespace
Namespace: UngDung/ThanhToan → metric "GiaoDichLoi"
Không có namespace riêng, hai metric cùng tên từ hai ứng dụng sẽ bị trộn thành một chuỗi dữ liệu — và biểu đồ trở nên vô nghĩa.
Đăng metric:
aws cloudwatch put-metric-data \
--namespace "UngDung/BanHang" \
--metric-name "DonHangDangCho" \
--value 42 --unit Count
Rồi gom tất cả lên một dashboard:
{
"widgets": [{
"type": "metric",
"properties": {
"metrics": [
["UngDung/BanHang", "DonHangDangCho"],
["UngDung/KhoVan", "DonHangDangCho"],
["UngDung/ThanhToan", "GiaoDichLoi"]
],
"title": "Chỉ số chính của các ứng dụng"
}
}]
}
Một dashboard hiển thị được tới 500 metric, thừa sức cho nhu cầu trong đề.
Vì sao các phương án khác sai
- C. Tạo custom dimension với tên metric riêng cho mỗi ứng dụng — đây là phương án gần nhất và đáng phân tích. Dimension cũng phân tách metric được (
Application=BanHang), và trong nhiều trường hợp nó là cách làm hợp lý. Nhưng dimension dùng để phân mảnh MỘT metric theo các chiều (theo instance, theo môi trường, theo Region), còn ở đây các ứng dụng là những hệ thống độc lập với metric khác nhau — namespace mới là ranh giới đúng. (Và nhớ: mỗi tổ hợp dimension là một custom metric riêng và một khoản phí riêng.) - A. Tạo custom alarm — alarm kích hoạt hành động khi vượt ngưỡng. Nó không phải cơ chế tổ chức metric, và một màn hình đầy alarm không phải là dashboard theo dõi.
- B. Tạo custom event — event thuộc về EventBridge, dùng để kích hoạt hành động khi có sự kiện. Không liên quan tới việc tổ chức và hiển thị metric.
Ghi nhớ
Cấu trúc phân cấp của metric trong CloudWatch:
Namespace (AWS/EC2, UngDung/BanHang)
└── Metric name (CPUUtilization, DonHangDangCho)
└── Dimensions (InstanceId=i-123, MoiTruong=prod)
└── Datapoints (giá trị theo thời gian)
Khi nào dùng cái nào: | Nhu cầu | Cơ chế | |---|---| | Tách các ứng dụng/hệ thống độc lập | namespace | | Tách các thể hiện của cùng một thứ | dimension | | Cảnh báo khi vượt ngưỡng | alarm | | Hiển thị nhiều metric cùng lúc | dashboard |
Quy ước đặt tên namespace:
- Namespace của AWS luôn bắt đầu bằng
AWS/—AWS/EC2,AWS/Lambda,AWS/DynamoDB. Đừng dùng tiền tố này cho metric của bạn. - Namespace tuỳ chỉnh nên có cấu trúc:
CongTy/MoiTruong/UngDung.
Ba lưu ý về chi phí và giới hạn: | Điểm | Chi tiết | |---|---| | Mỗi tổ hợp dimension = một custom metric | tính phí riêng | | Tối đa 30 dimension mỗi metric | — | | Dashboard: 500 metric mỗi widget | — | | Ba dashboard đầu tiên | miễn phí |
Vì vậy hãy cẩn thận với dimension có nhiều giá trị (như user_id) — nó có thể sinh ra hàng nghìn custom metric và hoá đơn tăng vọt.
A company wants a serverless solution for phased release of static websites hosted on various version control systems. Deployments should be triggered by Git branch merges and all data exchange should be over HTTPS.
Which option offers the LOWEST operational overhead?
-
A
Deploy websites on separate Amazon EC2 instances for each environment, use AWS CodeDeploy for automation, and link it with the version control systems.
-
B
Use AWS Amplify for hosting, connect corresponding repository branches, and initiate deployments by merging changes to the needed branch.
-
C
Use AWS Elastic Beanstalk for hosting and use AWS CodeStar to manage deployments and workflows.
-
D
Use Amazon S3 to host the websites, create a manual script to deploy changes when there are code merges in the version control systems.
Xem giải thích
Đáp án
B — Dùng AWS Amplify để lưu trữ, nối các nhánh tương ứng của kho mã, và kích hoạt triển khai bằng cách merge vào nhánh cần thiết.
Vì sao đúng
Đề nêu bốn yêu cầu, và Amplify đáp ứng cả bốn mà không cần vận hành gì:
- Serverless — không có máy chủ nào để quản lý
- Phát hành theo giai đoạn cho website tĩnh
- Triển khai kích hoạt bởi merge nhánh Git
- Mọi trao đổi dữ liệu qua HTTPS
Amplify Hosting ánh xạ mỗi nhánh Git thành một môi trường có URL riêng, và tự triển khai khi có commit mới:
Nhánh dev → https://dev.d1a2b3c4.amplifyapp.com
Nhánh staging → https://staging.d1a2b3c4.amplifyapp.com
Nhánh main → https://main.d1a2b3c4.amplifyapp.com (production)
Đó chính là phát hành theo giai đoạn: merge vào staging để kiểm thử, rồi merge vào main để phát hành.
Về vế "various version control systems" — Amplify nối được với GitHub, GitLab, Bitbucket, AWS CodeCommit, nên đáp ứng yêu cầu nhiều hệ thống quản lý mã.
Và HTTPS là mặc định, không cấu hình gì: mọi ứng dụng Amplify tự có chứng chỉ TLS, kể cả khi gắn tên miền riêng (Amplify tự xin và tự gia hạn chứng chỉ ACM).
Các tính năng đi kèm khiến gánh nặng vận hành gần bằng không: | Tính năng | Chi tiết | |---|---| | CDN toàn cầu | dựa trên CloudFront, tự động | | Pull request preview | mỗi PR có URL tạm riêng | | Atomic deployment | triển khai hỏng thì không có trạng thái nửa vời | | Rollback một cú bấm | về bản build trước | | Password protection | bảo vệ môi trường không phải production |
Vì sao các phương án khác sai
- A. EC2 riêng cho mỗi môi trường + CodeDeploy — gánh nặng vận hành cao nhất: nhiều instance phải vá, phải giám sát, phải cấu hình TLS thủ công, và trả tiền liên tục kể cả khi không ai truy cập. Trái hẳn yêu cầu "serverless" và "LOWEST operational overhead".
- C. Elastic Beanstalk + CodeStar — Beanstalk chạy trên EC2, nên không serverless và vẫn phải trả tiền theo giờ. Ngoài ra nó là nền tảng cho ứng dụng có máy chủ, quá nặng cho website tĩnh. (Và AWS CodeStar đã ngừng hoạt động từ 31/7/2024 — không tạo project mới được nữa.)
- D. S3 + script thủ công — S3 hosting thì serverless và rẻ, nhưng "manual script" vi phạm yêu cầu tự động hoá: bạn phải tự viết và tự bảo trì đường ống triển khai. Thêm nữa, S3 static website endpoint không hỗ trợ HTTPS — phải đặt CloudFront phía trước, tức là thêm việc cấu hình.
Ghi nhớ
So sánh các cách host website tĩnh trên AWS: | Cách | Vận hành | HTTPS | CI/CD | |---|---|---|---| | Amplify Hosting | gần như không | tự động | tích hợp sẵn | | S3 + CloudFront | thấp | phải cấu hình | tự dựng | | EC2 / Beanstalk | cao | tự cấu hình | tự dựng |
Nhận dạng nhanh: đề nói "static website", "triggered by Git merges", "lowest operational overhead" ⇒ Amplify.
Quy trình làm việc điển hình với Amplify:
feature/abc → PR preview URL tự sinh
↓ merge
dev → môi trường dev
↓ merge
staging → môi trường kiểm thử
↓ merge
main → production (gắn tên miền thật)
Hai lưu ý thực tế:
- Biến môi trường khai riêng cho từng nhánh — nên nhánh dev tự trỏ vào API của môi trường dev.
- Nếu ứng dụng có backend, dùng
amplify env addđể mỗi môi trường có tài nguyên AWS riêng. Tách frontend mà quên tách backend là để nhánh dev ghi thẳng vào dữ liệu production — sai lầm phổ biến nhất khi dùng Amplify.
A legacy service has an XML-based SOAP interface. The Developer wants to expose the functionality of the service to external clients with the Amazon API Gateway. Which technique will accomplish this?
-
A
Create a RESTful API with the API Gateway; transform the incoming XML into a valid message for the SOAP interface using mapping templates
-
B
Create a RESTful API with the API Gateway; pass the incoming XML to the SOAP interface through an Application Load Balancer
-
C
Create a RESTful API with the API Gateway; pass the incoming JSON to the SOAP interface through an Application Load Balancer
-
D
Create a RESTful API with the API Gateway; transform the incoming JSON into a valid XML message for the SOAP interface using mapping templates
Xem giải thích
Đáp án
D — Tạo RESTful API với API Gateway, dùng mapping template biến JSON đầu vào thành XML hợp lệ cho giao diện SOAP.
Vì sao đúng
Có hai chi tiết phải đúng, và các phương án sai đều hỏng ở một trong hai.
1. Chiều biến đổi: JSON → XML. Client bên ngoài gửi JSON (chuẩn hiện đại cho REST API), còn hệ thống cũ cần XML/SOAP. Nên chiều biến đổi là JSON vào, XML ra phía backend.
2. Công cụ: mapping template. Đây là tính năng biến đổi payload bằng VTL, chạy ngay trong API Gateway:
## Integration request: JSON của khách → XML cho SOAP
#set($inputRoot = $input.path('$'))
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TraCuuDonHang xmlns="http://example.com/">
<MaDon>$util.escapeJavaScript($inputRoot.maDon)</MaDon>
</TraCuuDonHang>
</soap:Body>
</soap:Envelope>
Và integration response làm chiều ngược lại — XML từ SOAP về JSON cho khách.
Kết quả: khách hàng bên ngoài chỉ thấy một REST API JSON hiện đại, còn hệ thống cũ không phải sửa một dòng nào. Mẫu này gọi là façade hay anti-corruption layer.
Vì sao các phương án khác sai
- A. REST API, biến đổi XML đầu vào thành message cho SOAP — sai chiều: nếu client đã gửi XML thì phần lớn giá trị của việc đặt API Gateway ở giữa biến mất. Mục đích của bài toán này là cho phép client dùng JSON, che giấu SOAP đi.
- C. REST API, chuyển JSON tới SOAP qua Application Load Balancer — chiều đúng nhưng công cụ sai: ALB không biến đổi payload. Nó định tuyến theo host/path và chuyển tiếp nguyên vẹn — SOAP endpoint sẽ nhận JSON và từ chối.
- B. REST API, chuyển XML tới SOAP qua ALB — sai cả hai vế: sai chiều và ALB không biến đổi được gì.
Ghi nhớ
Mapping template trong API Gateway: | Vị trí | Biến đổi | |---|---| | Integration Request | request của client → định dạng backend cần | | Integration Response | response của backend → định dạng client cần |
Các biến VTL hay dùng:
$input.path('$.field') ## đọc một trường từ body
$input.json('$') ## toàn bộ body dạng JSON
$input.params('ten') ## path, query, hoặc header
$context.requestId ## thông tin request
$util.escapeJavaScript(...) ## THOÁT KÝ TỰ cho dữ liệu người dùng
Dòng cuối rất quan trọng: thiếu nó, một giá trị chứa dấu < hoặc & sẽ phá vỡ cấu trúc XML — lỗi chỉ lộ ra với dữ liệu bất thường, rất khó tìm.
Điều kiện tiên quyết: phải dùng Lambda/HTTP integration kiểu non-proxy. Với proxy integration, API Gateway chuyển nguyên request và mapping template không chạy.
Nhận dạng nhanh trong đề: | Đề nói | Chọn | |---|---| | "transform", "convert" giữa hai định dạng | mapping template | | "pass through", "forward entire request" | proxy integration | | "định tuyến theo host hoặc path" | ALB |
Và nhớ: API Gateway không có loại API nào tên là "SOAP API" — chỉ có REST API, HTTP API và WebSocket API. Phương án nào nhắc tới "SOAP API" trong API Gateway đều sai.
To include objects defined by the AWS Serverless Application Model (SAM) in an AWS CloudFormation template, in addition to Resources, what section MUST be included in the document root?
-
A
Properties
-
B
Globals
-
C
Conditions
-
D
Transform
Xem giải thích
Đáp án
D — Phần Transform.
Vì sao đúng
Transform là dòng báo cho CloudFormation biết template có dùng cú pháp rút gọn của SAM, và phải biến đổi nó thành tài nguyên CloudFormation thật trước khi triển khai:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31 # ← BẮT BUỘC
Resources:
HamCuaToi:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs20.x
Nếu thiếu dòng đó, CloudFormation coi AWS::Serverless::Function là một loại tài nguyên không tồn tại và từ chối template ngay.
Việc biến đổi diễn ra ở phía AWS, và nó mở rộng ra rất nhiều: một khối AWS::Serverless::Function mười dòng sinh ra hàm Lambda, IAM role, log group, quyền gọi hàm, và cả API Gateway nếu có khai Events. Đó là toàn bộ giá trị của SAM — bạn viết mười dòng thay vì trăm dòng.
Xem trước kết quả biến đổi:
sam validate --debug
aws cloudformation get-template-summary --template-body file://template.yaml
Vì sao các phương án khác sai
- B.
Globals— là phần riêng của SAM dùng để khai cấu hình mặc định dùng chung cho mọi hàm, tránh lặp lại:
Rất hữu ích, nhưng hoàn toàn tuỳ chọn — bỏ đi thì template vẫn chạy. Đề hỏi phần BẮT BUỘC.Globals: Function: Runtime: nodejs20.x Timeout: 30 MemorySize: 512 - C.
Conditions— phần chuẩn của CloudFormation để tạo tài nguyên có điều kiện (ví dụ chỉ tạo ở môi trường production). Cũng tuỳ chọn, và không liên quan tới SAM. - A.
Properties— không phải một phần ở gốc template. Nó là thuộc tính của từng tài nguyên, nằm bên trongResources.
Ghi nhớ
Các phần ở gốc của một template CloudFormation: | Phần | Bắt buộc | |---|---| | Resources | ✅ luôn bắt buộc | | Transform | ✅ bắt buộc VỚI SAM | | AWSTemplateFormatVersion | ❌ (nhưng nên có) | | Description, Metadata | ❌ | | Parameters, Mappings, Conditions | ❌ | | Outputs | ❌ | | Globals | ❌ (chỉ có ở SAM) |
Hai loại Transform hay gặp: | Giá trị | Việc | |---|---| | AWS::Serverless-2016-10-31 | kích hoạt cú pháp SAM | | AWS::Include | chèn một đoạn template từ S3 — tái sử dụng khối chung |
Chuỗi ngày tháng 2016-10-31 là phiên bản của macro SAM, không phải ngày bạn tạo template — nó cố định và luôn viết y như vậy.
Ba lỗi hay gặp với template SAM:
- Quên
Transform— báo lỗi "Unrecognized resource type". - Viết thiếu dấu hai chấm:
AWS::Serverless:Functionthay vìAWS::Serverless::Function. - Quên
--capabilities CAPABILITY_IAMkhi deploy — SAM tự tạo IAM role, nên CloudFormation đòi bạn xác nhận tường minh:
aws cloudformation deploy --template-file da-dong-goi.yaml \
--stack-name ung-dung --capabilities CAPABILITY_IAM
A Developer is designing a fault-tolerant environment where client sessions will be saved. How can the Developer ensure that no sessions are lost if an Amazon EC2 instance fails?
-
A
Use Amazon DynamoDB to perform scalable session handling
-
B
Use Elastic Load Balancer connection draining to stop sending requests to failing instances
-
C
Use Amazon SQS to save session data
-
D
Use sticky sessions with an Elastic Load Balancer target group
Xem giải thích
Đáp án
A — Dùng Amazon DynamoDB để lưu session một cách co giãn.
Vì sao đúng
Nguyên tắc nền tảng của kiến trúc chịu lỗi: tầng web phải phi trạng thái. Nếu session nằm trong bộ nhớ của EC2, thì instance hỏng = mọi người dùng đang được nó phục vụ bị đăng xuất.
Cách chữa là đưa session ra kho lưu trữ bên ngoài, để mọi instance đều phục vụ được mọi người dùng:
Client → ELB → EC2 (BẤT KỲ máy nào, phi trạng thái)
↓ đọc/ghi session
DynamoDB (đa AZ, bền, tự co giãn)
DynamoDB phù hợp vì: | Đặc điểm | Chi tiết | |---|---| | Bền vững | nhân bản đồng bộ trên 3 AZ | | Không có gì để quản lý | không có cụm, không có node để vá | | Nhanh | độ trễ mili giây một chữ số | | TTL | tự xoá session hết hạn, miễn phí | | Co giãn | on-demand hoặc auto scaling |
Tính năng TTL đặc biệt hợp với session — không cần job dọn dẹp nào:
table.put_item(Item={
'session_id': sid,
'du_lieu': du_lieu,
'het_han': int(time.time()) + 3600 # DynamoDB tự xoá sau 1 giờ
})
AWS còn cung cấp sẵn DynamoDB Session Handler cho PHP và Tomcat SessionStore, dùng được với thay đổi cấu hình tối thiểu.
Vì sao các phương án khác sai
- D. Dùng sticky session với target group của ELB — đây là bẫy chính, và nó đi ngược yêu cầu: sticky session ghim mỗi người dùng vào đúng instance đang giữ session của họ. Khi instance đó hỏng, session mất hoàn toàn — đúng thứ đề muốn tránh. Nó chỉ che vấn đề đi chứ không giải quyết.
- B. Dùng connection draining để ngừng gửi request tới instance đang hỏng — connection draining (nay gọi là deregistration delay) cho phép các kết nối đang dở được hoàn tất trước khi instance bị gỡ khỏi target group. Hữu ích khi chủ động gỡ máy ra, nhưng vô dụng khi instance hỏng đột ngột — và nó không lưu session ở đâu cả.
- C. Dùng SQS để lưu session — sai bản chất dịch vụ: SQS là hàng đợi tin nhắn, message bị xoá sau khi xử lý và không truy cập ngẫu nhiên theo khoá được. Không có cách nào đọc "session của người dùng X".
Ghi nhớ
Các lựa chọn lưu session bên ngoài: | Kho | Độ trễ | Bền | Chọn khi | |---|---|---|---| | ElastiCache Redis | thấp nhất — dưới mili giây | vừa (bật persistence được) | cần nhanh nhất | | DynamoDB | mili giây một chữ số | rất bền, đa AZ | cần bền, có TTL, không quản lý | | RDS | cao hơn | bền | quá nặng cho session |
Cả hai lựa chọn đầu đều đúng về mặt kiến trúc; cách chọn phụ thuộc vào từ khoá trong đề:
- "lowest latency", "fastest" ⇒ ElastiCache Redis
- "durable", "fault tolerant", "no management" ⇒ DynamoDB ← câu này
Ba thứ không bao giờ dùng làm kho session: | Không dùng | Vì sao | |---|---| | Bộ nhớ hoặc ổ đĩa cục bộ của instance | mất khi instance được thay | | Instance store | mất khi instance dừng | | Sticky session làm giải pháp duy nhất | không sống sót qua sự cố instance |
(Sticky session vẫn hữu ích như tối ưu bổ sung khi đã có kho session ngoài — nó giúp tận dụng cache cục bộ và giảm số lần đọc. Nhưng nó không thay thế được kho chia sẻ, và câu hỏi kiểu này luôn hỏi về cái thay thế.)
A company is planning to use AWS CodeDeploy to deploy a new AWS Lambda function
What are the MINIMUM properties required in the 'resources' section of the AppSpec file for CodeDeploy to deploy the function successfully?
-
A
name, alias, currentversion, and targetversion
-
B
name, alias, PlatformVersion, and type
-
C
TaskDefinition, LoadBalancerInfo, and ContainerPort
-
D
TaskDefinition, PlatformVersion, and ContainerName
Xem giải thích
Đáp án
A — name, alias, currentversion, và targetversion.
Vì sao đúng
Với nền tảng Lambda, CodeDeploy làm đúng một việc: chuyển alias từ version cũ sang version mới. Nên phần resources của AppSpec chỉ cần đủ thông tin cho việc đó:
version: 0.0
Resources:
- HamXuLyDonHang:
Type: AWS::Lambda::Function
Properties:
Name: "ham-xu-ly-don-hang" # hàm nào
Alias: "prod" # alias nào sẽ được chuyển
CurrentVersion: "3" # đang trỏ vào đâu
TargetVersion: "4" # sẽ trỏ sang đâu
Hooks:
- BeforeAllowTraffic: "ham-kiem-thu-truoc"
- AfterAllowTraffic: "ham-kiem-thu-sau"
Bốn thuộc tính này là tối thiểu và bắt buộc — bỏ bất kỳ cái nào thì CodeDeploy không biết phải làm gì.
| Thuộc tính | Vai trò |
|---|---|
Name |
hàm Lambda nào |
Alias |
con trỏ nào được cập nhật |
CurrentVersion |
để rollback về đúng chỗ |
TargetVersion |
version mới cần chuyển sang |
CurrentVersion quan trọng hơn vẻ ngoài: nó là thứ CodeDeploy dùng để quay lại chính xác trạng thái cũ nếu triển khai thất bại — và cũng là thứ giữ traffic trong lúc chuyển dần theo canary hay linear.
Việc chuyển traffic không xảy ra tức thì nếu bạn chọn cấu hình khác AllAtOnce:
LambdaCanary10Percent5Minutes → 10% trong 5 phút, rồi 90%
LambdaLinear10PercentEvery1Minute → tăng 10% mỗi phút
LambdaAllAtOnce → chuyển 100% ngay
Vì sao các phương án khác sai
- C.
TaskDefinition,LoadBalancerInfo,ContainerPortvà D.TaskDefinition,PlatformVersion,ContainerName— đây là các thuộc tính của AppSpec cho Amazon ECS, không phải Lambda. Chúng khai task definition nào và container nào nhận traffic từ load balancer — những khái niệm hoàn toàn không tồn tại với Lambda. - B.
name,alias,PlatformVersion,type— trộn lẫn:namevàaliasđúng, nhưngPlatformVersionlà thuộc tính của Fargate, vàTypethì nằm ở cấp trên (Type: AWS::Lambda::Function) chứ không phải trongProperties. Quan trọng hơn, nó thiếuCurrentVersionvàTargetVersion— tức là thiếu thông tin cốt lõi.
Ghi nhớ
AppSpec khác nhau hoàn toàn theo nền tảng: | Nền tảng | Định dạng | Nội dung resources | |---|---|---| | Lambda | YAML hoặc JSON | Name, Alias, CurrentVersion, TargetVersion | | ECS | YAML hoặc JSON | TaskDefinition, ContainerName, ContainerPort, LoadBalancerInfo | | EC2 / On-premises | CHỈ YAML | files và hooks (không có resources) |
Dòng cuối đáng nhớ: với EC2, AppSpec bắt buộc phải là YAML và bắt buộc đặt tên appspec.yml ở gốc gói triển khai. Với Lambda và ECS thì linh hoạt hơn.
Hook theo từng nền tảng: | Nền tảng | Hook | |---|---| | Lambda | BeforeAllowTraffic, AfterAllowTraffic (chỉ hai) | | ECS | thêm BeforeInstall, AfterInstall, AfterAllowTestTraffic | | EC2 | ApplicationStop, BeforeInstall, AfterInstall, ApplicationStart, ValidateService |
Mẹo nhận dạng: hook hoặc thuộc tính có chữ "Install" thì không phải Lambda — Lambda không cài đặt gì, nó chỉ chuyển alias.
Và nhớ: hàm hook phải gọi put_lifecycle_event_hook_execution_status để báo kết quả — quên là triển khai treo cho tới khi hết timeout.
A company runs a decoupled application that uses an Amazon SQS queue. The messages are processed by an AWS Lambda function. The function is not keeping up with the number of messages in the queue. A developer noticed that though the application can process multiple messages per invocation, it is only processing one at a time.
How can the developer configure the application to process messages more efficiently?
-
A
Call the ChangeMessageVisibility API for the queue and set MessageRetentionPeriod to a value greater than the default of 1.
-
B
Call the ReceiveMessage API to set MaxNumberOfMessages to a value greater than the default of 1.
-
C
Call the SetQueueAttributes API for the queue and set MaxNumberOfMessages to a value greater than the default of 1.
-
D
Call the ReceiveMessage API to set MaximumMessageSize to a value greater than the default of 1.
Xem giải thích
Đáp án
B — Gọi API ReceiveMessage và đặt MaxNumberOfMessages lớn hơn giá trị mặc định là 1.
Vì sao đúng
Triệu chứng trong đề rất rõ: ứng dụng xử lý được nhiều message mỗi lần chạy, nhưng thực tế chỉ nhận về một.
Nguyên nhân là mặc định của SQS: MaxNumberOfMessages = 1. Nhiều consumer chạy đúng nhưng chậm chỉ vì không ai đổi tham số này.
messages = sqs.receive_message(
QueueUrl=url,
MaxNumberOfMessages=10, # ← tối đa cho phép
WaitTimeSeconds=20 # long polling, nên bật kèm
)['Messages']
for msg in messages:
xu_ly(msg)
Hiệu quả rất trực tiếp:
Xử lý 10.000 message, mỗi lần nhận 1 → 10.000 lời gọi API
Xử lý 10.000 message, mỗi lần nhận 10 → 1.000 lời gọi API ← giảm 90%
Vừa nhanh hơn (ít lần đi mạng) vừa rẻ hơn (SQS tính tiền theo số request).
Với Lambda làm consumer, tham số tương ứng nằm ở event source mapping:
aws lambda update-event-source-mapping --uuid <id> \
--batch-size 10 \
--maximum-batching-window-in-seconds 5
BatchSize của Lambda cho SQS lên tới 10.000 với hàng đợi standard (giới hạn 10 chỉ áp cho lời gọi ReceiveMessage trực tiếp), và MaximumBatchingWindow cho phép chờ gom đủ lô trước khi gọi hàm.
Vì sao các phương án khác sai
- C. Gọi
SetQueueAttributesvà đặtMaxNumberOfMessages— sai API:MaxNumberOfMessageslà tham số của lời gọiReceiveMessage, không phải thuộc tính của hàng đợi.SetQueueAttributesđặt đượcVisibilityTimeout,MessageRetentionPeriod,ReceiveMessageWaitTimeSeconds,DelaySeconds— nhưng không có tham số này. - D. Gọi
ReceiveMessagevà đặtMaximumMessageSize— sai tham số:MaximumMessageSizequy định kích thước tối đa của một message (mặc định 256 KB), không liên quan tới số lượng message nhận về. Và nó cũng là thuộc tính của hàng đợi, không phải tham số củaReceiveMessage. - A. Gọi
ChangeMessageVisibilityvà đặtMessageRetentionPeriod— trộn hai thứ không liên quan:ChangeMessageVisibilitygia hạn thời gian ẩn của một message đang xử lý, cònMessageRetentionPeriodquyết định message được giữ bao lâu trước khi bị xoá. Không cái nào ảnh hưởng tới số message nhận mỗi lần.
Ghi nhớ
Các giới hạn theo lô của SQS: | Thao tác | Giới hạn | |---|---| | ReceiveMessage | 10 message | | SendMessageBatch | 10 message, tổng 256 KB | | DeleteMessageBatch | 10 message | | Lambda BatchSize (SQS standard) | tới 10.000 | | Lambda BatchSize (SQS FIFO) | tới 10 |
Bốn tham số thời gian, để không nhầm lẫn: | Tham số | Phạm vi | Việc | |---|---|---| | MaxNumberOfMessages | 1 – 10 | số message mỗi lần nhận | | WaitTimeSeconds | 0 – 20 giây | long polling | | VisibilityTimeout | 0 – 12 giờ | ẩn message đang xử lý | | MessageRetentionPeriod | 60 giây – 14 ngày | giữ message bao lâu |
Cấu hình tối ưu cho consumer thông thường là kết hợp hai tham số đầu:
sqs.receive_message(QueueUrl=url, MaxNumberOfMessages=10, WaitTimeSeconds=20)
Chúng giải quyết hai vấn đề khác nhau: MaxNumberOfMessages giảm số lần gọi khi hàng đợi có nhiều message, còn WaitTimeSeconds giảm số lần gọi rỗng khi hàng đợi trống.
Và một lưu ý khi xử lý theo lô với Lambda: nếu một message trong lô gây lỗi, cả lô bị trả lại hàng đợi theo mặc định. Bật ReportBatchItemFailures để chỉ trả lại đúng những message hỏng.
An application uses an Auto Scaling group of Amazon EC2 instances, an Application Load Balancer (ALB), and an Amazon Simple Queue Service (SQS) queue. An Amazon CloudFront distribution caches content for global users. A Developer needs to add in-transit encryption to the data by configuring end-to-end SSL between the CloudFront Origin and the end users.
How can the Developer meet this requirement? (Select TWO.)
-
A
Configure the Origin Protocol Policy
-
B
Create an Origin Access Identity (OAI)
-
C
Configure the Viewer Protocol Policy
-
D
Add a certificate to the Auto Scaling Group
-
E
Create an encrypted distribution
Xem giải thích
Đáp án
A và C.
- C — Cấu hình Viewer Protocol Policy
- A — Cấu hình Origin Protocol Policy
Vì sao đúng
Yêu cầu là mã hoá đầu-cuối (end-to-end SSL), tức là cả hai chặng của đường đi đều phải dùng HTTPS:
Người dùng ──chặng 1──→ CloudFront ──chặng 2──→ ALB (origin)
↑ ↑
Viewer Protocol Policy Origin Protocol Policy
Hai chính sách này điều khiển hai chặng độc lập với nhau, nên phải đặt cả hai:
C — Viewer Protocol Policy (người dùng ↔ CloudFront): | Giá trị | Hành vi | |---|---| | allow-all | cho phép cả HTTP lẫn HTTPS | | redirect-to-https | chuyển hướng HTTP sang HTTPS — thường dùng nhất | | https-only | từ chối hẳn HTTP |
A — Origin Protocol Policy (CloudFront ↔ origin): | Giá trị | Hành vi | |---|---| | http-only | luôn dùng HTTP — phá vỡ mã hoá đầu-cuối | | https-only | luôn dùng HTTPS | | match-viewer | dùng đúng giao thức mà người dùng đã dùng |
{
"DefaultCacheBehavior": {
"ViewerProtocolPolicy": "redirect-to-https"
},
"Origins": [{
"DomainName": "alb-ung-dung.ap-southeast-1.elb.amazonaws.com",
"CustomOriginConfig": {
"OriginProtocolPolicy": "https-only",
"OriginSSLProtocols": {"Items": ["TLSv1.2"]}
}
}]
}
Điểm hay bị bỏ sót: chỉ đặt Viewer Protocol Policy là chưa đủ. Nhiều người thấy trình duyệt hiện ổ khoá rồi yên tâm, trong khi chặng từ CloudFront tới origin vẫn đang chạy HTTP — dữ liệu vẫn đi qua Internet công khai ở dạng không mã hoá.
Vì sao các phương án khác sai
- B. Tạo Origin Access Identity (OAI) — OAI (và bản thay thế hiện đại là Origin Access Control) dùng để giới hạn truy cập vào S3 bucket sao cho chỉ CloudFront đọc được. Nó là cơ chế kiểm soát truy cập, không phải mã hoá. Và nó chỉ dùng với S3 origin — ở đây origin là ALB.
- D. Thêm chứng chỉ vào Auto Scaling group — ASG không nhận chứng chỉ: nó quản lý số lượng và vòng đời instance. Chứng chỉ gắn vào listener của ALB, hoặc cài trên chính máy chủ web nếu muốn mã hoá cả chặng ALB → EC2.
- E. Tạo "encrypted distribution" — không có loại distribution nào như vậy. Mã hoá được cấu hình bằng hai chính sách giao thức ở trên, không phải bằng một loại distribution riêng.
Ghi nhớ
Ba chặng có thể mã hoá trong kiến trúc này:
Người dùng → CloudFront → ALB → EC2
① ② ③
| Chặng | Cấu hình bằng |
|---|---|
| ① Viewer | ViewerProtocolPolicy + chứng chỉ ACM (ở us-east-1) |
| ② Origin | OriginProtocolPolicy + chứng chỉ trên ALB |
| ③ ALB → EC2 | HTTPS listener trên target group |
Đề chỉ yêu cầu tới chặng ②, nhưng với dữ liệu nhạy cảm thì nên mã hoá cả ③ — và ở đó ALB không kiểm tra chứng chỉ của backend, nên EC2 dùng được chứng chỉ tự ký, không tốn thêm chi phí.
Hai lưu ý về chứng chỉ:
- Chứng chỉ ACM cho CloudFront bắt buộc nằm ở Region
us-east-1— cấp nhầm Region thì Console đơn giản là không hiện nó trong danh sách. - Origin phải có chứng chỉ hợp lệ, do CA công cộng tin cậy cấp, và tên miền phải khớp với
DomainNamekhai trong origin — CloudFront có kiểm tra điều này, khác với ALB.
Và nên đặt OriginSSLProtocols chỉ gồm TLS 1.2 trở lên — mặc định vẫn cho phép các phiên bản cũ hơn.