GĐ33 — AWS SAA: Labs, Case Studies và Ôn tập có giải thích

Áp dụng GĐ28–32. Lab là hướng dẫn để bạn tự thực hành; việc build guide không tạo tài nguyên AWS và không xác nhận lab đã chạy trên account của bạn. Câu hỏi dưới đây do guide tự xây, không phải đề thi AWS hay exam dumps.

1. Chuẩn bị lab và cách lưu bằng chứng#

Hai mức thực hành:

  • Trên giấy: sơ đồ, policy review, cost estimate, câu hỏi lỗi; dùng được trước khi có account.
  • Trên AWS: tài nguyên sandbox và dữ liệu giả, chạy từng lab rồi dọn ngay.

Chuẩn bị AWS CLI v2, danh tính tạm thời theo phương thức đăng nhập account hỗ trợ, một Region và quyền tạo đúng tài nguyên lab. Không dùng root cho lab. Bật MFA cho account, tạo budget alert, kiểm tra pricing; budget không phải hard cap. Gắn tag Project=aws-saa-lab, Owner và ngày dự kiến dọn cho tài nguyên hỗ trợ.

Kiểm tra CLI bằng lệnh đọc, thay profile/Region bằng giá trị của bạn:

bashReady
aws sts get-caller-identity --profile YOUR-LAB-PROFILEaws configure get region --profile YOUR-LAB-PROFILE

Không đưa output có thông tin account cá nhân lên repo public. Không lưu secrets vào source. Mỗi lab ghi riêng: sơ đồ, resource IDs, điều kiện thử, kết quả mong đợi/thực tế, timestamp, cost estimate và cleanup checklist. Dữ liệu upload chỉ là file giả; không dùng PDF cá nhân.

Nguồn: CLI authentication, AWS Budgets.

Lời giải và cách kiểm tra: chuẩn bị lab và mẫu bằng chứng

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Mọi lệnh và JSON trong GĐ33 là mẫu để bạn tự chạy trên account sandbox của mình; chưa có output thật nào được quan sát.

Hướng làm (pre-flight, làm một lần trước Lab A).

  1. Dùng account sandbox riêng, không dùng account công việc. Không dùng root; bật MFA. Free plan và Paid plan của account mới đều có credit đăng ký (100 USD khi đăng ký, cộng tối đa 100 USD khi hoàn thành hoạt động; xem thông báo của AWS và Free Tier FAQs); Free plan kết thúc sau 6 tháng hoặc khi hết credit. Mô hình "12 tháng miễn phí" cũ không dùng. Credit không có nghĩa lab nào cũng miễn phí: đọc trang pricing từng dịch vụ.

  2. Tạo budget với cảnh báo email. Nhắc lại: alert không phải hard cap.

  3. Chọn một Region cho mọi lab và ghi vào biến môi trường; đa số lệnh dưới đây dùng $AWS_PROFILE và $AWS_REGION.

  4. Xác nhận danh tính trước khi tạo gì (lệnh đọc, không đổi gì):

    bashReady
    export AWS_PROFILE=YOUR-LAB-PROFILEexport AWS_REGION=YOUR-LAB-REGIONaws sts get-caller-identity

    Kết quả mong đợi: JSON có Account và Arn. Nếu ARN là root hoặc account lạ, dừng lại.

  5. Tạo thư mục ~/saa-lab/ ngoài repo cho mọi file bằng chứng. Không commit output có Account ID, ARN thật, hoặc secret.

  6. Tag mọi tài nguyên hỗ trợ tag: Project=aws-saa-lab, Owner=<tên>, CleanupBy=<ngày>.

Mẫu bằng chứng (một file lab-X.md cho mỗi lab).

textReady
# Lab X - <tên>             Ngày: YYYY-MM-DD   Region: ...Sơ đồ:            (ASCII hoặc ảnh, có AZ/subnet/SG)Tài nguyên tạo:   <loại> | <id/tên> | <thời điểm tạo>Điều kiện thử:    <ai gọi gì, từ đâu>Mong đợi:         ...Thực tế:          ... (dán output đã che Account ID)Giải thích:       vì sao ra kết quả đó (policy nào, rule nào)Thời gian đo:     bắt đầu - kết thúc - tổngƯớc tính chi phí: giả định, nguồn giá, ngàyDọn dẹp:          lệnh dọn + lệnh kiểm "không còn gì" + ngày xem billingCòn lại/không làm: ...

Mẫu decision record (cho Done khi, mục 15).

textReady
Quyết định: <một câu>Bối cảnh/requirement: <RTO/RPO, AZ, ngân sách, compliance>Phương án đã xét: A ... | B ... | C ...Chọn: B vì ...Loại: A vì (vi phạm requirement nào) ; C vì ...Hệ quả: chi phí cố định, vận hành, rủi ro còn lạiKhi nào xem lại: <điều kiện + ngày>

Kết quả mong đợi. Sáu file lab-A đến lab-F gần như trống (đến khi làm), pre-flight hoàn tất, budget hoạt động.

Lỗi hay gặp. Chạy lệnh khi AWS_PROFILE trỏ nhầm account; quên đặt Region nên tài nguyên nằm rải nhiều Region (dọn sót); dán output có Account ID lên repo công khai; coi credit là "miễn phí hết".

2. Lab A — S3 private, IAM và versioning#

Mục tiêu: cùng một object, quyền đọc đúng prefix thành công, prefix ngoài phạm vi bị từ chối; ghi đè rồi lấy lại được version cũ.

  1. Tạo general purpose bucket có tên duy nhất trong Region đã chọn; giữ Block Public Access, dùng SSE-S3 cho lần đầu.

    Đáp án

    Tạo bucket và kiểm tra mặc định. Bucket mới đã bật Block Public Access, tắt ACL (bucket owner enforced) và mã hóa SSE-S3 mặc định (SSE-S3 mặc định từ tháng 1/2023 theo AWS What's New; Block Public Access bật và ACL tắt cho bucket mới từ tháng 4/2023 theo AWS What's New), nên các lệnh get-* chỉ để xác nhận:

    bashReady
    BUCKET=saa-lab-$(date +%s)-CHANGE-ME     # tên phải duy nhất toàn cầu# Region khác us-east-1 cần LocationConstraint; nếu chọn us-east-1# thì BỎ dòng --create-bucket-configuration (nếu không sẽ lỗi# InvalidLocationConstraint; suy luận theo tài liệu, chưa chạy)aws s3api create-bucket --bucket "$BUCKET" --region "$AWS_REGION" \  --create-bucket-configuration LocationConstraint="$AWS_REGION"aws s3api get-public-access-block --bucket "$BUCKET"aws s3api get-bucket-encryption --bucket "$BUCKET"
  2. Bật versioning. Tạo hai file giả qua editor, upload raw/note.txt và other/note.txt bằng danh tính setup có quyền tương ứng.

    Đáp án

    Bật versioning rồi kiểm tra, sau đó tạo hai file giả và upload:

    bashReady
    aws s3api put-bucket-versioning --bucket "$BUCKET" \  --versioning-configuration Status=Enabledaws s3api get-bucket-versioning --bucket "$BUCKET"   # Status: Enabledecho "version one" > note.txtaws s3api put-object --bucket "$BUCKET" --key raw/note.txt --body note.txtaws s3api put-object --bucket "$BUCKET" --key other/note.txt --body note.txt
  3. Tạo role kiểm thử mà danh tính lab được assume; trust chỉ dành cho danh tính đó. Gắn identity policy chỉ s3:GetObject trên raw/* như GĐ29. Giữ role này không có policy rộng khác làm sai phép thử.

    Đáp án

    Tạo role chỉ cho phép đọc raw/*. trust.json cho danh tính lab được assume (thay ARN bằng của bạn), policy.json chỉ có s3:GetObject:

    jsonReady
    { "Version": "2012-10-17",  "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID:user/YOUR-LAB-USER" }, "Action": "sts:AssumeRole" } ] }
    jsonReady
    { "Version": "2012-10-17",  "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::BUCKET-NAME/raw/*" } ] }
    bashReady
    aws iam create-role --role-name saa-lab-reader \  --assume-role-policy-document file://trust.jsonaws iam put-role-policy --role-name saa-lab-reader \  --policy-name raw-read-only --policy-document file://policy.json

    Nếu danh tính lab dùng IAM Identity Center thay vì IAM user, đổi Principal cho khớp phương thức đăng nhập (xem trang CLI role profiles).

  4. Assume role qua phương thức profile được hỗ trợ; dùng profile kiểm thử đọc raw/note.txt → thành công, đọc other/note.txt → AccessDenied. Không yêu cầu ListBucket để đọc một key đã biết.

    Đáp án

    Tạo profile đọc trong ~/.aws/config (đợi vài giây để role lan truyền):

    textReady
    [profile saa-reader]role_arn = arn:aws:iam::ACCOUNT_ID:role/saa-lab-readersource_profile = YOUR-LAB-PROFILE
    bashReady
    aws s3api get-object --bucket "$BUCKET" --key raw/note.txt out-raw.txt \  --profile saa-readeraws s3api get-object --bucket "$BUCKET" --key other/note.txt out-other.txt \  --profile saa-reader
  5. Quay về danh tính setup, ghi đè raw/note.txt với nội dung khác. Xem Versions và tải version đầu; delete current object rồi quan sát delete marker.

    Đáp án

    Quay lại profile setup: ghi đè, xem versions, lấy bản cũ, rồi xóa:

    bashReady
    echo "version two" > note.txtaws s3api put-object --bucket "$BUCKET" --key raw/note.txt --body note.txtaws s3api list-object-versions --bucket "$BUCKET" --prefix raw/note.txtaws s3api get-object --bucket "$BUCKET" --key raw/note.txt \  --version-id VERSION-ID-OF-V1 old.txtaws s3api delete-object --bucket "$BUCKET" --key raw/note.txtaws s3api list-object-versions --bucket "$BUCKET" --prefix raw/note.txt
  6. Mở rộng tùy chọn: dùng SSE-KMS, cấp GetObject nhưng chưa cấp quyền KMS phù hợp; quan sát lỗi rồi bổ sung quyền key tối thiểu.

    Đáp án

    Tùy chọn, chưa chạy: tạo KMS key riêng, đặt mặc định mã hóa SSE-KMS cho bucket, upload lại một object. Cấp cho role s3:GetObject nhưng chưa cấp quyền KMS: đọc sẽ lỗi. Sau đó thêm kms:Decrypt trên đúng key vào policy của role rồi đọc lại. Đây là lỗi hay gặp với SSE-KMS (xem Lỗi hay gặp trong Khung và mã dùng chung).

    Mẫu CLI (tham số đã đối chiếu help). Key tạo không kèm --policy sẽ dùng default key policy; policy này cho phép account dùng IAM policy để cấp quyền key, nên inline policy của role là đủ:

    bashReady
    KEY_ARN=$(aws kms create-key --description saa-lab-s3 \  --tags TagKey=Project,TagValue=aws-saa-lab --query KeyMetadata.Arn --output text)aws s3api put-bucket-encryption --bucket "$BUCKET" \  --server-side-encryption-configuration \  '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"'"$KEY_ARN"'"}}]}'echo kms-test > kms.txtaws s3api put-object --bucket "$BUCKET" --key raw/kms.txt --body kms.txtaws s3api get-object --bucket "$BUCKET" --key raw/kms.txt out-kms.txt \  --profile saa-reader            # mong đợi: lỗi, role chưa có kms:Decryptaws iam put-role-policy --role-name saa-lab-reader --policy-name kms-decrypt \  --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"kms:Decrypt","Resource":"'"$KEY_ARN"'"}]}'

    Chờ vài giây rồi chạy lại get-object. Khi dọn: aws iam delete-role-policy --role-name saa-lab-reader --policy-name kms-decrypt trước khi xóa role, và lên lịch xóa key như phần dọn bên dưới. Nguồn: SSE-KMS trong S3, default key policy.

Khung và mã dùng chung

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Chưa có output quan sát được; phần "mong đợi" suy ra từ tài liệu.

Sơ đồ.

textReady
 profile saa-setup (quyền tạo)          profile saa-reader (assume role)        |  put-object x2                        |  get-object        v                                       v   +--------------------- bucket (private, versioning ON) ---------+   |  raw/note.txt   (v1, v2)         other/note.txt               |   +---------------------------------------------------------------+   role saa-lab-reader: Allow s3:GetObject on arn:...:bucket/raw/*   raw/*  -> Allow            other/*  -> implicit deny (không có Allow)

Kết quả mong đợi.

BướcMong đợi
get raw/note.txt bằng saa-readerThành công, out-raw.txt có nội dung
get other/note.txt bằng saa-readerAccessDenied (HTTP 403): role không có Allow nào cho prefix này, nên bị implicit deny
list-object-versions sau ghi đèHai VersionId cho raw/note.txt, bản mới có IsLatest: true
get với --version-id của v1Nội dung "version one"
delete-object (không version)Trả DeleteMarker: true và VersionId của marker; các bản cũ vẫn còn trong Versions
get không version sau deleteLỗi not found vì phiên bản hiện tại là delete marker; lấy lại bằng --version-id

Bằng chứng cần lưu. Hai output khác nhau của cùng principal (che Account ID); danh sách version trước và sau; giải thích implicit deny ("không có câu Allow cho other/*"); tên và nội dung policy.

Lỗi hay gặp.

  • Cả hai đọc được: role còn gắn policy rộng khác, hoặc bucket policy cấp quyền cho cả account. Tìm trước khi kết luận policy prefix sai.
  • Role chưa assume được: trust.json sai principal, hoặc vừa tạo nên chưa lan truyền, hoặc source_profile trỏ nhầm.
  • 403 thay vì 404 cho key không tồn tại: theo tài liệu GetObject, khi principal có s3:ListBucket thì key không tồn tại trả 404; không có s3:ListBucket thì trả 403. Vì vậy lỗi 403 ở key bạn gõ sai chính tả không chứng minh policy chặn.
  • get-object không cần s3:ListBucket để đọc một key đã biết; chỉ cần quyền đó khi muốn phân biệt 404 và 403, hoặc liệt kê.
  • SSE-KMS (tùy chọn): GetObject được phép nhưng thiếu quyền KMS sẽ lỗi; cấp thêm quyền giải mã trên đúng key.

Dọn (thứ tự quan trọng). aws s3 rb --force không xóa versions và delete markers của bucket bật versioning, nên dùng list-object-versions:

bashReady
aws s3api list-object-versions --bucket "$BUCKET" --output json \ | jq '{Objects: ([.Versions[]?, .DeleteMarkers[]?]                  | map({Key, VersionId})), Quiet: true}' > del.jsonaws s3api delete-objects --bucket "$BUCKET" --delete file://del.jsonaws s3api list-multipart-uploads --bucket "$BUCKET"     # nếu có: abort-multipart-uploadaws s3api delete-bucket --bucket "$BUCKET"aws iam delete-role-policy --role-name saa-lab-reader --policy-name raw-read-onlyaws iam delete-role --role-name saa-lab-reader

Một lần delete-objects có giới hạn số key: nếu nhiều hơn, lặp lại cho đến khi list-object-versions trống; lệnh sẽ lỗi nếu Objects rỗng, hãy bỏ qua bước đó. Kiểm: aws s3api head-bucket --bucket "$BUCKET" phải lỗi 404. KMS key riêng (nếu có): aws kms schedule-key-deletion --key-id KEY --pending-window-in-days 7. Thời gian chờ là 7-30 ngày (mặc định 30), trong thời gian này key ở trạng thái Pending deletion, không dùng được và có thể hủy bằng cancel-key-deletion; sau khi hết hạn thì không hoàn tác và dữ liệu mã hóa bằng key đó không giải mã được. Cú pháp jq và lệnh ở trên chưa chạy; kiểm lại trên dữ liệu thật.

Lệnh đọc object bằng profile giới hạn, output là file mới trong thư mục lab của bạn:

bashReady
aws s3api get-object --bucket YOUR-LAB-BUCKET --key raw/note.txt ./saa-raw-result.txt --profile YOUR-READER-PROFILE --region YOUR-LAB-REGIONaws s3api get-object --bucket YOUR-LAB-BUCKET --key other/note.txt ./saa-other-result.txt --profile YOUR-READER-PROFILE --region YOUR-LAB-REGION

Evidence: hai kết quả khác nhau dưới cùng principal, version IDs/nội dung trước-sau và giải thích implicit deny. Nếu cả hai đọc được, tìm policy rộng/resource grant khác trước khi kết luận prefix policy sai.

Dọn: xóa tất cả object versions và delete markers, incomplete multipart uploads nếu có, bucket, role/policies riêng cho lab; chỉ xóa KMS key riêng khi chắc không còn dữ liệu cần decrypt. Key deletion có waiting period và không được nhầm với xóa object.

Nguồn: S3 versioning, CLI role profiles.

3. Lab B — VPC, ALB và Auto Scaling hai AZ#

Mục tiêu: thấy load balancer đưa request tới nhiều máy; khi một máy bị thay, service phục hồi mà không lưu state trên máy đó. Lab này có ALB/EC2 và tài nguyên network tính phí.

  1. Vẽ VPC với hai public subnets và hai private app subnets ở hai AZ. Public route tới IGW; app egress qua thiết kế NAT/endpoints đã chọn. Ghi fixed cost trước khi tạo.

    Đáp án

    Vẽ và tạo VPC: hai public subnet, hai private subnet ở hai AZ khác nhau, route public tới IGW. Chọn một cách egress cho private subnet và ghi chi phí cố định trước khi tạo: NAT gateway từng AZ, hoặc Regional NAT gateway (một gateway tự mở rộng qua nhiều AZ; ra mắt 2025-11-19, không có ở GovCloud và China), hoặc interface/gateway endpoints cho đúng dịch vụ cần dùng.

    Mẫu CLI tạo network (chưa chạy trên AWS; tham số đã đối chiếu aws ec2 <lệnh> help). Mỗi lệnh in ra ID để dùng tiếp; tag Project=aws-saa-lab để quét sót khi dọn:

    bashReady
    TAG='Tags=[{Key=Project,Value=aws-saa-lab}]'read AZ1 AZ2 _ < <(aws ec2 describe-availability-zones \  --filters Name=zone-type,Values=availability-zone \  --query 'AvailabilityZones[].ZoneName' --output text)VPC=$(aws ec2 create-vpc --cidr-block 10.20.0.0/16 \  --tag-specifications "ResourceType=vpc,$TAG" --query Vpc.VpcId --output text)mk() { aws ec2 create-subnet --vpc-id "$VPC" --cidr-block "$1" \  --availability-zone "$2" --tag-specifications "ResourceType=subnet,$TAG" \  --query Subnet.SubnetId --output text; }PUB_A=$(mk 10.20.0.0/24 "$AZ1");  PUB_B=$(mk 10.20.1.0/24 "$AZ2")APP_A=$(mk 10.20.10.0/24 "$AZ1"); APP_B=$(mk 10.20.11.0/24 "$AZ2")IGW=$(aws ec2 create-internet-gateway \  --tag-specifications "ResourceType=internet-gateway,$TAG" \  --query InternetGateway.InternetGatewayId --output text)aws ec2 attach-internet-gateway --internet-gateway-id "$IGW" --vpc-id "$VPC"RT_PUB=$(aws ec2 create-route-table --vpc-id "$VPC" \  --tag-specifications "ResourceType=route-table,$TAG" \  --query RouteTable.RouteTableId --output text)aws ec2 create-route --route-table-id "$RT_PUB" \  --destination-cidr-block 0.0.0.0/0 --gateway-id "$IGW"aws ec2 associate-route-table --route-table-id "$RT_PUB" --subnet-id "$PUB_A"aws ec2 associate-route-table --route-table-id "$RT_PUB" --subnet-id "$PUB_B"RT_APP=$(aws ec2 create-route-table --vpc-id "$VPC" \  --tag-specifications "ResourceType=route-table,$TAG" \  --query RouteTable.RouteTableId --output text)aws ec2 associate-route-table --route-table-id "$RT_APP" --subnet-id "$APP_A"aws ec2 associate-route-table --route-table-id "$RT_APP" --subnet-id "$APP_B"

    Route table RT_APP chưa có đường ra Internet. Thêm NAT/Regional NAT nếu app cần tải package, hoặc làm theo biến thể không NAT ở cuối mục này.

  2. Tạo ALB SG chỉ nhận HTTP từ IP máy bạn cho lần thử; app SG chỉ nhận port app từ ALB SG. Với demo public dùng HTTPS/ACM; HTTP lab không truyền credentials/dữ liệu nhạy cảm.

    Đáp án

    Tạo SG: SG-alb cho HTTP 80 từ IP máy bạn; SG-app cho port app chỉ từ SG-alb.

    bashReady
    SG_ALB=$(aws ec2 create-security-group --group-name saa-alb \  --description "ALB lab" --vpc-id "$VPC" --query GroupId --output text)aws ec2 authorize-security-group-ingress --group-id "$SG_ALB" \  --protocol tcp --port 80 --cidr YOUR-IP/32SG_APP=$(aws ec2 create-security-group --group-name saa-app \  --description "App lab" --vpc-id "$VPC" --query GroupId --output text)aws ec2 authorize-security-group-ingress --group-id "$SG_APP" \  --protocol tcp --port 8080 --source-group "$SG_ALB"

    Rule thứ hai tham chiếu SG thay vì IP, nên instance mới do ASG tạo ra vẫn nhận traffic từ ALB.

  3. Tạo launch template bằng AMI hỗ trợ, role tối thiểu và bootstrap server trả JSON chứa marker instance cùng /health/ready. Đảm bảo đường bootstrap/package downloads và management có egress/endpoints cần thiết. Dùng app từ GĐ15 nếu đã có image; không đưa secret vào user data.

    Đáp án

    Launch template: AMI, instance profile tối thiểu, user data khởi động HTTP server trả JSON có instanceId và có /health/ready. Không đặt secret vào user data. Mẫu khung:

    bashReady
    aws ec2 create-launch-template --launch-template-name saa-lt \  --launch-template-data file://lt.json     # ImageId, InstanceType, UserData(base64), SG
  4. Tạo target group, health check, ALB listener; ASG ở hai app subnets với min/desired 2, max 3. Bật ELB health checks cho ASG và đặt grace period phù hợp bootstrap.

    Đáp án

    Tạo target group, ALB và listener trước, rồi ASG ở hai private subnet, dùng ELB health check và grace period lớn hơn thời gian khởi động app. Grace period mặc định là 300 giây khi tạo ASG bằng console và 0 giây khi tạo bằng CLI hoặc SDK (tài liệu Auto Scaling), nên hãy đặt rõ, ví dụ lab 120 giây:

    bashReady
    aws elbv2 create-target-group --name saa-tg --protocol HTTP --port 8080 \  --vpc-id VPC-ID --target-type instance --health-check-path /health/readyaws elbv2 create-load-balancer --name saa-alb --type application \  --subnets PUBLIC-A PUBLIC-B --security-groups SG-ALB-IDaws elbv2 create-listener --load-balancer-arn ALB-ARN --protocol HTTP --port 80 \  --default-actions Type=forward,TargetGroupArn=TG-ARNaws autoscaling create-auto-scaling-group --auto-scaling-group-name saa-asg \  --launch-template LaunchTemplateName=saa-lt,Version='$Latest' \  --min-size 2 --max-size 3 --desired-capacity 2 \  --vpc-zone-identifier "PRIVATE-A,PRIVATE-B" --target-group-arns TG-ARN \  --health-check-type ELB --health-check-grace-period 120
  5. Gọi endpoint nhiều lần; ghi marker trả về và healthy targets.

    Đáp án

    Gọi endpoint nhiều lần và ghi instanceId trả về; kiểm tra target:

    bashReady
    for i in $(seq 1 10); do curl -s http://ALB-DNS-NAME/; echo; doneaws elbv2 describe-target-health --target-group-arn TG-ARN
  6. Chỉ terminate một instance thuộc ASG lab, giữ desired capacity. Quan sát ASG launch replacement, target health và thời gian endpoint phục hồi. Không terminate tài nguyên ngoài lab.

    Đáp án

    Chỉ terminate một instance của ASG lab, giữ desired capacity, và ghi mốc thời gian:

    bashReady
    aws autoscaling terminate-instance-in-auto-scaling-group \  --instance-id i-XXXX --no-should-decrement-desired-capacityaws autoscaling describe-scaling-activities --auto-scaling-group-name saa-asg
  7. Bật target tracking phù hợp, tạo tải nhẹ có giới hạn từ máy của bạn; ghi metric/capacity và dừng tải. Nếu không scale, kiểm tra warmup, threshold và metric thay vì tăng tải vô hạn.

    Đáp án

    Target tracking nhẹ, rồi tạo tải có giới hạn từ máy bạn và dừng khi xong:

    jsonReady
    { "PredefinedMetricSpecification": { "PredefinedMetricType": "ASGAverageCPUUtilization" },  "TargetValue": 50.0 }
    bashReady
    aws autoscaling put-scaling-policy --auto-scaling-group-name saa-asg \  --policy-name cpu50 --policy-type TargetTrackingScaling \  --target-tracking-configuration file://tt.json
Khung và mã dùng chung

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Lab này có tài nguyên tính phí theo giờ (ALB, EC2, NAT hoặc endpoints, public IPv4): tra trang pricing của EC2, ELB và VPC cho Region của bạn, không nêu số ở đây. Lệnh dưới là khung; tham số như AMI, subnet, SG phải thay bằng giá trị của bạn.

Sơ đồ.

textReady
Internet --> IGW --> ALB (public-a, public-b)  SG-alb: 80 từ IP của bạn                      |  forward -> target group, health /health/ready          +-----------+-----------+          v                       v   app-a (private, AZ-a)   app-b (private, AZ-b)   SG-app: chỉ từ SG-alb          |  ASG min=2 desired=2 max=3  (ELB health check)          v   egress: NAT hoặc VPC endpoints (để tải package/ECR)   Mất 1 instance -> ASG thay -> target mới healthy   Mất cả AZ-a    -> còn app-b; DB/NAT nếu chỉ ở AZ-a thì vẫn là điểm đơn

Kết quả mong đợi.

Quan sátMong đợi
Nhiều request liên tiếpMarker instanceId thay đổi giữa hai instance
describe-target-healthHai target healthy, thuộc hai AZ
Sau terminate một instanceTarget đó draining/unhealthy; ASG ghi hoạt động launch thay thế; endpoint vẫn trả lời nhờ instance còn lại
Khi replacement xong health checkLại đủ hai target healthy; ghi tổng thời gian từ terminate tới đủ hai
Tải vượt ngưỡng trong thời gian đủ dàiASG có thể tăng desired tới tối đa 3; nếu không, kiểm tra metric, warmup, ngưỡng thay vì tăng tải vô hạn

Bằng chứng cần lưu. Sơ đồ route/SG; output marker; target health trước/sau; timeline replacement; số request lỗi (nếu có) và thời gian phục hồi. Kết luận đúng: bài này chứng minh thay instance hỏng, không chứng minh sống sót khi mất cả AZ. Phần AZ outage làm tabletop: nếu AZ-a mất thì còn gì (app-b, ALB ở hai AZ), còn điểm đơn nào (NAT chỉ ở AZ-a, DB một AZ). AWS Fault Injection Service có thể mô phỏng sự cố có kiểm soát; tên và phạm vi kịch bản AZ chưa xác minh trong lượt tra này, nên coi là mở rộng, không phải bước bắt buộc.

Lỗi hay gặp.

  • Instance private không tải được package/image: thiếu NAT hoặc endpoint. Triệu chứng: target không bao giờ healthy.
  • Target unhealthy: sai port, health path chưa trả 200, SG-app không cho từ SG-alb, hoặc grace period quá ngắn nên ASG thay instance đang khởi động (vòng lặp thay mới).
  • ALB cần subnet ở ít nhất hai AZ khác nhau (đối chiếu tài liệu ELB khi tạo).
  • Quên rằng public IPv4, ALB và NAT tính phí theo giờ dù không có traffic.
  • Terminate trực tiếp nhầm instance ngoài ASG lab.

Dọn (thứ tự).

bashReady
aws autoscaling delete-auto-scaling-group --auto-scaling-group-name saa-asg --force-deleteaws elbv2 delete-listener --listener-arn LISTENER-ARNaws elbv2 delete-load-balancer --load-balancer-arn ALB-ARNaws elbv2 wait load-balancers-deleted --load-balancer-arns ALB-ARNaws elbv2 delete-target-group --target-group-arn TG-ARNaws ec2 delete-launch-template --launch-template-name saa-lt

Sau đó NAT gateway (rồi release Elastic IP của nó), endpoints riêng, SG, route table, subnet, IGW (detach trước), VPC. Kiểm tra theo Region: aws ec2 describe-instances, describe-nat-gateways, describe-addresses, describe-vpc-endpoints, và xem Billing sau độ trễ. Lệnh trên chưa chạy; kiểm lại tên tham số bằng aws <service> <command> help.

Phần network tạo bằng CLI ở bước 1-2 dọn theo thứ tự ngược (biến lấy từ lúc tạo; nếu đã có NAT thì xóa NAT và release EIP trước):

bashReady
aws ec2 delete-security-group --group-id "$SG_APP"aws ec2 delete-security-group --group-id "$SG_ALB"for a in $(aws ec2 describe-route-tables --route-table-ids "$RT_PUB" "$RT_APP" \    --query 'RouteTables[].Associations[].RouteTableAssociationId' --output text); do  aws ec2 disassociate-route-table --association-id "$a"; doneaws ec2 delete-route-table --route-table-id "$RT_PUB"aws ec2 delete-route-table --route-table-id "$RT_APP"for s in "$PUB_A" "$PUB_B" "$APP_A" "$APP_B"; do  aws ec2 delete-subnet --subnet-id "$s"; doneaws ec2 detach-internet-gateway --internet-gateway-id "$IGW" --vpc-id "$VPC"aws ec2 delete-internet-gateway --internet-gateway-id "$IGW"aws ec2 delete-vpc --vpc-id "$VPC"

Route table phải gỡ hết liên kết subnet trước khi xóa (theo aws ec2 delete-route-table help). Lệnh nào báo DependencyViolation nghĩa là còn tài nguyên bám vào (ENI của ALB đang xóa, endpoint, instance): chờ hoặc tìm bằng aws ec2 describe-network-interfaces --filters Name=vpc-id,Values=$VPC.

Evidence: sơ đồ route/SG, hai targets thuộc hai AZ, timeline replacement, request errors và thời gian phục hồi. Terminate một instance kiểm tra instance failure, chưa chứng minh toàn bộ AZ failure; phần AZ outage làm tabletop: chỉ ra DB/egress còn phụ thuộc AZ nào.

Dọn: ASG về 0 rồi xóa, EC2/volumes còn lại, ALB/listeners/target group, launch template, NAT/EIP/endpoints riêng, SG/routes/subnets/IGW/VPC khi hết dependencies. Kiểm tra tài nguyên theo Region.

Nguồn: ASG + ELB, ASG health checks.

Lab B biến thể — app subnet không NAT, dựng bằng CloudFormation#

Kiểm chứng ngày 2026-10-05. Biến thể này cho app subnet không có đường ra Internet: không NAT, instance không có public IP. Nó chạy được vì ứng dụng mẫu chỉ dùng Python 3 có sẵn trong AL2023 (AL2023 Python), AMI lấy qua SSM public parameter (AL2023 trên EC2), và ALB gọi instance ngay trong VPC. Template có sẵn S3 gateway endpoint, loại endpoint không tính thêm phí (gateway endpoints), để dùng khi app cần đọc S3.

Chi phí cố định: bỏ được NAT gateway, vốn tính theo mỗi giờ tồn tại cộng mỗi GB xử lý, giờ lẻ tính tròn một giờ (VPC pricing; đơn giá theo Region, xem trang pricing). Public IPv4 tính 0,005 USD mỗi giờ mỗi địa chỉ, gồm cả địa chỉ của load balancer (cùng trang, đọc ngày 2026-10-05), nên ALB internet-facing vẫn có dòng này. ALB, EC2 và EBS: xem pricing của từng dịch vụ.

Bằng chứng: đã chạy cfn-lint 1.57.1 trên đúng template dưới đây (0 lỗi, 0 cảnh báo) và chạy thử phần ứng dụng Python trên máy local (trả JSON, HTTP 200; instanceId là unknown vì máy local không có IMDS). Template chưa deploy trên AWS thật.

Template lab-b-no-nat.yaml
textReady
AWSTemplateFormatVersion: "2010-09-09"Description: SAA Lab B - ALB + ASG hai AZ, app subnet private khong NATParameters:  MyIpCidr:    Type: String    Description: IP may ban dang x.x.x.x/32, duoc goi ALB qua HTTP 80  LatestAmiId:    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64  InstanceType:    Type: String    Default: t3.microResources:  Vpc:    Type: AWS::EC2::VPC    Properties:      CidrBlock: 10.20.0.0/16      EnableDnsSupport: true      EnableDnsHostnames: true      Tags: [{ Key: Project, Value: aws-saa-lab }]  Igw:    Type: AWS::EC2::InternetGateway    Properties:      Tags: [{ Key: Project, Value: aws-saa-lab }]  IgwAttach:    Type: AWS::EC2::VPCGatewayAttachment    Properties: { VpcId: !Ref Vpc, InternetGatewayId: !Ref Igw }  PublicA:    Type: AWS::EC2::Subnet    Properties:      VpcId: !Ref Vpc      CidrBlock: 10.20.0.0/24      AvailabilityZone: !Select [0, !GetAZs ""]      Tags: [{ Key: Project, Value: aws-saa-lab }]  PublicB:    Type: AWS::EC2::Subnet    Properties:      VpcId: !Ref Vpc      CidrBlock: 10.20.1.0/24      AvailabilityZone: !Select [1, !GetAZs ""]      Tags: [{ Key: Project, Value: aws-saa-lab }]  AppA:    Type: AWS::EC2::Subnet    Properties:      VpcId: !Ref Vpc      CidrBlock: 10.20.10.0/24      AvailabilityZone: !Select [0, !GetAZs ""]      Tags: [{ Key: Project, Value: aws-saa-lab }]  AppB:    Type: AWS::EC2::Subnet    Properties:      VpcId: !Ref Vpc      CidrBlock: 10.20.11.0/24      AvailabilityZone: !Select [1, !GetAZs ""]      Tags: [{ Key: Project, Value: aws-saa-lab }]  PublicRt:    Type: AWS::EC2::RouteTable    Properties:      VpcId: !Ref Vpc      Tags: [{ Key: Project, Value: aws-saa-lab }]  PublicDefault:    Type: AWS::EC2::Route    DependsOn: IgwAttach    Properties:      RouteTableId: !Ref PublicRt      DestinationCidrBlock: 0.0.0.0/0      GatewayId: !Ref Igw  PublicAAssoc:    Type: AWS::EC2::SubnetRouteTableAssociation    Properties: { SubnetId: !Ref PublicA, RouteTableId: !Ref PublicRt }  PublicBAssoc:    Type: AWS::EC2::SubnetRouteTableAssociation    Properties: { SubnetId: !Ref PublicB, RouteTableId: !Ref PublicRt }  AppRt: # khong co route 0.0.0.0/0: app subnet khong ra Internet    Type: AWS::EC2::RouteTable    Properties:      VpcId: !Ref Vpc      Tags: [{ Key: Project, Value: aws-saa-lab }]  AppAAssoc:    Type: AWS::EC2::SubnetRouteTableAssociation    Properties: { SubnetId: !Ref AppA, RouteTableId: !Ref AppRt }  AppBAssoc:    Type: AWS::EC2::SubnetRouteTableAssociation    Properties: { SubnetId: !Ref AppB, RouteTableId: !Ref AppRt }  S3Endpoint: # gateway endpoint: duong rieng toi S3 neu app can doc S3    Type: AWS::EC2::VPCEndpoint    Properties:      VpcId: !Ref Vpc      VpcEndpointType: Gateway      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3      RouteTableIds: [!Ref AppRt]  AlbSg:    Type: AWS::EC2::SecurityGroup    Properties:      GroupDescription: ALB lab, HTTP 80 tu IP cua ban      VpcId: !Ref Vpc      SecurityGroupIngress:        - { IpProtocol: tcp, FromPort: 80, ToPort: 80, CidrIp: !Ref MyIpCidr }      Tags: [{ Key: Project, Value: aws-saa-lab }]  AppSg:    Type: AWS::EC2::SecurityGroup    Properties:      GroupDescription: App lab, port 8080 chi tu ALB SG      VpcId: !Ref Vpc      SecurityGroupIngress:        - IpProtocol: tcp          FromPort: 8080          ToPort: 8080          SourceSecurityGroupId: !Ref AlbSg      Tags: [{ Key: Project, Value: aws-saa-lab }]  Alb:    Type: AWS::ElasticLoadBalancingV2::LoadBalancer    DependsOn: IgwAttach    Properties:      Type: application      Scheme: internet-facing      Subnets: [!Ref PublicA, !Ref PublicB]      SecurityGroups: [!Ref AlbSg]      Tags: [{ Key: Project, Value: aws-saa-lab }]  Tg:    Type: AWS::ElasticLoadBalancingV2::TargetGroup    Properties:      VpcId: !Ref Vpc      Protocol: HTTP      Port: 8080      TargetType: instance      HealthCheckPath: /health/ready      Tags: [{ Key: Project, Value: aws-saa-lab }]  Listener:    Type: AWS::ElasticLoadBalancingV2::Listener    Properties:      LoadBalancerArn: !Ref Alb      Protocol: HTTP      Port: 80      DefaultActions: [{ Type: forward, TargetGroupArn: !Ref Tg }]  Lt:    Type: AWS::EC2::LaunchTemplate    Properties:      LaunchTemplateData:        ImageId: !Ref LatestAmiId        InstanceType: !Ref InstanceType        SecurityGroupIds: [!Ref AppSg]        MetadataOptions: { HttpTokens: required }        UserData:          Fn::Base64: |            #!/bin/bash            cat > /opt/saa-app.py <<'PY'            import http.server, json, urllib.request            def imds(path):                base = "http://169.254.169.254/latest/"                try:                    t = urllib.request.Request(base + "api/token", method="PUT",                        headers={"X-aws-ec2-metadata-token-ttl-seconds": "300"})                    tok = urllib.request.urlopen(t, timeout=2).read().decode()                    r = urllib.request.Request(base + "meta-data/" + path,                        headers={"X-aws-ec2-metadata-token": tok})                    return urllib.request.urlopen(r, timeout=2).read().decode()                except OSError:                    return "unknown"            IID, AZ = imds("instance-id"), imds("placement/availability-zone")            class H(http.server.BaseHTTPRequestHandler):                def do_GET(self):                    body = json.dumps({"instanceId": IID, "az": AZ,                                       "path": self.path}).encode()                    self.send_response(200)                    self.send_header("Content-Type", "application/json")                    self.end_headers()                    self.wfile.write(body)            http.server.ThreadingHTTPServer(("", 8080), H).serve_forever()            PY            nohup python3 /opt/saa-app.py > /var/log/saa-app.log 2>&1 &  Asg:    Type: AWS::AutoScaling::AutoScalingGroup    Properties:      MinSize: "2"      MaxSize: "3"      DesiredCapacity: "2"      VPCZoneIdentifier: [!Ref AppA, !Ref AppB]      LaunchTemplate:        LaunchTemplateId: !Ref Lt        Version: !GetAtt Lt.LatestVersionNumber      TargetGroupARNs: [!Ref Tg]      HealthCheckType: ELB      HealthCheckGracePeriod: 120      Tags:        - { Key: Project, Value: aws-saa-lab, PropagateAtLaunch: true }Outputs:  AlbDns:    Value: !GetAtt Alb.DNSName
  1. Deploy stack với IP của bạn, chờ xong, lấy DNS của ALB và gọi nhiều lần.

    Đáp án
    bashReady
    aws cloudformation deploy --template-file lab-b-no-nat.yaml \  --stack-name saa-lab-b --parameter-overrides MyIpCidr=YOUR-IP/32 \  --tags Project=aws-saa-labALB=$(aws cloudformation describe-stacks --stack-name saa-lab-b \  --query "Stacks[0].Outputs[?OutputKey=='AlbDns'].OutputValue" --output text)for i in $(seq 1 10); do curl -s "http://$ALB/"; echo; done

    Mong đợi: JSON có instanceId và az đổi giữa hai instance ở hai AZ. Nếu target không healthy, kiểm tra SG-app có nhận 8080 từ SG-alb và aws elbv2 describe-target-health; muốn vào máy thì thêm endpoint Session Manager (bước 2), đừng mở SSH ra Internet.

  2. Chứng minh app subnet không ra Internet, rồi liệt kê những gì sẽ hỏng nếu app cần thêm phụ thuộc.

    Đáp án
    bashReady
    VPC=$(aws cloudformation describe-stack-resource --stack-name saa-lab-b \  --logical-resource-id Vpc --query StackResourceDetail.PhysicalResourceId \  --output text)APP_A=$(aws cloudformation describe-stack-resource --stack-name saa-lab-b \  --logical-resource-id AppA --query StackResourceDetail.PhysicalResourceId \  --output text)aws ec2 describe-route-tables \  --filters Name=association.subnet-id,Values="$APP_A" \  --query 'RouteTables[].Routes[].[DestinationCidrBlock,DestinationPrefixListId,GatewayId]'

    Route table gắn với app subnet chỉ có route local và route tới prefix list của S3 qua vpce-...; không có 0.0.0.0/0. Sẽ hỏng nếu app cần: cài package bằng dnf từ repo ngoài, kéo image từ registry Internet, gọi API bên thứ ba, hoặc dùng Session Manager. Session Manager cần interface endpoint cho ssm, ssmmessages và ec2messages (Systems Manager và VPC endpoints); mỗi interface endpoint có phí riêng, xem PrivateLink pricing. Lúc đó so tổng phí endpoints với một NAT trước khi chọn.

  3. Xóa stack và kiểm tra không còn tài nguyên của lab.

    Đáp án
    bashReady
    aws cloudformation delete-stack --stack-name saa-lab-baws cloudformation wait stack-delete-complete --stack-name saa-lab-baws ec2 describe-vpcs --filters Name=tag:Project,Values=aws-saa-lab \  --query 'Vpcs[].VpcId'

    Mong đợi: wait kết thúc không lỗi và lệnh cuối trả []. Nếu xóa kẹt ở DELETE_FAILED, xem describe-stack-events để biết tài nguyên nào còn phụ thuộc. Quét toàn bộ theo tag ở mục 7, phần quét tài nguyên sót.

4. Lab C — SQS retry, visibility và DLQ#

Mục tiêu: chứng minh receive không xóa message và phân biệt retry với mất dữ liệu. Làm Standard queue trước.

  1. Tạo Standard queue saa-jobs và Standard DLQ cùng account/Region; đặt redrive policy maxReceiveCount=3, visibility timeout 30 giây, retention DLQ dài hơn queue nguồn. Cho source queue được dùng DLQ qua redrive allow policy phù hợp.

    Đáp án

    Tạo DLQ trước, lấy ARN, rồi tạo queue nguồn. DLQ phải cùng account, cùng Region và cùng loại (Standard) với queue nguồn. Retention của DLQ phải dài hơn queue nguồn, vì với Standard queue message giữ nguyên thời điểm enqueue gốc khi chuyển sang DLQ (đồng hồ retention không được reset). Redrive allow policy mặc định cho phép mọi queue nguồn dùng DLQ; chỉ cần đặt nếu muốn siết:

    bashReady
    aws sqs create-queue --queue-name saa-jobs-dlq \  --attributes MessageRetentionPeriod=1209600       # 14 ngày; kiểm giới hạn tối đa trong trang quotasDLQ_URL=$(aws sqs get-queue-url --queue-name saa-jobs-dlq --query QueueUrl --output text)DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "$DLQ_URL" \  --attribute-names QueueArn --query Attributes.QueueArn --output text)

    RedrivePolicy là chuỗi JSON nằm trong JSON, dễ sai khi quote trong zsh. Viết ra file thay vì gõ trên dòng lệnh:

    jsonReady
    {  "VisibilityTimeout": "30",  "RedrivePolicy": "{\"deadLetterTargetArn\":\"DLQ_ARN\",\"maxReceiveCount\":\"3\"}"}
    bashReady
    # thay DLQ_ARN trong attrs.json bằng giá trị thật, kiểm bằng: jq . attrs.jsonaws sqs create-queue --queue-name saa-jobs --attributes file://attrs.jsonJOBS_URL=$(aws sqs get-queue-url --queue-name saa-jobs --query QueueUrl --output text)
  2. Send một message JSON giả { "jobId": "job-001", "kind": "demo" }.

    Đáp án

    Gửi job-001:

    bashReady
    aws sqs send-message --queue-url "$JOBS_URL" \  --message-body '{"jobId":"job-001","kind":"demo"}'
  3. Receive với long polling, ghi MessageId/receipt handle và timestamp. Không delete; receive ngay có thể chưa thấy message vì đang invisible.

    Đáp án

    Receive bằng long polling (tối đa 20 giây; ở đây 10) và không delete; ghi MessageId, ReceiptHandle và giờ:

    bashReady
    aws sqs receive-message --queue-url "$JOBS_URL" --wait-time-seconds 10 \  --max-number-of-messages 1 --message-system-attribute-names All

    Gọi lại ngay: không thấy message vì đang invisible.

  4. Sau visibility timeout, receive lại; kiểm tra ApproximateReceiveCount. Tiếp tục không delete tới khi message được chuyển DLQ; quá trình/metrics có thể có độ trễ.

    Đáp án

    Đợi hết visibility timeout (mặc định 30 giây, ở lab này đặt 30), receive lại; mỗi lần ghi ApproximateReceiveCount. Lặp đến khi message không còn xuất hiện ở queue nguồn; rồi kiểm tra DLQ:

    bashReady
    aws sqs get-queue-attributes --queue-url "$DLQ_URL" \  --attribute-names ApproximateNumberOfMessagesaws sqs receive-message --queue-url "$DLQ_URL" --wait-time-seconds 10
  5. Send job-002, receive và delete bằng receipt handle của lần receive đó. MessageId không phải receipt handle.

    Đáp án

    Gửi job-002, receive, rồi delete bằng ReceiptHandle của chính lần receive đó:

    bashReady
    aws sqs delete-message --queue-url "$JOBS_URL" --receipt-handle "RECEIPT-HANDLE"

    ReceiptHandle gắn với từng lần receive; MessageId không dùng để delete.

  6. Bài nâng cao với worker từ GĐ10: lưu kết quả theo jobId unique; chủ động crash sau commit trước delete. Cho retry và chứng minh chỉ có một business result.

    Đáp án

    Nâng cao (idempotency nghiệp vụ). Worker ghi kết quả vào bảng có ràng buộc duy nhất theo jobId, rồi mới delete. Cố tình crash sau khi commit và trước khi delete, để message được giao lại:

    textReady
    -- PostgreSQL (chưa chạy)CREATE TABLE job_results (job_id text PRIMARY KEY, result jsonb NOT NULL);INSERT INTO job_results (job_id, result) VALUES ($1, $2)ON CONFLICT (job_id) DO NOTHING;   -- lần giao lại: 0 hàng được chèn
Khung và mã dùng chung

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Chưa có output quan sát; chỗ nào chưa chắc được ghi rõ.

Sơ đồ.

textReady
send job-001 --> [saa-jobs] --receive #1--> (invisible 30s) --hết hạn-->                     ^                                           |                     +--------- hiện lại (chưa delete) <---------+   receive #1,#2,#3 không delete -> vượt maxReceiveCount=3 -> [saa-jobs-dlq]   job-002: receive -> xử lý -> delete-message(ReceiptHandle của lần đó) -> xong

Kết quả mong đợi.

Quan sátMong đợi
Receive ngay sau lần đầuRỗng (message đang invisible)
Receive lần 2, 3 sau khi hết timeoutCùng MessageId, ApproximateReceiveCount tăng 1, 2, 3
Sau lần 3 không deleteMessage rời queue nguồn và nằm trong DLQ. Thời điểm chính xác có thể trễ và có thể xảy ra ở lần receive kế tiếp thay vì ngay lúc nhận lần 3 (tài liệu DLQ định nghĩa maxReceiveCount là số lần consumer được nhận message trước khi chuyển sang DLQ, không nêu mốc theo giây; thời điểm chính xác "ngay lần 3 hay ở lần receive kế tiếp": chưa xác minh); đừng viết bài báo cáo khẳng định một trong hai
job-002Xóa thành công; không xuất hiện lại
Bài nâng caoHai lần giao, bảng job_results có đúng 1 hàng cho job-001

Bằng chứng cần lưu. Chuỗi MessageId và receive count; output DLQ; hai lần xử lý nhưng một hàng kết quả. Receive/DLQ chỉ chứng minh retry; chỉ bước 6 mới chứng minh idempotency nghiệp vụ. SQS giao ít nhất một lần, kể cả trong lúc message đang invisible, nên handler luôn phải idempotent.

Lỗi hay gặp.

  • Dán chuỗi RedrivePolicy trên dòng lệnh bị zsh ăn dấu ngoặc: dùng file://attrs.json.
  • Nhầm MessageId với ReceiptHandle khi delete; dùng handle cũ của lần receive trước (có thể không còn hiệu lực).
  • Visibility timeout ngắn hơn thời gian xử lý khiến job bị giao hai lần khi vẫn đang chạy; kéo dài bằng ChangeMessageVisibility (tối đa 12 giờ kể từ lần nhận đầu).
  • DLQ khác Region/account/loại queue, hoặc retention DLQ ngắn hơn queue nguồn nên message hết hạn sớm.
  • Redrive hàng loạt từ DLQ khi chưa sửa nguyên nhân: message lại vào DLQ.

Dọn. Dừng worker trước, rồi:

bashReady
aws sqs delete-queue --queue-url "$JOBS_URL"aws sqs delete-queue --queue-url "$DLQ_URL"aws cloudwatch delete-alarms --alarm-names saa-dlq-not-empty   # nếu đã tạo

Kiểm: aws sqs list-queues --queue-name-prefix saa- không còn gì. Lệnh chưa chạy; kiểm cú pháp bằng aws sqs <command> help.

Lệnh quan sát queue của bạn; mỗi receive có thể làm message invisible:

bashReady
aws sqs receive-message --queue-url YOUR-LAB-QUEUE-URL --wait-time-seconds 10 --max-number-of-messages 1 --message-system-attribute-names All --profile YOUR-LAB-PROFILE --region YOUR-LAB-REGION

Evidence: cùng job nhận lại, receive count tăng, message lỗi tới DLQ, job thành công được delete. Phần receive/DLQ chưa chứng minh idempotency business; cần phần worker nâng cao để chứng minh.

Dọn: dừng worker trước, xóa hai queue và policies/alarms riêng. Không redrive message lỗi hàng loạt khi chưa sửa nguyên nhân.

Nguồn: SQS visibility, DLQ.

5. Lab D — RDS restore và failover#

Mục tiêu: chứng minh backup đọc lại được dữ liệu và phân biệt restore/failover. Lab có DB/storage tính phí; bắt đầu với dữ liệu nhỏ và diễn tập trên giấy nếu chưa cần tạo DB.

  1. Tạo RDS PostgreSQL private với DB subnet group ít nhất hai AZ theo yêu cầu dịch vụ; chọn Single-AZ cho restore lab, bật backup retention phù hợp, SG chỉ nhận từ app/test client trong VPC.

    Đáp án

    Tạo DB PostgreSQL private. DB subnet group cần subnet ở ít nhất hai AZ; chọn Single-AZ cho phần restore, bật automated backup, SG chỉ nhận từ client trong VPC, không public.

    Trước hết tạo SG và DB subnet group (dùng lại VPC và hai private subnet của Lab B, hoặc VPC sandbox của bạn; SG-CLIENT là SG của máy client trong VPC):

    bashReady
    SG_DB=$(aws ec2 create-security-group --group-name saa-db \  --description "RDS lab" --vpc-id "$VPC" --query GroupId --output text)aws ec2 authorize-security-group-ingress --group-id "$SG_DB" \  --protocol tcp --port 5432 --source-group SG-CLIENTaws rds create-db-subnet-group --db-subnet-group-name saa-db-subnets \  --db-subnet-group-description "SAA lab DB subnets" \  --subnet-ids "$APP_A" "$APP_B" --tags Key=Project,Value=aws-saa-lab

    Trong các lệnh dưới, SUBNET-GROUP là saa-db-subnets và SG-DB là giá trị $SG_DB.

    bashReady
    aws rds create-db-instance --db-instance-identifier saa-pg \  --engine postgres --db-instance-class CLASS-NHO-NHAT \  --allocated-storage 20 --master-username saaadmin \  --manage-master-user-password \  --db-subnet-group-name SUBNET-GROUP --vpc-security-group-ids SG-DB \  --no-publicly-accessible --no-multi-az --backup-retention-period 1aws rds wait db-instance-available --db-instance-identifier saa-pg

    --manage-master-user-password để RDS lưu mật khẩu trong Secrets Manager; không đặt mật khẩu trong lệnh hay file.

  2. Kết nối bằng client trong VPC, dùng TLS verify theo docs engine. Tạo bảng lab, insert dữ liệu giả, ghi count và vài khóa đã biết; không mở DB public chỉ để kết nối thuận tiện.

    Đáp án

    Từ client trong VPC (EC2 nhỏ hoặc Session Manager), kết nối và tạo dữ liệu giả; ghi count(*) và vài khóa:

    textReady
    CREATE TABLE notes (id int PRIMARY KEY, body text);INSERT INTO notes SELECT g, 'before-snapshot-' || g FROM generate_series(1,5) g;SELECT count(*) FROM notes;   -- 5
  3. Tạo manual snapshot sau khi dữ liệu đã commit. Ghi thời gian snapshot sẵn sàng; insert thêm bản ghi sau snapshot.

    Đáp án

    Snapshot sau khi commit, chờ sẵn sàng, rồi chèn thêm dữ liệu sau snapshot:

    bashReady
    aws rds create-db-snapshot --db-instance-identifier saa-pg \  --db-snapshot-identifier saa-pg-snap1aws rds wait db-snapshot-available --db-snapshot-identifier saa-pg-snap1# sau đó: INSERT INTO notes VALUES (6, 'after-snapshot');
  4. Restore snapshot sang DB instance mới, chọn subnet/SG/secret phù hợp. Kiểm tra endpoint mới và dữ liệu tại thời điểm snapshot; bản ghi thêm sau snapshot không có.

    Đáp án

    Restore sang instance mới, chỉ định rõ subnet group và SG (không để mặc định):

    bashReady
    aws rds restore-db-instance-from-db-snapshot \  --db-instance-identifier saa-pg-restored --db-snapshot-identifier saa-pg-snap1 \  --db-subnet-group-name SUBNET-GROUP --vpc-security-group-ids SG-DB \  --no-publicly-accessibleaws rds wait db-instance-available --db-instance-identifier saa-pg-restored
  5. Nếu học PITR, chọn thời điểm nằm trong restorable window và restore thành instance mới. Ghi target time, thời gian bắt đầu/kết thúc và kết quả dữ liệu.

    Đáp án

    PITR: lấy mốc restore trong cửa sổ, rồi restore thành instance mới khác:

    bashReady
    aws rds describe-db-instances --db-instance-identifier saa-pg \  --query 'DBInstances[0].LatestRestorableTime'aws rds restore-db-instance-to-point-in-time \  --source-db-instance-identifier saa-pg \  --target-db-instance-identifier saa-pg-pitr \  --restore-time 2026-10-05T10:00:00Z \  --db-subnet-group-name SUBNET-GROUP --vpc-security-group-ids SG-DB

    (restore-time là ví dụ; dùng mốc nằm giữa cửa sổ của bạn. Hoặc --use-latest-restorable-time.)

  6. Tùy chọn riêng: dùng Multi-AZ DB instance trong sandbox, reboot với failover khi dịch vụ hỗ trợ; quan sát client reconnect và downtime. Đọc rõ cách failover theo deployment type trước khi thao tác.

    Đáp án

    Tùy chọn failover (chỉ sandbox): đổi sang Multi-AZ instance rồi reboot với failover:

    bashReady
    aws rds modify-db-instance --db-instance-identifier saa-pg --multi-az --apply-immediatelyaws rds wait db-instance-available --db-instance-identifier saa-pgaws rds reboot-db-instance --db-instance-identifier saa-pg --force-failover

    Với Multi-AZ DB cluster thì dùng lệnh failover riêng của cluster; đọc trang failover theo deployment type trước khi thử.

Khung và mã dùng chung

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Lab tính phí instance, storage và backup: bắt đầu với dữ liệu nhỏ, instance class nhỏ nhất bạn được dùng ở Region (tra trang pricing, không nêu số). Nếu chưa muốn tạo DB, làm tabletop theo bảng "mong đợi".

Sơ đồ.

textReady
 saa-pg (Single-AZ) --snapshot (sau commit)--> saa-pg-snap1      | insert thêm (sau snapshot)                 |      |                                            v restore => DB MỚI      +--transaction log lên S3 (mỗi 5 phút)   saa-pg-restored (endpoint mới)              \__ PITR: restore-time trong cửa sổ => DB MỚI khác nữa Tùy chọn: Multi-AZ instance --reboot --force-failover--> standby lên primary           (endpoint DNS giữ tên; kết nối TCP cũ đứt, app phải reconnect)

Kết quả mong đợi.

Quan sátMong đợi
saa-pg-restoredEndpoint mới; count(*) = 5; không có hàng id 6 (nó được thêm sau snapshot)
LatestRestorableTimeChậm hơn hiện tại một khoảng ngắn (transaction log được tải lên S3 mỗi 5 phút)
saa-pg-pitrDữ liệu đúng tại restore-time; DB mới, không đụng DB gốc
Ngay sau khi restore availableHiệu năng có thể thấp lúc đầu vì volume vẫn tải block nền; DB vẫn dùng được
Parameter group sau restoreMặc định của engine/version, không phải bản tùy chỉnh trừ khi bạn chỉ định
FailoverKết nối đang mở đứt; app reconnect tới cùng DNS endpoint; ghi lại thời gian gián đoạn quan sát được

Bằng chứng cần lưu. Lệnh và output restore; count(*) trước và sau; mốc thời gian bắt đầu và kết thúc mỗi restore; log reconnect của client. Thời gian đo trong lab nhỏ không phải RTO production: RTO thực còn gồm dựng network/app, đổi endpoint, validate dữ liệu, DNS và quy trình phê duyệt.

Lỗi hay gặp.

  • Restore ra SG hoặc parameter group mặc định nên client không kết nối được: chỉ định lại khi restore.
  • Chờ restore ghi đè DB gốc: restore luôn tạo instance mới.
  • Chọn restore-time ngoài cửa sổ retention hoặc sau LatestRestorableTime.
  • Backup retention bằng 0 hoặc quên tạo snapshot trước khi xóa.
  • Nghĩ "stop" là dọn: instance stop tối đa 7 ngày liên tục rồi tự start lại; trong lúc stop vẫn tính phí storage và backup (và public IPv4 nếu có).
  • Tìm kết nối vào standby để đọc: standby của Multi-AZ instance không phục vụ read.

Dọn.

bashReady
aws rds delete-db-instance --db-instance-identifier saa-pg-restored \  --skip-final-snapshot --delete-automated-backupsaws rds delete-db-instance --db-instance-identifier saa-pg-pitr \  --skip-final-snapshot --delete-automated-backupsaws rds delete-db-instance --db-instance-identifier saa-pg \  --skip-final-snapshot --delete-automated-backupsaws rds delete-db-snapshot --db-snapshot-identifier saa-pg-snap1

Automated backups bị xóa cùng instance nếu bạn không chọn giữ; manual snapshot không tự xóa (và tính vào hạn mức 100 manual snapshot mỗi Region) nên phải xóa riêng, cùng secret master và log group riêng. Kiểm: aws rds describe-db-instances, describe-db-snapshots --snapshot-type manual, describe-db-instance-automated-backups đều không còn đồ của lab. Lệnh chưa chạy; kiểm tham số bằng aws rds <command> help.

Sau khi mọi DB instance đã xóa xong, xóa DB subnet group và SG của DB:

bashReady
for i in saa-pg saa-pg-restored saa-pg-pitr; do  aws rds wait db-instance-deleted --db-instance-identifier "$i"doneaws rds delete-db-subnet-group --db-subnet-group-name saa-db-subnetsaws ec2 delete-security-group --group-id "$SG_DB"

Evidence: snapshot/PITR restore thành công, dữ liệu đúng thời điểm, thời gian thực tế, app reconnect. Thời gian trong lab nhỏ không phải RTO production; còn thời gian dựng network/app, đổi endpoint, validation và DNS.

Dọn: app/test client, DB gốc và DB restored, snapshot lab/retained backups không cần giữ, secret và log riêng theo retention. RDS stop không phải cleanup vĩnh viễn; storage vẫn có thể tính phí và DB có cơ chế tự start lại.

Nguồn: RDS restore snapshot, PITR, stopping RDS.

6. Lab E — CloudFront và S3 origin private#

Mục tiêu: S3 URL trực tiếp không public, CloudFront vẫn trả static object; phân biệt quyền origin với quyền viewer.

  1. Tạo private S3 bucket với Block Public Access; upload một static file giả bằng danh tính setup.

    Đáp án

    Bucket private, Block Public Access bật, Object Ownership là bucket owner enforced (mặc định bucket mới; OAC yêu cầu). Upload file giả:

    bashReady
    echo "<h1>saa lab</h1>" > index.htmlaws s3api put-object --bucket "$BUCKET" --key index.html --body index.html \  --content-type text/html
  2. Tạo distribution với S3 REST origin, OAC ký request và bucket policy chỉ cho distribution đó đọc objects. Không chọn S3 website endpoint cho bài OAC này.

    Đáp án

    Tạo OAC kiểu S3, ký luôn luôn:

    bashReady
    aws cloudfront create-origin-access-control --origin-access-control-config \  Name=saa-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3

    Ghi Id trả về. Tạo distribution (console: origin là S3 REST endpoint của bucket, không phải website endpoint; Origin access: Origin access control settings; chọn OAC trên; default root object index.html). Ghi ID distribution.

    Hoặc tạo bằng CLI. File dist.json tối thiểu (tên field đối chiếu aws cloudfront create-distribution --generate-cli-skeleton; cache policy ID là của managed policy CachingOptimized theo tài liệu managed cache policies):

    jsonReady
    {  "CallerReference": "saa-lab-e-2026-10-05",  "Comment": "saa lab E",  "Enabled": true,  "DefaultRootObject": "index.html",  "Origins": { "Quantity": 1, "Items": [{    "Id": "s3-origin",    "DomainName": "BUCKET.s3.REGION.amazonaws.com",    "S3OriginConfig": { "OriginAccessIdentity": "" },    "OriginAccessControlId": "OAC_ID" }] },  "DefaultCacheBehavior": {    "TargetOriginId": "s3-origin",    "ViewerProtocolPolicy": "redirect-to-https",    "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6" }}
    bashReady
    aws cloudfront create-distribution --distribution-config file://dist.json \  --query 'Distribution.[Id,DomainName]' --output text

    OriginAccessIdentity để chuỗi rỗng vì dùng OAC thay cho OAI. CallerReference phải khác nhau giữa các lần tạo.

    Bucket policy cho đúng distribution đó (thay ACCOUNT_ID, BUCKET, DIST_ID):

    jsonReady
    {  "Version": "2012-10-17",  "Statement": [{    "Sid": "AllowCloudFrontRead",    "Effect": "Allow",    "Principal": { "Service": "cloudfront.amazonaws.com" },    "Action": "s3:GetObject",    "Resource": "arn:aws:s3:::BUCKET/*",    "Condition": { "StringEquals": {      "AWS:SourceArn":        "arn:aws:cloudfront::ACCOUNT_ID:distribution/DIST_ID" } }  }]}
    bashReady
    aws s3api put-bucket-policy --bucket "$BUCKET" --policy file://oac-policy.json
  3. Chờ distribution deploy; gọi CloudFront URL → đọc được, gọi unsigned S3 object URL → bị từ chối. Danh tính IAM có quyền vẫn có thể đọc S3: phép thử public dùng request không ký.

    Đáp án

    Chờ distribution deploy rồi gọi hai đường truy cập (đường S3 gọi không ký, không dùng credentials):

    bashReady
    aws cloudfront wait distribution-deployed --id DIST_IDcurl -sI https://DOMAIN.cloudfront.net/index.html          # 200curl -sI https://"$BUCKET".s3."$AWS_REGION".amazonaws.com/index.html   # 403
  4. Đọc response headers/cache status và xem hit/miss sau nhiều request. Đặt cache policy cho nội dung static; không upload dữ liệu private của user vào bài này.

    Đáp án

    Gọi lặp và đọc header cache:

    bashReady
    for i in 1 2 3; do  curl -sI https://DOMAIN.cloudfront.net/index.html | grep -i x-cachedone
  5. Tùy chọn: yêu cầu signed viewer URL/cookie, cấu hình trusted key group và thử request không ký/bị hết hạn. Không commit signing private key.

    Đáp án

    Tùy chọn viewer: tạo trusted key group (public key bạn tải lên, private key giữ ngoài repo), đặt behavior yêu cầu signed URL/cookie, rồi thử request không ký, hết hạn, hợp lệ. Dùng key group, không dùng root key pair.

    Mẫu CLI, chưa chạy (tham số đã đối chiếu help). Với trusted key group, Key-Pair-Id trong signed URL là ID của CloudFront public key:

    bashReady
    openssl genrsa -out private_key.pem 2048     # giữ ngoài repoopenssl rsa -pubout -in private_key.pem -out public_key.pemjq -n --arg k "$(cat public_key.pem)" --arg r "saa-$(date +%s)" \  '{CallerReference: $r, Name: "saa-lab-pub", EncodedKey: $k}' > pubkey.jsonPUB_ID=$(aws cloudfront create-public-key --public-key-config file://pubkey.json \  --query PublicKey.Id --output text)aws cloudfront create-key-group \  --key-group-config "Name=saa-lab-kg,Items=$PUB_ID" --query KeyGroup.Id --output text

    Gắn key group ID vào TrustedKeyGroups của cache behavior (get-distribution-config rồi update-distribution --if-match ETAG), chờ deploy, rồi ký URL:

    bashReady
    aws cloudfront sign --url "https://DIST-DOMAIN/index.html" \  --key-pair-id "$PUB_ID" --private-key file://private_key.pem \  --date-less-than "$(date -u -v+10M +%Y-%m-%dT%H:%M:%SZ)"   # macOS date

    Nguồn: signed URL canned policy.

Khung và mã dùng chung

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Phần tạo distribution làm bằng console là đường ngắn nhất; bước 2 có thêm mẫu create-distribution cho CLI, và CLI dưới đây dùng cho OAC, bucket policy, kiểm tra và dọn. Giá CloudFront và request: tra trang pricing.

Sơ đồ.

textReady
 Viewer --HTTPS--> CloudFront (cache) --SigV4 do OAC ký--> S3 bucket (private) Viewer --trực tiếp--> https://BUCKET.s3...amazonaws.com/index.html -> 403 bucket policy: Allow cloudfront.amazonaws.com GetObject                nếu AWS:SourceArn = distribution của bạn OAC  = bảo vệ ORIGIN (chỉ CloudFront đọc được S3) Signed URL/cookie = bảo vệ VIEWER (ai được xem qua CloudFront)

Kết quả mong đợi.

Phép thửMong đợi
CloudFront URL200 và nội dung file
Gọi lặp CloudFrontHeader X-Cache đổi từ Miss sang Hit khi đã cache (tùy cache policy và edge)
Unsigned S3 URL403 (bucket không public, request không ký)
(Tùy chọn) CloudFront không ký/hết hạn403; request ký hợp lệ: 200

Bằng chứng cần lưu. Ba kết quả curl; ID distribution và OAC; bucket policy; ghi chú: danh tính IAM có quyền đọc vẫn đọc được S3 trực tiếp, nên phép thử "public" phải là request không ký. Giải thích: OAC không chặn viewer public (ai có URL CloudFront đều xem được); viewer chỉ bị chặn khi cấu hình signed URL/cookie.

Lỗi hay gặp.

  • Chọn S3 website endpoint làm origin: OAC không dùng được, phải cấu hình custom origin.
  • Bucket policy sai AWS:SourceArn (distribution khác) hoặc dán trước khi có ID distribution: CloudFront nhận 403.
  • Object mã hóa SSE-KMS: key policy cũng phải cho service principal của CloudFront dùng key (điều kiện AWS:SourceArn theo distribution).
  • Đổi file nhưng vẫn thấy bản cũ: còn trong cache; tạo invalidation hoặc dùng tên file có version.
  • Chưa chờ distribution-deployed nên thấy kết quả cũ.
  • Để lộ private key ký URL trong repo.

Dọn (thứ tự quan trọng: disable, chờ deploy, xóa distribution, rồi mới xóa OAC).

bashReady
aws cloudfront get-distribution-config --id DIST_ID > dist.json   # lấy ETag + config# sửa DistributionConfig.Enabled=false rồi:aws cloudfront update-distribution --id DIST_ID \  --distribution-config file://dist-config-disabled.json --if-match ETAG-CUaws cloudfront wait distribution-deployed --id DIST_IDaws cloudfront get-distribution --id DIST_ID --query ETag --output textaws cloudfront delete-distribution --id DIST_ID --if-match ETAG-MOIaws cloudfront delete-origin-access-control --id OAC_ID --if-match OAC-ETAG

Sau đó xóa object và versions rồi bucket như Lab A, xóa key group rồi public key nếu đã tạo (aws cloudfront delete-key-group --id KG_ID --if-match ETAG, sau đó aws cloudfront delete-public-key --id PUB_ID --if-match ETAG; lệnh chưa chạy). Kiểm: aws cloudfront list-distributions --query 'DistributionList.Items[].Id' không còn ID lab. Lệnh chưa chạy; ETag đổi sau mỗi lần cập nhật nên phải lấy lại đúng lúc.

Evidence: hai đường truy cập có kết quả khác nhau; giải thích OAC không tự chặn viewer public. Với signed viewer config, ghi kết quả valid/invalid/expired.

Dọn: disable distribution, chờ triển khai rồi xóa; bỏ OAC/bucket policy riêng và dọn bucket. Kiểm tra objects/versions và tài nguyên phụ trợ.

Nguồn: OAC setup, signed URLs.

7. Lab F — Cost estimate và alarm có kiểm chứng#

Mục tiêu: biết cost drivers và kiểm tra alarm từ lỗi có kiểm soát.

  1. Dùng Pricing Calculator lập hai phương án cho cùng workload: Lambda/API Gateway so với ECS/Fargate/ALB. Nhập request, runtime, RAM, hours, logs, database và network; ghi phần chưa tính.

    Đáp án

    Calculator, hai phương án cùng workload (ví dụ 20 triệu request/tháng, 200 ms mỗi request, 512 MB, log 30 ngày): A = API Gateway + Lambda (+ DynamoDB nếu cần dữ liệu), B = ALB + ECS/Fargate hai task + RDS nếu cần. Với mỗi dòng ghi đơn vị và con số nhập. Dùng bảng kết quả để tìm điểm hòa vốn như bài ở GĐ32 mục 1.

  2. So bình thường/peak; thử đổi retention logs, traffic S3 qua NAT/endpoints và số AZ. Không xóa HA requirement chỉ để một phương án rẻ hơn.

    Đáp án

    Biến thể: đổi retention log (ngắn hơn / dài hơn), chuyển traffic S3 từ NAT sang gateway endpoint, đổi số AZ (1 so với 2). Không bỏ yêu cầu HA chỉ để phương án rẻ hơn.

  3. Với lab compute đã tạo, đặt alarm cho metric có thể thử an toàn: error count hoặc unhealthy target. Cấu hình threshold, periods và missing data behavior.

    Đáp án

    Tạo SNS topic và alarm trên tài nguyên Lab B (thay ARN):

    bashReady
    aws sns create-topic --name saa-lab-alertsaws sns subscribe --topic-arn TOPIC-ARN --protocol email --notification-endpoint you@example.com# mở email, bấm xác nhậnaws cloudwatch put-metric-alarm --alarm-name saa-unhealthy \  --namespace AWS/ApplicationELB --metric-name UnHealthyHostCount \  --dimensions Name=TargetGroup,Value=targetgroup/saa-tg/TG-ID \            Name=LoadBalancer,Value=app/saa-alb/LB-ID \  --statistic Maximum --period 60 --evaluation-periods 2 --threshold 1 \  --comparison-operator GreaterThanOrEqualToThreshold \  --treat-missing-data notBreaching --alarm-actions TOPIC-ARN --ok-actions TOPIC-ARN
  4. Kích hoạt lỗi trong resource lab, kiểm tra trạng thái alarm và kênh thông báo của chính bạn; khôi phục rồi xác nhận alarm về trạng thái mong đợi. Kênh email cần xác nhận subscription nếu dùng SNS.

    Đáp án

    Kiểm thử hai tầng. Tầng thông báo (không phá tài nguyên): ép trạng thái để thử đường SNS; trạng thái này sẽ tự quay về theo dữ liệu thật ở lần đánh giá tiếp theo:

    bashReady
    aws cloudwatch set-alarm-state --alarm-name saa-unhealthy \  --state-value ALARM --state-reason "test notification path"aws cloudwatch describe-alarm-history --alarm-name saa-unhealthy --max-items 5

    Tầng thật: làm một instance của Lab B trả health check lỗi (ví dụ đổi health path hoặc dừng tiến trình app trên đúng một instance lab), ghi giờ, chờ alarm sang ALARM, rồi khôi phục và chờ về OK.

  5. Sau cleanup, xem Billing/Cost Explorer và danh sách tài nguyên. Dữ liệu billing có độ trễ; ghi thời điểm cần kiểm tra lại, không kết luận zero cost ngay sau xóa.

    Đáp án

    Sau cleanup, xem Billing và Cost Explorer, kiểm tra lại sau độ trễ billing (không nêu số vì chưa xác minh), và đối chiếu danh sách tài nguyên.

Khung và mã dùng chung

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đối chiếu tài liệu AWS. Không nêu giá: mọi con số lấy từ Calculator ở ngày bạn làm và ghi lại ngày đó.

Sơ đồ (đường tín hiệu của alarm).

textReady
target unhealthy --> metric UnHealthyHostCount --> alarm (2 chu kỳ liên tiếp)        --> ALARM --> SNS topic --> email của bạn (phải xác nhận subscription) khôi phục instance --> metric về 0 --> alarm OK --> (tùy chọn) thông báo OK

Kết quả mong đợi.

Quan sátMong đợi
set-alarm-stateTrạng thái ALARM, có email (nếu đã xác nhận subscription); trạng thái rồi quay về theo dữ liệu thực
Gây lỗi thật trên một instanceUnHealthyHostCount đạt 1 trong hai chu kỳ liên tiếp -> ALARM
Khôi phụcMetric về 0 -> OK (có thể sau vài chu kỳ)
Hai estimateCùng giả định; ghi rõ dòng chưa tính

Bằng chứng cần lưu. Hai bảng estimate (export hoặc ảnh), kèm Region, ngày giá, giả định; lịch sử alarm với giờ chuyển trạng thái; email nhận được; inventory trước và sau cleanup.

Lỗi hay gặp.

  • Không xác nhận subscription email nên không thấy thông báo.
  • Alarm kẹt INSUFFICIENT_DATA: sai dimension (TargetGroup/LoadBalancer cần đúng chuỗi ARN rút gọn) hoặc chưa có metric.
  • treat-missing-data đặt sai khiến lỗi bị che hoặc báo giả.
  • set-alarm-state chỉ thử đường thông báo, không chứng minh metric và ngưỡng đúng.
  • Kết luận "zero cost" ngay sau xóa; budget alert không chặn chi phí.
  • Hai estimate khác giả định (log, traffic, số AZ) nên so sánh không có nghĩa.

Dọn.

bashReady
aws cloudwatch delete-alarms --alarm-names saa-unhealthyaws sns delete-topic --topic-arn TOPIC-ARN

Xóa log group riêng của lab nếu đã tạo. Kiểm tra budget/Cost Explorer sau độ trễ billing và ghi ngày kiểm lại. Lệnh chưa chạy; kiểm cú pháp bằng aws cloudwatch put-metric-alarm help.

Evidence: hai estimate cùng assumptions, nguồn giá/ngày/Region, alarm đã trigger/recover, inventory tài nguyên đã dọn. Ngoài vài đơn giá có ghi nguồn và ngày kiểm (ví dụ IPv4 công khai ở Lab B biến thể), tài liệu này không dùng giá cố định để tránh estimate lỗi thời; mọi estimate lấy từ Calculator.

Nguồn: Calculator, CloudWatch alarms.

Quét tài nguyên sót sau các lab#

Kiểm chứng ngày 2026-10-05 với tài liệu AWS ở cuối mục và phần help của AWS CLI 2.35.14 (aws s3 rb help, aws ec2 describe-regions help). Lệnh dưới đây chưa chạy trên AWS thật; chỉ kiểm tên lệnh và tham số bằng help.

Mỗi lab đã có phần dọn riêng; bước này là lưới an toàn cuối, làm sau khi dọn xong mọi lab. Ba điểm cần nhớ:

  • GetResources của Resource Groups Tagging API chỉ trả tài nguyên đang có tag hoặc từng có tag, trong một Region được chỉ định, nên phải lặp qua từng Region. Tài nguyên từng có tag nhưng nay không còn tag hiện với "Tags": [].
  • GetResources không trả tài nguyên chưa từng gắn tag. Tài liệu AWS hướng dẫn tìm loại này bằng Resource Explorer với truy vấn tag:none. Vì vậy lab nào không gắn tag Project=aws-saa-lab thì vẫn phải kiểm bằng phần dọn của lab đó.
  • aws s3 rb --force không xóa object versions, nên bucket từng bật versioning sẽ không xóa được nếu còn version. Khi versioning chuyển sang Suspended, các object hiện có không thay đổi, tức version cũ vẫn còn. Cách xóa hết versions và delete markers nằm ở phần dọn của GĐ33 mục 2.
  1. Sau khi dọn xong các lab, quét mọi Region đang bật để tìm tài nguyên còn tag Project=aws-saa-lab, rồi kiểm bucket nào còn version. Ghi kết quả vào bằng chứng của Lab F.

    Đáp án

    Quét tag theo từng Region (describe-regions không có --all-regions chỉ trả các Region đang bật cho account):

    bashReady
    for R in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do  echo "== $R"  aws resourcegroupstaggingapi get-resources --region "$R" \    --tag-filters Key=Project,Values=aws-saa-lab \    --query 'ResourceTagMappingList[].ResourceARN' --output textdone

    Kiểm trạng thái versioning của từng bucket, rồi xem bucket lab còn version hay delete marker không:

    bashReady
    for B in $(aws s3api list-buckets --query 'Buckets[].Name' --output text); do  echo "$B $(aws s3api get-bucket-versioning --bucket "$B" --query Status --output text)"doneaws s3api list-object-versions --bucket BUCKET --max-items 5 \  --query '{versions: Versions[].Key, markers: DeleteMarkers[].Key}'

    Kết quả mong đợi: vòng lặp tag không in ARN nào, hoặc chỉ in ARN của tài nguyên bạn chủ động giữ lại và ghi lý do. Bucket có Enabled hoặc Suspended mà còn version là chưa dọn xong: quay lại phần dọn của Lab A. KMS key ở trạng thái Pending deletion vẫn mang tag nên có thể còn hiện ra: đó là bình thường cho tới khi hết thời gian chờ xóa. Role IAM, SNS subscription và log group tạo tay cho lab cũng kiểm riêng (ví dụ aws iam list-roles --query 'Roles[].RoleName'), vì chúng có thể không mang tag lab. Sau đó vẫn xem Billing theo bước 5 ở trên.

Nguồn: GetResources, Resource Explorer search query syntax, Versioning-suspended buckets.

8. Case study — SaaS xử lý tài liệu và RAG#

Yêu cầu giả định để luyện kiến trúc: user upload PDF, xử lý bất đồng bộ, hỏi đáp qua LLM; metadata/billing cần transaction; API chịu mất một AZ; downtime khi mất Region chấp nhận vài giờ. Không có yêu cầu train ML model.

textReady
Browser → CloudFront → frontend static private S3 originBrowser → ALB HTTPS → ECS/Fargate API (hai AZ)                       ├→ RDS PostgreSQL Multi-AZ: metadata/billing                       ├→ Secrets Manager: credentials                       └→ presigned URL → browser upload S3 privateS3 upload event → SQS → worker → extraction/embedding → DB/indexBrowser → API → retrieval (tenant filter) → external LLM/Bedrock nếu chọnCloudWatch: queue age, errors, latency; CloudTrail: AWS API audit

Phân biệt frontend static dùng CloudFront với PDF user private: không cho viewer public đọc mọi PDF. API phải xác thực user, chọn key/prefix và quyền tenant; IAM của worker không thay tenant authorization trong app.

Giải thích quyết định: PostgreSQL cho quan hệ/transaction; S3 cho file; queue để xử lý burst; worker compute chọn theo duration/RAM; app hai AZ và DB Multi-AZ cho AZ failure. Nếu cần OCR managed có thể đánh giá Textract; gọi LLM không tự tạo nhu cầu SageMaker.

S3 → SQS trực tiếp dùng Standard queue cùng Region và queue policy cho S3 với source conditions phù hợp; nếu cần FIFO phải thiết kế đường trung gian hỗ trợ như EventBridge. Event có thể trùng; worker dùng idempotency. Không để output ghi lại prefix trigger tạo loop.

Recovery: backup/PITR và bản dữ liệu ở recovery Region theo RPO; template/config/secret/permissions phải có kế hoạch dựng lại. DNS failover riêng không đủ. Theo dõi egress worker → LLM, queue age, DB connections và chi phí embedding.

Bài tập: vẽ phiên bản tối giản cho MVP; thêm AZ resilience; thêm Region recovery. Với mỗi phiên bản, ghi tài nguyên tăng thêm, yêu cầu được đáp ứng và chi phí tăng. Xem capstone GĐ25 cho hành vi sản phẩm.

Lời giải và cách kiểm tra: ba phiên bản MVP, thêm AZ, thêm Region

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; đây là lập luận thiết kế, không có giá cố định. Đáp án là một lựa chọn hợp lý, không phải đáp án duy nhất; điểm chấm là lập luận theo requirement.

Sơ đồ.

textReady
(1) MVP tối giản: chưa chịu mất AZ, Region recovery = dựng lại từ backup Browser -> CloudFront -> S3 (static, private, OAC) Browser -> ALB (subnet ở 2 AZ, theo yêu cầu của ALB) -> 1 task API (AZ-a) API -> RDS PostgreSQL Single-AZ ; presigned URL -> S3 private (PDF) S3 event -> SQS (+DLQ) -> 1 worker (AZ-a) -> DB/index Backup: automated backup RDS + versioning S3 ; IaC trong repo(2) + chịu mất một AZ ALB -> API task x2 (AZ-a, AZ-b)      RDS Multi-AZ (instance hoặc cluster) SQS -> worker x2 (hai AZ)            egress: NAT mỗi AZ hoặc Regional NAT,                                      hoặc endpoints; rà điểm đơn còn lại(3) + khôi phục khi mất Region (downtime vài giờ chấp nhận) Region chính                          Region phụ (chưa chạy full app) RDS ---- snapshot copy / backup ---->  bản sao backup (hoặc replica tùy RPO) S3  ---- replication (versioning) --->  bucket đích IaC + image + secrets + quyền: có kế hoạch dựng lại ở Region phụ DNS chuyển sang Region phụ SAU khi dựng xong và validate

Bảng thay đổi.

Phiên bảnTài nguyên tăng thêmRequirement được đáp ứngYếu tố chi phí tăng
(1) MVPCơ sở: CloudFront, S3, ALB, API, RDS Single-AZ, SQS, workerChức năng; phục hồi bằng backupCố định: ALB, DB, task
(2) + AZTask thứ hai/AZ thứ hai, RDS Multi-AZ, worker thứ hai, egress theo AZMất một AZ vẫn phục vụNhân đôi compute nền; DB Multi-AZ; NAT/endpoint theo AZ; cross-AZ transfer
(3) + RegionBản sao backup/replication sang Region phụ, template và image sẵn ở Region phụRPO/RTO của sự cố Region theo yêu cầu "vài giờ"Storage bản sao, transfer giữa Region; chưa trả compute full ở Region phụ

Vì sao chọn mức này cho (3), và vì sao loại phương án khác. Yêu cầu chấp nhận vài giờ downtime khi mất Region và không cần ghi đa Region, nên backup/restore hoặc pilot light là đủ. Loại active/active đa Region vì vượt yêu cầu (chi phí và độ phức tạp ghi dữ liệu). Chỉ failover DNS mà không có dữ liệu, template, secret, quyền ở Region phụ thì không phục hồi được; vì vậy phải có kế hoạch dựng lại. Nếu yêu cầu đổi sang phút thay vì giờ thì nâng lên pilot light hoặc warm standby và đo lại RTO thực.

Lỗi hay gặp. Coi RDS Multi-AZ là Region recovery (nó chỉ nằm trong một Region); quên rằng S3 replication cần versioning và không copy object có sẵn nếu chỉ bật live replication; chỉ nhân đôi compute mà để NAT/DB ở một AZ; quên kiểm tra tenant filter ở retrieval khi mở rộng.

Nguồn kỹ thuật event: S3 notification destinations, S3 notification permissions.

9. Case study — ba yêu cầu, ba thiết kế khác nhau#

Tình huống tự xâyHướng đánh giáPhương án dễ chọn sai
Static site global, file public, deploy ítS3 private + CloudFront OAC, versioned assetsEC2/ALB chỉ để phục vụ HTML static
Đơn hàng SQL, phải chịu AZ failure, read reports tăngRDS Multi-AZ cho HA; replica/cache/query tuning cho đọcChỉ bật read replica rồi coi HA/failover đã hoàn tất
Batch có thể chạy lại, completion trong vài giờQueue + Spot/container/Batch, checkpoint, retryMột Spot instance giữ dữ liệu duy nhất

Với mỗi dòng, thay một requirement: static site có user-private content; báo cáo phải đọc ngay write mới; batch có deadline cứng và không chịu interruption. Kiến trúc phải được đánh giá lại theo yêu cầu mới.

Lời giải và cách kiểm tra: đổi một requirement trong từng tình huống

Kiểm chứng ngày 2026-10-05. Chưa chạy trên AWS thật; lập luận theo tài liệu AWS. Với mỗi dòng: chỉ requirement bị đổi, kiến trúc mới, vì sao phương án cũ không còn đủ.

Tình huống đổiKiến trúc mớiVì sao phương án cũ hoặc phương án khác bị loại
Static site nay có nội dung private theo userGiữ S3 private + CloudFront OAC cho origin; thêm signed URL hoặc signed cookie (trusted key group), hoặc kiểm quyền ở lớp ứng dụng/edge, tùy mô hìnhOAC chỉ bảo vệ origin: ai có URL CloudFront vẫn xem được, nên không đủ cho nội dung theo user. Public bucket bị loại vì bỏ kiểm soát. EC2/ALB phục vụ HTML không giải quyết quyền viewer
Báo cáo phải đọc ngay write mớiĐọc từ writer (hoặc strongly consistent read nếu dùng DynamoDB base table); replica/cache chỉ cho báo cáo chấp nhận độ trễRead replica bất đồng bộ có replica lag; Multi-AZ DB cluster dùng semi-synchronous nhưng không bảo đảm reader đã áp dụng thay đổi; GSI của DynamoDB luôn eventually consistent; cache có thể stale
Batch có deadline cứng, không chịu gián đoạnOn-Demand (hoặc Savings Plans cho phần nền ổn định); cần chắc chắn có capacity ở AZ thì thêm Capacity Reservation; có thể trộn Spot cho phần dưSpot có thể bị thu hồi vì capacity/giá nên không bảo đảm deadline nếu là nguồn duy nhất. Savings Plans chỉ giảm giá, không giữ chỗ. Capacity Reservation giữ chỗ nhưng không tự có chiết khấu

Cách tự kiểm. Viết lại một dòng của bảng "ba yêu cầu" ở trên với requirement mới và chỉ ra đúng một câu: requirement nào làm phương án cũ sai. Nếu không chỉ ra được, bạn mới học tên dịch vụ chứ chưa học điều kiện chọn.

10. Câu hỏi tự luyện — security và networking#

Chọn trước khi mở đáp án. Mỗi câu chọn một phương án phù hợp nhất với các điều kiện đã nêu.

1. EC2 phải đọc raw/* trong S3, không lưu static credentials. Chọn gì?

A. Access key trong image. B. EC2 instance role với quyền tối thiểu. C. Public bucket. D. Root credentials trong environment.

Đáp án

B — role cấp temporary credentials; các phương án khác tăng exposure hoặc bỏ kiểm soát truy cập. Loại: A, key nằm trong image bị lộ cùng image và khó xoay vòng; C, public bucket bỏ kiểm soát truy cập, ngược yêu cầu "chỉ đọc raw/*"; D, root credentials là rủi ro lớn nhất, không dùng cho workload.

2. Role có Allow đọc S3 nhưng SCP áp dụng có explicit Deny action đó. Kết quả?

A. Allow vì role gần resource. B. Allow khi retry. C. Deny. D. SCP tự cấp quyền administrator.

Đáp án

C — explicit deny áp dụng thắng allow; retry không đổi policy. Loại: A, không có quy tắc "gần resource hơn thì thắng"; B, retry không đổi kết quả đánh giá policy; D, SCP chỉ đặt trần quyền tối đa, không cấp quyền.

3. App private chỉ cần đọc S3 trong Region, muốn tránh đường NAT cho traffic này. Chọn gì?

A. IGW và không cần public IP. B. S3 gateway endpoint với route/policy phù hợp. C. NLB. D. Route 53 weighted record.

Đáp án

B — gateway endpoint tạo đường S3 phù hợp; app vẫn cần quyền S3. DNS/load balancer không thay endpoint route. Loại: A, IGW là đường ra Internet, instance private không public IP không dùng được nó và vẫn là đường công khai; C, NLB là cân bằng tải inbound, không tạo đường ra S3; D, Route 53 weighted record chỉ chia DNS.

4. EC2 không có public IP ở subnet có route IGW. Vì sao inbound IPv4 Internet trực tiếp không vào được?

A. Mọi subnet public đều tự cấp public IP. B. Cần địa chỉ public và các lớp route/firewall phù hợp. C. IAM role mở network. D. S3 endpoint cấp public IP.

Đáp án

B — route IGW riêng chưa đủ; SG/NACL và địa chỉ cũng phải phù hợp. IAM quản quyền API, không cấp IP. Loại: A, subnet có route IGW không tự cấp public IP (phụ thuộc cấu hình auto-assign hoặc Elastic IP); C, IAM role quản quyền gọi API AWS, không mở network; D, S3 endpoint là đường ra S3, không cấp public IP cho instance.

11. Câu hỏi tự luyện — resilience và messaging#

5. Worker Standard SQS commit kết quả rồi chết trước delete. Yêu cầu không tạo kết quả business trùng. Chọn gì?

A. Bỏ retry. B. Idempotency theo job ID với transaction/constraint phù hợp. C. Chỉ tăng CPU. D. Xóa message trước xử lý.

Đáp án

B — retry sau commit có thể lặp; business invariant phải được giữ trong ứng dụng. Xóa sớm có thể mất job. Loại: A, bỏ retry thì mất job khi lỗi tạm; C, CPU không liên quan tới giao lặp; D, xóa trước khi xử lý là "tối đa một lần": crash giữa chừng thì mất job.

6. Cần ba consumer độc lập đều nhận cùng event, mỗi consumer có buffer riêng. Chọn gì?

A. Ba worker cùng một queue. B. SNS fan-out tới ba SQS queues. C. Một SG cho ba worker. D. ASG desired 3.

Đáp án

B — queue riêng cho mỗi consumer giữ event độc lập. Nhiều worker cùng queue thường chia jobs. Loại: A, competing consumers: mỗi message chỉ tới một worker; C, security group là tường lửa; D, ASG desired 3 chỉ là số instance.

7. API cần chịu mất một AZ. Thiết kế nào xử lý trực tiếp failure domain đó tốt hơn?

A. Hai EC2 cùng subnet một AZ. B. App nhiều AZ + LB và data tier có HA phù hợp. C. Một máy lớn hơn. D. Backup app disk hàng tháng.

Đáp án

B — redundancy phải vượt ranh giới AZ và xét data/dependencies. Tăng máy không đổi failure domain. Loại: A, cùng một AZ thì mất AZ là mất hết; C, máy lớn hơn vẫn nằm trong một AZ; D, backup hàng tháng là RPO rất dài và không có failover.

8. Core data đang replicate tới recovery site; full app đã chạy capacity nhỏ, cần scale khi failover. Chiến lược?

A. Backup/restore thuần. B. Warm standby. C. Pilot light chỉ giữ core và chưa chạy full app. D. Active/active đủ tải cả hai site.

Đáp án

B — full app hoạt động ở capacity nhỏ là warm standby; vẫn cần đo RTO thực tế. Loại: A, backup/restore không có gì đang chạy; C, pilot light chỉ giữ lõi, app chưa chạy đầy đủ (đề nói full app đã chạy); D, active/active chạy đủ tải ở cả hai site, vượt mô tả.

12. Câu hỏi tự luyện — performance và dữ liệu#

9. RDS Multi-AZ DB instance truyền thống đã có standby; muốn scale báo cáo đọc. Chọn gì?

A. Route SELECT tới standby đó. B. Đánh giá read replica và sửa query/index, chấp nhận lag phù hợp. C. Public DB. D. Tăng số ALB.

Đáp án

B — standby của Multi-AZ DB instance không phục vụ reads. DB cluster là mô hình khác; replica/query tuning phải đúng yêu cầu consistency. Loại: A, standby của Multi-AZ DB instance không nhận read traffic; C, public DB mở rộng bề mặt tấn công và không scale đọc; D, thêm ALB không tăng năng lực database.

10. DynamoDB GSI trả dữ liệu cũ ngay sau write; cần strong read bằng key chính. Chọn gì?

A. ConsistentRead=true trên GSI. B. Strongly consistent read trên base table với key phù hợp. C. TTL. D. CloudFront invalidation.

Đáp án

B — GSI không hỗ trợ strong read; phải có key truy cập base table. Nếu cần truy vấn khác, thiết kế lại access pattern. Loại: A, strongly consistent read không được hỗ trợ trên GSI; C, TTL dọn item hết hạn, không liên quan consistency; D, CloudFront invalidation là cache của CDN, không phải DynamoDB.

11. Nhiều Linux instances cần mount shared filesystem. Chọn dịch vụ mặc định để đánh giá?

A. EFS. B. Instance store một máy. C. S3 thay POSIX mount không cần thay app. D. Snapshot EBS.

Đáp án

A — EFS phục vụ shared NFS access; còn phải đánh giá throughput/HA/quyền. Ba phương án còn lại không tự tạo shared filesystem đúng yêu cầu. Loại: B, instance store gắn với một host và mất khi instance bị thay; C, S3 là object API, không mount POSIX nếu không đổi ứng dụng; D, snapshot EBS là bản sao lưu, không phải filesystem dùng chung.

12. Cần archive ít đọc nhưng retrieval milliseconds. Chọn class để đánh giá?

A. Glacier Deep Archive. B. Glacier Flexible Retrieval không restore. C. Glacier Instant Retrieval. D. Chỉ download trước mỗi request.

Đáp án

C — Instant Retrieval có truy cập tức thời; vẫn xét retrieval fee, retention và giá. Flexible/Deep cần restore. Loại: A, Deep Archive cần restore, Standard trong 12 giờ và Bulk trong 48 giờ; B, Flexible Retrieval cần restore (Expedited cũng cỡ 1-5 phút), không phải mili giây; D, tải trước mỗi request là hack tăng độ trễ và chi phí.

13. Câu hỏi tự luyện — cost và migration#

13. Batch jobs có checkpoint, chấp nhận interruption và chạy lại. Hướng giảm compute cost?

A. Spot với queue/checkpoint/retry và capacity fallback theo deadline. B. Dedicated Host bất kể license. C. Luôn máy lớn nhất. D. Bỏ checkpoint.

Đáp án

A — job chịu gián đoạn mới thích hợp Spot; deadline/capacity vẫn cần phương án. Checkpoint giảm công mất khi retry. Loại: B, Dedicated Host dành cho license/compliance, không phải tiết kiệm; C, máy lớn nhất không giảm chi phí; D, bỏ checkpoint làm mất công khi bị thu hồi.

14. Compute ổn định, cam kết chi tiêu theo giờ nhưng muốn linh hoạt theo phạm vi plan. Chọn gì?

A. Savings Plans phù hợp. B. Capacity Reservation mặc định discount. C. Budget alert. D. EIP.

Đáp án

A — commitment theo USD/giờ; phải chọn phạm vi plan phù hợp. Discount khác việc giữ capacity. Loại: B, Capacity Reservation giữ chỗ chứ không mặc định có chiết khấu; C, budget alert chỉ cảnh báo, không giảm giá; D, Elastic IP không liên quan.

15. Cần database migration full load rồi tiếp tục replicate changes, source/target hỗ trợ. Chọn gì?

A. DataSync thay CDC database. B. DMS, kèm schema assessment/validation/cutover. C. CloudFront. D. WAF.

Đáp án

B — DMS cho data migration/change replication hỗ trợ, không tự bảo đảm toàn bộ schema và app đúng. Loại: A, DataSync chuyển file/object, không thay change replication của database; C, CloudFront là CDN; D, WAF là tường lửa ứng dụng.

16. Budget vượt ngưỡng nhưng tài nguyên vẫn chạy. Hiểu đúng thế nào?

A. AWS chắc chắn lỗi. B. Budget alert không phải hard cap; kiểm tra action đã cấu hình và dữ liệu có độ trễ. C. Mọi tài nguyên tự xóa. D. Chi phí không bao giờ vượt ngưỡng.

Đáp án

B — alert không trực tiếp ngắt mọi tài nguyên; phải xử lý theo policy/account thực tế. Loại: A, vượt ngưỡng không có nghĩa AWS lỗi; C, tài nguyên không tự xóa; D, chi phí hoàn toàn có thể vượt ngưỡng vì alert không chặn.

Ngân hàng câu hỏi theo domain SAA-C03#

Kiểm chứng ngày 2026-10-05 với exam guide SAA-C03 và tài liệu AWS ghi ở cuối đáp án của từng câu. 65 câu dưới đây (số 17–81, nối tiếp 16 câu ở mục 10–13) do guide tự viết theo task statement của exam guide; không chép và không dựng lại từ đề thi thật hay exam dumps. Chưa chạy trên AWS thật: đáp án lập luận từ tài liệu AWS, và link "Nguồn" là trang quyết định đáp án.

Cách dùng: làm hết một khối task rồi mới mở đáp án, ghi câu sai vào error notebook ở mục 14. Câu một đáp án có bốn phương án, giống dạng multiple choice trong exam guide (một đúng, ba sai). Câu ghi "Chọn HAI" có năm phương án và hai đáp án đúng; exam guide gọi dạng này là multiple response (hai đáp án đúng trở lên trong năm phương án trở lên).

DomainTrọng sốSố câuCâuChọn HAI
1. Design Secure Architectures30%1917–354
2. Design Resilient Architectures26%1736–523
3. Design High-Performing Architectures24%1653–683
4. Design Cost-Optimized Architectures20%1369–812
Tổng100%6517–8112 (18,5%)

Số câu mỗi domain lấy 65 nhân trọng số rồi làm tròn theo phần dư lớn nhất. Vị trí đáp án đúng được trộn đều: 53 câu một đáp án có đáp án ở A/B/C/D lần lượt 14/13/13/13 lần; 12 câu "Chọn HAI" có 24 đáp án đúng, A/B/C/D/E lần lượt 4/5/5/5/5 lần. Đừng đoán theo chữ cái. Task 3.5 có sáu câu (63–68) phủ Kinesis, EMR, Lake Formation, Amazon Quick, Athena, DataSync, Storage Gateway, Glue và đổi CSV sang Parquet.

Bộ câu này kiểm tra lập luận theo requirement, không mô phỏng độ khó, coverage hay xác suất đỗ của đề thật.

Domain 1 — Design Secure Architectures (30%, câu 17–35)#

Task 1.1 — truy cập an toàn tới tài nguyên AWS (câu 17–23)

17. Một startup vừa mở account AWS cho team 5 người. Root user còn một access key cũ do người sáng lập tạo và chưa bật MFA. Công ty muốn giảm rủi ro cho root mà team vẫn làm việc hằng ngày đủ quyền. Chọn HAI.

  • A. Chia sẻ mật khẩu root cho cả 5 người để ai cũng xử lý được sự cố.
  • B. Tạo thêm access key thứ hai cho root để xoay vòng định kỳ.
  • C. Bật MFA cho root user.
  • D. Dùng root cho pipeline CI/CD vì root có đủ mọi quyền.
  • E. Xóa access key của root user; tạo danh tính quản trị riêng (IAM Identity Center hoặc IAM) cho công việc hằng ngày.
Đáp án

C, E — Hai việc nền tảng cho root là MFA và không giữ access key; công việc hằng ngày đi qua danh tính riêng có quyền phù hợp.

Loại:

  • A: Root là danh tính quyền cao nhất; dùng chung làm mất truy vết từng người và ngược khuyến nghị chỉ dùng root cho số ít tác vụ cần root.
  • B: Khuyến nghị là root không có access key; xoay vòng vẫn giữ nguyên rủi ro một credential dài hạn quyền cao nhất.
  • D: Máy dùng credential root là bề mặt tấn công lớn nhất; workload cần role với quyền tối thiểu.

Nguồn: Root user best practices.

18. Script kiểm kê chạy trên EC2 ở account Tooling cần gọi ec2:DescribeInstances trên 30 account khác trong cùng organization. Yêu cầu: không lưu access key dài hạn ở đâu cả. Chọn thiết kế nào?

  • A. Tạo IAM user ở mỗi account đích và lưu 30 cặp access key trên instance.
  • B. Tạo VPC peering từ VPC Tooling tới VPC của từng account.
  • C. Tạo IAM role ở mỗi account đích với trust policy tin account Tooling và quyền Describe chỉ đọc; instance role ở Tooling được phép sts:AssumeRole vào các role đó.
  • D. Gắn một SCP Allow ec2:Describe* vào root của organization.
Đáp án

C — Role chéo account trả credential tạm thời qua STS; account đích quyết định ai được assume qua trust policy, account nguồn cấp quyền sts:AssumeRole.

Loại:

  • A: Đây chính là access key dài hạn mà đề cấm.
  • B: Peering là kết nối mạng giữa VPC, không cấp quyền gọi API AWS.
  • D: SCP không cấp quyền; nó chỉ đặt giới hạn tối đa, principal vẫn cần policy IAM cho phép.

Nguồn: Cross-account access với role, Service control policies.

19. Tổ chức dùng AWS Organizations. Yêu cầu: không ai trong các member account, kể cả admin và root user của account đó, được dừng hoặc xóa trail CloudTrail. Chọn gì?

  • A. SCP Deny cloudtrail:StopLogging và cloudtrail:DeleteTrail, gắn vào OU chứa các member account.
  • B. Gắn permissions boundary cho mọi IAM user hiện có.
  • C. Viết IAM policy Deny trong management account.
  • D. Bật MFA cho mọi IAM user.
Đáp án

A — SCP đặt trần quyền cho mọi principal trong member account, kể cả root user của account đó. Lưu ý SCP không ảnh hưởng management account, nên trail ở management account cần kiểm soát riêng.

Loại:

  • B: Boundary gắn theo từng principal; admin trong account có thể tạo principal mới không có boundary, và boundary không áp lên root user.
  • C: Policy IAM trong management account chỉ áp cho principal của account đó, không áp lên principal ở member account.
  • D: MFA xác thực người dùng; người đã đăng nhập hợp lệ và có quyền vẫn dừng được trail.

Nguồn: Service control policies, Permissions boundaries.

20. Doanh nghiệp có 300 nhân viên quản lý trong một IdP bên ngoài hỗ trợ SAML. Họ cần đăng nhập một lần vào 40 account AWS với bộ quyền theo vai trò (dev, ops, read-only), và khi nhân viên nghỉ việc thì khóa ở IdP là mất quyền AWS. Chọn gì?

  • A. Tạo IAM user cho 300 người ở mỗi account.
  • B. Mỗi vai trò dùng chung một IAM user và mật khẩu.
  • C. IAM Identity Center (organization instance) kết nối IdP, gán permission sets cho nhóm theo từng account.
  • D. Gửi access key dài hạn cho từng nhân viên qua email.
Đáp án

C — Identity Center kết nối nguồn danh tính bên ngoài, quản lý truy cập nhiều account bằng permission sets; organization instance là cách được khuyến nghị.

Loại:

  • A: Tạo hàng nghìn user rời rạc; nghỉ việc phải xóa ở 40 nơi, không dùng IdP làm nguồn sự thật.
  • B: Mất truy vết từng người và không thu hồi được quyền của riêng một người.
  • D: Credential dài hạn qua kênh không an toàn; không nối với vòng đời tài khoản ở IdP.

Nguồn: What is IAM Identity Center.

21. Team platform muốn để dev lead tự tạo IAM role cho Lambda của team, nhưng role đó không bao giờ vượt quá quyền DynamoDB và CloudWatch Logs, kể cả khi lead gắn policy AdministratorAccess vào role. Chọn cách nào?

  • A. Dặn lead bằng quy trình nội bộ là không gắn AdministratorAccess.
  • B. Cho lead quyền iam:CreateRole kèm điều kiện iam:PermissionsBoundary bắt buộc gắn một boundary chỉ gồm DynamoDB và Logs.
  • C. Gắn SCP chỉ cho phép DynamoDB và Logs vào account.
  • D. Không cho lead tạo role; platform tạo một role dùng chung cho mọi Lambda.
Đáp án

B — Permissions boundary đặt quyền tối đa cho role; quyền thực tế là phần giao giữa boundary và policy gắn vào role. Điều kiện iam:PermissionsBoundary buộc lead phải gắn boundary khi tạo role. Để lead không gỡ hoặc thay boundary về sau, policy của lead cũng phải Deny iam:DeleteRolePermissionsBoundary và chỉ cho iam:PutRolePermissionsBoundary với đúng boundary đã chọn (ví dụ delegation trong tài liệu IAM về permissions boundary).

Loại:

  • A: Không có kiểm soát kỹ thuật; một lần quên là role có toàn quyền.
  • C: SCP áp cho mọi principal trong account, chặn luôn công việc của các team khác, không chỉ role do lead tạo.
  • D: Không đáp ứng yêu cầu lead tự tạo role, và role dùng chung dễ thừa quyền.

Nguồn: Permissions boundaries.

22. Công ty chạy Amazon RDS for PostgreSQL. Kiểm toán hỏi trong mô hình trách nhiệm chia sẻ, việc nào thuộc về khách hàng. Chọn HAI.

  • A. Vá hệ điều hành của host chạy DB instance.
  • B. Cấu hình security group giới hạn nguồn được kết nối tới DB instance.
  • C. Quản lý user, role và quyền bên trong DB engine.
  • D. Bảo trì phần cứng và mạng vật lý của data center.
  • E. Thay ổ đĩa vật lý hỏng dưới DB instance.
Đáp án

B, C — Với RDS, AWS vận hành hạ tầng và tự thực hiện bảo trì, kể cả cập nhật hệ điều hành bên dưới. Khách hàng kiểm soát ai kết nối tới DB (security group, IAM) và ai đăng nhập vào DB (tính năng bảo mật của engine).

Loại:

  • A: Với RDS, việc bảo trì hệ điều hành bên dưới do RDS thực hiện trong maintenance window.
  • D: Hạ tầng vật lý thuộc phần trách nhiệm của AWS.
  • E: Phần cứng storage vật lý do AWS vận hành.

Nguồn: Shared responsibility model, Security in Amazon RDS, RDS maintenance.

23. Bucket chứa báo cáo nội bộ chỉ được truy cập từ ứng dụng trong VPC qua gateway endpoint vpce-0abc. Kể cả IAM user có quyền S3 rộng cũng không được đọc khi đứng ngoài VPC. Chọn gì?

  • A. Bật SSE-KMS cho bucket.
  • B. Thêm NACL chặn 0.0.0.0/0 trên subnet của ứng dụng.
  • C. Bật versioning cho bucket.
  • D. Bucket policy Deny các action S3 khi aws:SourceVpce khác vpce-0abc.
Đáp án

D — Điều kiện aws:SourceVpce trong bucket policy là resource policy giới hạn truy cập theo endpoint. Deny rộng có thể khóa cả quyền quản trị qua console, nên phải thử kỹ trước khi áp.

Loại:

  • A: Mã hóa không giới hạn đường truy cập; ai có quyền S3 và KMS vẫn đọc được từ bất kỳ đâu.
  • B: NACL lọc traffic của subnet đó, không ảnh hưởng request tới S3 từ máy ở ngoài VPC.
  • C: Versioning giữ phiên bản object, không kiểm soát ai đọc từ đâu.

Nguồn: Bucket policy với VPC endpoint.

Task 1.2 — workload và ứng dụng an toàn (câu 24–30)

24. Ứng dụng trên ECS đọc mật khẩu DB từ biến môi trường ghi cứng trong task definition. Yêu cầu mới: mật khẩu tự đổi mỗi 30 ngày mà không deploy lại code. Chọn gì?

  • A. Lưu mật khẩu trong AWS Secrets Manager, bật automatic rotation và để ứng dụng đọc secret lúc chạy.
  • B. Lưu trong Parameter Store dạng String thường.
  • C. Mã hóa biến môi trường bằng base64.
  • D. Ghi mật khẩu vào file trong container image.
Đáp án

A — Secrets Manager hỗ trợ rotation tự động theo lịch; ứng dụng lấy giá trị hiện hành khi chạy nên không cần deploy lại.

Loại:

  • B: Chuỗi không mã hóa, và chính tài liệu Parameter Store khuyến nghị Secrets Manager cho credential cần xoay tự động.
  • C: Base64 là mã hóa ký tự, không phải bảo mật; vẫn không tự xoay.
  • D: Đổi mật khẩu phải build và deploy lại image, và secret lộ theo image.

Nguồn: Rotate Secrets Manager secrets, Parameter Store.

25. ALB công khai nhận nhiều request chứa chuỗi SQL injection vào form tìm kiếm. Team muốn chặn trước khi request tới ứng dụng, dùng rule do AWS quản lý thay vì tự viết. Chọn gì?

  • A. Sửa security group của ALB để chặn port 443.
  • B. Thêm NACL deny theo từng IP tấn công.
  • C. Gắn AWS WAF web ACL vào ALB với managed rule group cho SQL database.
  • D. Bật Amazon GuardDuty.
Đáp án

C — WAF kiểm tra nội dung request ở tầng 7; managed rule group SQL database có rule chặn mẫu SQL injection.

Loại:

  • A: Chặn luôn mọi người dùng hợp lệ; security group không đọc nội dung HTTP.
  • B: NACL chỉ lọc theo IP/port, không nhận diện payload SQL injection, và IP tấn công thay đổi liên tục.
  • D: GuardDuty là dịch vụ phát hiện mối đe dọa từ các nguồn như CloudTrail, VPC flow logs, DNS; nó không đứng trên đường đi để lọc request HTTP.

Nguồn: AWS WAF managed rule groups theo use case, What is GuardDuty.

26. Data lake S3 có hàng triệu object do nhiều team upload. Compliance cần biết bucket và object nào có thông tin cá nhân (PII) để xử lý. Chọn dịch vụ nào?

  • A. Amazon GuardDuty.
  • B. S3 Inventory.
  • C. CloudTrail data events.
  • D. Amazon Macie.
Đáp án

D — Macie dùng machine learning và pattern matching để phát hiện dữ liệu nhạy cảm, gồm PII, trong S3.

Loại:

  • A: GuardDuty phát hiện hoạt động đáng ngờ, không phân loại nội dung object.
  • B: Inventory liệt kê object và metadata, không đọc nội dung để tìm PII.
  • C: Data events ghi ai gọi API nào trên object, không cho biết object chứa gì.

Nguồn: What is Amazon Macie.

27. Kiến trúc ba tầng: ALB public, app EC2 trong private subnet, RDS MySQL. Yêu cầu: DB không có đường từ Internet và chỉ app tier kết nối được, kể cả khi ASG thêm instance có IP mới. Chọn HAI.

  • A. Đặt RDS trong DB subnet group gồm private subnet (không route tới IGW) và tắt publicly accessible.
  • B. Security group của DB cho phép 3306 với nguồn là security group của app tier.
  • C. Security group DB cho phép 3306 từ 0.0.0.0/0 vì DB đã ở private subnet.
  • D. Security group DB liệt kê IP private của từng instance app.
  • E. Đặt DB trong public subnet rồi chặn bằng NACL.
Đáp án

A, B — Tách subnet theo tầng giữ DB không có route Internet; tham chiếu security group cho phép mọi instance mang SG của app, bất kể IP.

Loại:

  • C: Vi phạm "chỉ app tier kết nối"; bỏ một lớp phòng thủ nếu sau này route thay đổi.
  • D: IP đổi khi ASG thay hoặc thêm instance, rule sẽ lỗi thời.
  • E: DB có đường tới Internet, trái yêu cầu; NACL stateless còn dễ cấu hình sai.

Nguồn: Security group rules.

28. Subnet web có custom NACL: inbound cho phép TCP 443 từ 0.0.0.0/0; outbound chỉ cho phép TCP 443 tới 0.0.0.0/0. Security group đúng, nhưng client không tải được trang. Sửa gì?

  • A. Thêm rule outbound NACL cho phép TCP 1024-65535 tới 0.0.0.0/0.
  • B. Thêm inbound rule security group cho 1024-65535.
  • C. Đổi NACL sang chế độ stateful.
  • D. Thêm outbound rule security group cho port 443.
Đáp án

A — NACL stateless nên response đi ra port tạm của client cần rule outbound riêng; tài liệu VPC khuyến nghị trên thực tế mở 1024-65535 để phủ mọi loại client (ví dụ NACL trong tài liệu dùng 32768-65535).

Loại:

  • B: Security group là stateful nên response đã được cho phép; lỗi nằm ở NACL.
  • C: NACL là stateless, không có tùy chọn stateful.
  • D: Response của kết nối inbound đã được security group cho phép tự động; vấn đề là NACL chặn response.

Nguồn: Network ACLs, Custom network ACL và ephemeral ports.

29. Instance trong private subnet không có route ra Internet (không NAT). Ứng dụng cần gọi AWS KMS và Systems Manager, và traffic này không được đi qua Internet. Chọn gì?

  • A. Tạo gateway endpoint cho KMS.
  • B. Gán Elastic IP cho instance và thêm route tới IGW.
  • C. Peering tới một VPC khác có NAT gateway.
  • D. Tạo interface VPC endpoints cho KMS và các endpoint Systems Manager, bật private DNS.
Đáp án

D — Interface endpoint (PrivateLink) đưa endpoint dịch vụ vào VPC; với private DNS, SDK gọi tên dịch vụ mặc định mà vẫn đi đường riêng.

Loại:

  • A: Gateway endpoint chỉ có cho S3 và DynamoDB.
  • B: Traffic đi Internet, trái yêu cầu, và mở bề mặt tấn công.
  • C: Mục đích của NAT là ra Internet, trái yêu cầu traffic không đi Internet; ngoài ra VPC peering không cho VPC này dùng NAT gateway của VPC kia (không có edge to edge routing); thêm VPC thứ hai chỉ tăng độ phức tạp.

Nguồn: Gateway endpoints, Interface endpoints cho dịch vụ AWS, VPC peering basics.

30. Văn phòng cần kết nối mã hóa tới một VPC trong tuần này, băng thông vừa phải, chấp nhận đi qua Internet. Chọn gì?

  • A. AWS Direct Connect.
  • B. VPC peering từ VPC tới văn phòng.
  • C. Gateway endpoint.
  • D. AWS Site-to-Site VPN (IPsec) giữa thiết bị văn phòng và virtual private gateway hoặc transit gateway.
Đáp án

D — Site-to-Site VPN dùng IPsec qua Internet, phù hợp kết nối mã hóa cần sớm với băng thông vừa phải.

Loại:

  • A: Direct Connect là kết nối mạng riêng tới AWS và mặc định không mã hóa traffic; với yêu cầu đơn giản này nó tốn công triển khai hơn cần thiết.
  • B: Peering chỉ nối hai VPC, không nối mạng on-premises.
  • C: Gateway endpoint chỉ cho S3 và DynamoDB từ trong VPC.

Nguồn: What is Site-to-Site VPN, Direct Connect encryption in transit.

Task 1.3 — kiểm soát bảo mật dữ liệu (câu 31–35)

31. Compliance yêu cầu object S3 mã hóa at rest, mọi lần dùng key phải có log audit, và công ty tự quyết định ai được dùng key qua key policy. Chọn gì?

  • A. SSE-KMS với customer managed key.
  • B. SSE-S3.
  • C. Mã hóa phía client với key lưu trong source code.
  • D. Bật versioning.
Đáp án

A — SSE-KMS dùng KMS key; với customer managed key, công ty tự quản key policy. CloudTrail ghi mọi lời gọi API tới KMS, nên việc dùng key đều có dấu vết audit theo từng lời gọi KMS (với S3 Bucket Key, S3 dùng lại một key cấp bucket trong một khoảng thời gian nên số lời gọi KMS ít hơn số object).

Loại:

  • B: Key do S3 quản lý, không có key policy riêng để công ty kiểm soát ai dùng key.
  • C: Key lộ theo source; không có log dùng key tập trung.
  • D: Versioning không phải mã hóa.

Nguồn: SSE-KMS, Logging AWS KMS API calls với CloudTrail.

32. Bản ghi giao dịch phải không thể xóa hay ghi đè trong 7 năm, kể cả bởi root user. Chọn gì?

  • A. S3 Object Lock ở governance mode.
  • B. S3 Object Lock ở compliance mode với retention 7 năm.
  • C. Bucket policy Deny s3:DeleteObject.
  • D. Lifecycle chuyển object sang Glacier Deep Archive.
Đáp án

B — Ở compliance mode, không user nào, kể cả root, ghi đè hay xóa được phiên bản object trong thời hạn retention.

Loại:

  • A: Governance mode cho phép user có quyền đặc biệt bỏ qua khóa, không đạt yêu cầu "kể cả root".
  • C: Người quản trị có quyền sửa bucket policy có thể gỡ câu Deny rồi xóa.
  • D: Đổi storage class để giảm chi phí, không chặn xóa hay ghi đè.

Nguồn: S3 Object Lock.

33. Một RDS MySQL đang chạy không mã hóa. Quy định mới bắt buộc mã hóa at rest. Cách nào khả thi?

  • A. Chạy modify-db-instance để bật mã hóa tại chỗ.
  • B. Tạo snapshot, copy snapshot với mã hóa KMS, restore DB instance mới từ bản copy đã mã hóa, rồi chuyển ứng dụng sang.
  • C. Tạo read replica có mã hóa rồi promote.
  • D. Bắt buộc kết nối TLS.
Đáp án

B — Đường đi được tài liệu RDS mô tả là qua snapshot: copy snapshot có mã hóa rồi restore thành DB mới.

Loại:

  • A: RDS không mã hóa trực tiếp một DB instance chưa mã hóa đang có.
  • C: Không thể tạo read replica mã hóa từ DB instance chưa mã hóa.
  • D: TLS mã hóa dữ liệu trên đường truyền, không phải at rest.

Nguồn: Encrypting RDS resources.

34. Website dùng CloudFront với domain riêng, origin là ALB ở ap-southeast-1. Certificate đang import thủ công, đã có lần quên gia hạn gây sự cố. Muốn certificate tự gia hạn. Chọn HAI.

  • A. Yêu cầu public certificate của ACM ở Region us-east-1 rồi gắn vào distribution.
  • B. Tiếp tục import certificate và bật managed renewal cho certificate imported.
  • C. Yêu cầu certificate ở ap-southeast-1 (Region của ALB origin) rồi gắn vào CloudFront.
  • D. Dùng DNS validation rồi xóa CNAME ngay sau khi certificate được cấp.
  • E. Dùng DNS validation và giữ nguyên các bản ghi CNAME validation trong DNS.
Đáp án

A, E — ACM tự gia hạn certificate do ACM cấp; với DNS validation, gia hạn tự động khi CNAME còn và certificate đang gắn vào dịch vụ. CloudFront yêu cầu certificate ở us-east-1.

Loại:

  • B: Certificate imported không đủ điều kiện managed renewal.
  • C: CloudFront chỉ dùng certificate ACM ở us-east-1.
  • D: Gia hạn tự động theo DNS cần CNAME còn nguyên và certificate đang được dùng.

Nguồn: ACM managed renewal, Renewal cho domain DNS-validated, CloudFront HTTPS requirements.

35. Một customer managed KMS key dùng cho SSE-KMS. Chính sách bảo mật yêu cầu xoay key material hằng năm mà không đổi code hay ARN key trong ứng dụng. Chọn gì?

  • A. Tạo key mới mỗi năm và sửa code sang key ID mới.
  • B. Lên lịch xóa key cũ ngay khi tạo key mới.
  • C. Không cần làm gì vì customer managed key luôn tự xoay.
  • D. Bật automatic key rotation trên key đó (chu kỳ mặc định 365 ngày).
Đáp án

D — Khi xoay, KMS giữ toàn bộ key material cũ để giải mã dữ liệu cũ; ID và ARN của key không đổi nên ứng dụng không phải sửa.

Loại:

  • A: Trái yêu cầu không đổi code và ARN.
  • B: Dữ liệu mã hóa bằng key cũ sẽ không giải mã được sau khi key bị xóa.
  • C: Với customer managed key, automatic rotation là tùy chọn, phải bật.

Nguồn: Rotate AWS KMS keys.

Domain 2 — Design Resilient Architectures (26%, câu 36–52)#

Task 2.1 — kiến trúc scalable và loosely coupled (câu 36–44)

36. Web cho upload ảnh; mỗi ảnh resize mất 20-40 giây và đang xử lý đồng bộ trong request. Giờ cao điểm request tăng gấp 10 lần, web bị timeout. Muốn web trả lời ngay và phần xử lý scale theo lượng việc tồn. Chọn gì?

  • A. Tăng idle timeout của ALB.
  • B. Chuyển sang một EC2 lớn hơn.
  • C. Giữ hàng đợi job trong bộ nhớ của web server.
  • D. Web ghi job vào Amazon SQS; worker trong Auto Scaling group scale theo số message tồn trên mỗi instance (backlog per instance).
Đáp án

D — Queue tách producer và consumer. Tài liệu Auto Scaling hướng dẫn tính backlog per instance (message tồn chia số instance) làm metric target tracking cho worker.

Loại:

  • A: Request vẫn chờ xử lý đồng bộ; chỉ kéo dài thời gian treo, không tăng năng lực.
  • B: Vẫn đồng bộ và thành điểm lỗi đơn; tải tăng 10 lần thì lại thiếu.
  • C: Job mất khi instance bị thay hoặc scale in; worker không scale độc lập được.

Nguồn: Scaling dựa trên SQS.

37. Hệ thống ví điện tử: lệnh của cùng một ví phải xử lý đúng thứ tự gửi, còn lệnh của các ví khác nhau cần xử lý song song để kịp tải. Chọn gì?

  • A. SQS Standard queue với nhiều consumer.
  • B. SQS FIFO với một MessageGroupId chung cho mọi message.
  • C. SQS FIFO queue với MessageGroupId là ID của ví.
  • D. Standard queue với delay 15 phút cho mỗi message.
Đáp án

C — FIFO giữ thứ tự trong từng message group; các group khác nhau được xử lý song song.

Loại:

  • A: Standard queue chỉ cố gắng giữ thứ tự (best-effort), không bảo đảm.
  • B: Đúng thứ tự nhưng mọi lệnh thành một hàng duy nhất, mất khả năng xử lý song song giữa các ví.
  • D: Delay chỉ hoãn thời điểm message hiện ra, không tạo thứ tự.

Nguồn: FIFO queue logic, Standard queues, Delay queues.

38. Quy trình duyệt hợp đồng: tạo hồ sơ, chờ người duyệt tối đa 7 ngày, rồi gửi kết quả. Cần xem lại lịch sử từng bước để audit. Chọn gì?

  • A. Step Functions Express workflow.
  • B. Một Lambda function (một lần invoke) ngồi chờ người duyệt.
  • C. AWS Step Functions Standard workflow.
  • D. SQS delay queue 7 ngày.
Đáp án

C — Standard workflow chạy tới một năm và lưu lịch sử thực thi, phù hợp quy trình dài có bước chờ con người.

Loại:

  • A: Express chạy tối đa 5 phút, không chờ được 7 ngày.
  • B: Một lần invoke Lambda tối đa 900 giây, không chờ được 7 ngày.
  • D: Delay tối đa của SQS là 15 phút.

Nguồn: Choosing workflow type, Lambda timeout, Delay queues.

39. Web app sau ALB trong Auto Scaling group lưu session trong RAM của instance; mỗi lần scale in, một phần user bị đăng xuất. Muốn instance stateless. Chọn HAI.

  • A. Tăng kích thước instance.
  • B. Lưu session trong Amazon ElastiCache.
  • C. Tắt hẳn scale in.
  • D. Lưu session trên instance store.
  • E. Lưu session trong bảng Amazon DynamoDB.
Đáp án

B, E — Đưa state ra kho dùng chung làm mọi instance thay thế được cho nhau; Well-Architected nêu ElastiCache và DynamoDB là nơi lưu session phổ biến.

Loại:

  • A: Session vẫn nằm trên từng instance, scale in vẫn mất.
  • C: Trả tiền cho capacity thừa và session vẫn mất khi instance bị thay vì lỗi.
  • D: Instance store gắn với host; mất khi instance dừng hoặc bị terminate.

Nguồn: REL05-BP06 Make systems stateless, Instance store lifetime.

40. API REST trên API Gateway bán cho đối tác theo gói; mỗi đối tác có giới hạn request mỗi giây và quota mỗi tháng riêng. Chọn gì?

  • A. Reserved concurrency cho Lambda backend.
  • B. Usage plans gắn với API key của từng đối tác.
  • C. Một ALB riêng cho mỗi đối tác.
  • D. IAM policy chặn đối tác sau 1.000 request.
Đáp án

B — Usage plan đặt throttling và quota theo API key. Tài liệu lưu ý throttling và quota là best-effort, không dùng làm cơ chế duy nhất để kiểm soát chi phí hay chặn truy cập.

Loại:

  • A: Giới hạn chung cho cả function, không phân biệt đối tác, không có quota tháng.
  • C: ALB không có khái niệm quota theo khách hàng; chi phí tăng theo số đối tác.
  • D: IAM không đếm số request.

Nguồn: API Gateway usage plans.

41. Team nhỏ chạy 6 microservice dạng container. Không muốn quản lý EC2, vá OS host hay tính capacity cho cluster. Chọn gì?

  • A. Amazon ECS trên AWS Fargate.
  • B. Amazon ECS với capacity là Auto Scaling group EC2 do team tự quản.
  • C. Tự cài Kubernetes trên EC2.
  • D. Một EC2 lớn chạy Docker Compose.
Đáp án

A — Fargate chạy container mà không cần quản lý server hay cluster EC2.

Loại:

  • B: Team vẫn phải quản lý, vá và scale instance của cluster.
  • C: Thêm cả việc vận hành control plane, trái mục tiêu giảm vận hành.
  • D: Vẫn phải vá OS, và một máy là điểm lỗi đơn.

Nguồn: AWS Fargate cho ECS.

42. Sự kiện OrderPlaced cần đi tới nhiều nơi: đơn có paymentMethod là COD tới Lambda kiểm tra rủi ro, mọi đơn tới SQS của kho. Producer không được sửa code mỗi khi thêm consumer. Chọn gì?

  • A. Amazon EventBridge event bus với rule theo event pattern, mỗi rule có target riêng.
  • B. Producer gọi trực tiếp từng consumer.
  • C. Một SQS queue chung cho mọi consumer.
  • D. Ghi đơn vào CloudWatch Logs để consumer tự đọc.
Đáp án

A — Rule của EventBridge lọc theo nội dung sự kiện và gửi tới một hoặc nhiều target; thêm consumer bằng rule mới.

Loại:

  • B: Coupling chặt; thêm consumer phải sửa producer.
  • C: Các consumer cạnh tranh message, mỗi đơn chỉ tới một consumer.
  • D: Log dành cho quan sát vận hành, không phải kênh định tuyến sự kiện nghiệp vụ.

Nguồn: EventBridge rules.

43. Aurora MySQL bị quá tải đọc vào giờ chạy báo cáo, lưu lượng ghi thấp, tải đọc lên xuống theo giờ trong ngày. Chọn gì?

  • A. Tăng instance writer lên class lớn nhất.
  • B. Chuyển toàn bộ sang DynamoDB.
  • C. Bật Aurora Auto Scaling cho Aurora Replicas và cho ứng dụng đọc qua reader endpoint.
  • D. Cấu hình ứng dụng trỏ cố định tới endpoint của từng replica.
Đáp án

C — Aurora Auto Scaling thêm hoặc bớt Aurora Replicas theo metric; reader endpoint phân phối kết nối đọc sang các replica.

Loại:

  • A: Trả cho capacity lớn cả lúc rảnh và mọi tải đọc vẫn dồn vào một instance.
  • B: Đổi mô hình dữ liệu và viết lại ứng dụng cho một vấn đề scale đọc.
  • D: Replica mới do auto scaling thêm vào sẽ không nhận traffic; reader endpoint mới phân phối được.

Nguồn: Aurora Auto Scaling.

44. Ứng dụng .NET chạy trên nhiều Windows Server cần thư mục dùng chung qua SMB, phân quyền theo user Active Directory. Chọn storage nào?

  • A. Amazon EFS.
  • B. Amazon FSx for Windows File Server.
  • C. EBS Multi-Attach.
  • D. Mount trực tiếp bucket S3 làm ổ đĩa.
Đáp án

B — FSx for Windows File Server cung cấp file share SMB tích hợp Active Directory.

Loại:

  • A: EFS dùng NFS và không hỗ trợ instance Windows.
  • C: Chỉ io1/io2, các instance phải cùng AZ, và là block device chứ không phải file share SMB.
  • D: S3 là object storage, không phải SMB share có phân quyền AD.

Nguồn: What is FSx for Windows File Server, What is Amazon EFS, EBS Multi-Attach.

Task 2.2 — kiến trúc highly available và fault-tolerant (câu 45–52)

45. Ứng dụng nội bộ cần phục hồi được khi mất cả Region chính, với RPO 1 giờ và RTO 24 giờ; ngân sách DR càng thấp càng tốt. Chọn chiến lược nào?

  • A. Active/active ở hai Region.
  • B. Warm standby ở Region DR.
  • C. RDS Multi-AZ trong Region chính.
  • D. Backup and restore: backup ít nhất mỗi giờ sang Region DR, dựng lại hạ tầng bằng IaC khi xảy ra sự cố.
Đáp án

D — Whitepaper DR mô tả backup and restore là lựa chọn chi phí thấp, hợp với RPO/RTO tính bằng giờ.

Loại:

  • A: Chi phí và độ phức tạp cao nhất, vượt xa RTO 24 giờ.
  • B: Luôn chạy một bản thu nhỏ, đắt hơn mức RTO 24 giờ cần.
  • C: Chỉ chống mất một AZ, không phục hồi khi mất cả Region.

Nguồn: DR options in the cloud.

46. Site chính chạy ở một Region; một trang thông báo tĩnh trên S3 ở Region khác làm dự phòng. Khi site chính không khỏe, DNS phải tự chuyển sang trang dự phòng. Chọn gì?

  • A. Weighted routing 50/50.
  • B. Simple routing với hai giá trị.
  • C. Latency routing.
  • D. Route 53 failover routing: record primary gắn health check, record secondary trỏ tới trang dự phòng.
Đáp án

D — Failover routing dùng cho active-passive: trả record primary khi khỏe, chuyển sang secondary khi health check lỗi.

Loại:

  • A: Một nửa người dùng tới trang dự phòng cả khi site chính khỏe.
  • B: Không có cơ chế chủ/dự phòng dựa trên health check.
  • C: Mục tiêu là chọn Region có độ trễ thấp nhất, không phải mô hình chủ/dự phòng.

Nguồn: Failover routing.

47. Lambda gọi RDS PostgreSQL. Khi traffic tăng đột biến, hàng nghìn execution environment mở kết nối mới làm DB cạn connection và lỗi. Chọn gì?

  • A. Đặt Amazon RDS Proxy giữa Lambda và DB.
  • B. Tăng max_connections hết mức.
  • C. Thêm read replica.
  • D. Tăng timeout của Lambda.
Đáp án

A — RDS Proxy gộp và chia sẻ kết nối, giúp DB chịu được đợt tăng kết nối đột ngột từ ứng dụng serverless.

Loại:

  • B: Mỗi kết nối tốn bộ nhớ DB; đẩy giới hạn chỉ dời điểm sập.
  • C: Không gộp kết nối, và các lệnh ghi vẫn vào primary.
  • D: Không giảm số kết nối mở cùng lúc.

Nguồn: Amazon RDS Proxy.

48. ALB và Auto Scaling group đã trải hai AZ, nhưng chỉ có một NAT gateway ở AZ-a và RDS Single-AZ ở AZ-a. Yêu cầu: hệ thống vẫn chạy khi mất AZ-a. Chọn HAI.

  • A. Tăng max size của Auto Scaling group.
  • B. Snapshot RDS mỗi giờ.
  • C. Mỗi AZ có NAT gateway riêng và route table private của AZ đó trỏ tới NAT cùng AZ (hoặc dùng Regional NAT gateway).
  • D. Chuyển RDS sang Multi-AZ.
  • E. Thêm NAT gateway thứ hai cũng ở AZ-a.
Đáp án

C, D — Tài liệu NAT gateway nêu NAT dùng chung tạo phụ thuộc AZ và khuyến nghị NAT theo từng AZ; Regional NAT gateway tự trải qua nhiều AZ. RDS Multi-AZ có standby ở AZ khác.

Loại:

  • A: Instance ở AZ-b vẫn ra Internet qua NAT ở AZ-a và đọc DB ở AZ-a.
  • B: Restore tạo DB mới và mất thời gian, không có failover tự động.
  • E: Vẫn cùng một AZ; mất AZ-a là mất cả hai.

Nguồn: NAT gateway basics, Regional NAT gateways, RDS Multi-AZ.

49. Bucket nguồn đã có 50 TB object. Yêu cầu mới: có bản sao ở Region khác cho cả object cũ lẫn object mới. Chọn gì?

  • A. Bật versioning ở cả hai bucket, cấu hình Cross-Region Replication cho object mới và chạy S3 Batch Replication cho object đã có.
  • B. Chỉ cấu hình Cross-Region Replication.
  • C. Chỉ bật versioning ở bucket nguồn.
  • D. Lifecycle chuyển object sang Glacier.
Đáp án

A — Live replication xử lý object mới; Batch Replication sao chép object có sẵn. Cả hai bucket phải bật versioning.

Loại:

  • B: Replication trực tiếp chỉ áp cho object mới sau khi bật; object có sẵn cần Batch Replication.
  • C: Replication yêu cầu versioning ở cả nguồn lẫn đích.
  • D: Lifecycle đổi storage class trong cùng bucket, không tạo bản sao ở Region khác.

Nguồn: S3 Batch Replication, Replication requirements.

50. Ứng dụng legacy chạy trên một EC2 dùng EBS, không sửa được code, cấu hình bên ngoài gắn với IP private của máy. Muốn máy tự phục hồi khi phần cứng host lỗi. Chọn gì?

  • A. Auto Scaling group min=max=1.
  • B. Dùng EC2 automatic recovery (simplified automatic recovery hoặc CloudWatch alarm với action recover).
  • C. Chuyển dữ liệu sang instance store cho nhanh.
  • D. Lên lịch reboot hằng tuần.
Đáp án

B — Recovery chuyển instance sang host khác mà giữ instance ID, IP private, IP public, Elastic IP và EBS volumes; dữ liệu trong RAM mất. Phù hợp ứng dụng không sửa được.

Loại:

  • A: ASG thay bằng instance mới với IP private mới, phá cấu hình gắn với IP.
  • C: Instance store không tồn tại qua lần recover hay dừng máy.
  • D: Không phát hiện hay xử lý lỗi host khi nó xảy ra.

Nguồn: EC2 instance recovery.

51. Request đi qua API Gateway, ba Lambda và DynamoDB. User báo chậm ngắt quãng nhưng không biết chặng nào gây chậm. Chọn gì để tìm điểm nghẽn?

  • A. Đọc CloudTrail.
  • B. Bật AWS X-Ray tracing và xem trace map cùng thời gian từng segment.
  • C. Bật VPC Flow Logs.
  • D. Tăng memory cho mọi Lambda.
Đáp án

B — X-Ray thu trace của request qua các dịch vụ và hiển thị trace map, giúp thấy chặng có độ trễ cao.

Loại:

  • A: CloudTrail ghi lịch sử lời gọi API để audit, không đo độ trễ từng chặng của một request.
  • C: Flow logs ghi metadata traffic IP, không có thời gian xử lý trong từng dịch vụ.
  • D: Đoán mò; chưa biết chậm ở đâu thì không biết sửa đúng chỗ.

Nguồn: What is AWS X-Ray.

52. Diễn tập warm standby: scale out ở Region DR lỗi vì vượt giới hạn vCPU của account, và AMI ứng dụng chỉ có ở Region chính. Chọn HAI.

  • A. Tăng service quotas ở Region chính.
  • B. Tăng service quotas ở Region DR đủ cho tải khi failover.
  • C. Chờ đến lúc sự cố thật mới xin tăng quota.
  • D. Copy AMI sang Region DR và dựng hạ tầng bằng IaC (ví dụ CloudFormation).
  • E. Dùng root user ở Region DR để vượt quota.
Đáp án

B, D — Whitepaper DR nhắc kiểm tra quota ở Region DR đủ cho tải failover và chuẩn bị AMI, IaC từ trước.

Loại:

  • A: Quota vCPU EC2 tính theo từng Region; tăng ở Region chính không đổi giới hạn ở Region DR.
  • C: Xin tăng quota cần thời gian, làm hỏng RTO.
  • E: Quota áp cho account, root không bỏ qua được.

Nguồn: DR options in the cloud, What is Service Quotas.

Domain 3 — Design High-Performing Architectures (24%, câu 53–68)#

Task 3.1 — storage hiệu năng cao và scale được (câu 53–54)

53. Cụm xử lý log trên EC2 đọc và ghi tuần tự các file lớn hàng trăm GB. Throughput quan trọng hơn IOPS, dữ liệu được đọc thường xuyên, volume không cần boot, chi phí càng thấp càng tốt. Chọn EBS volume type nào?

  • A. Throughput Optimized HDD (st1).
  • B. Provisioned IOPS SSD (io2).
  • C. Cold HDD (sc1).
  • D. Lưu file trong S3 Glacier Instant Retrieval và mount như ổ đĩa.
Đáp án

A — st1 được thiết kế cho tải tuần tự, truy cập thường xuyên, throughput lớn như ETL và xử lý log; nó không dùng làm volume boot.

Loại:

  • B: Tối ưu cho IOPS và độ trễ thấp, vượt yêu cầu khi tải chủ yếu là throughput tuần tự.
  • C: Dành cho dữ liệu ít được truy cập; đề nói đọc thường xuyên.
  • D: S3 là object storage, không gắn làm block volume cho EC2.

Nguồn: HDD volumes.

54. Ứng dụng ghi khoảng 20.000 PUT mỗi giây vào cùng một prefix uploads/ và bắt đầu nhận lỗi 503 Slow Down. Chọn hướng xử lý?

  • A. Phân tán key ra nhiều prefix (ví dụ theo hash hoặc ngày) và retry có backoff.
  • B. Bật S3 Transfer Acceleration.
  • C. Bật versioning.
  • D. Chuyển bucket sang Region khác.
Đáp án

A — S3 hỗ trợ ít nhất 3.500 PUT/COPY/POST/DELETE và 5.500 GET/HEAD mỗi giây cho mỗi prefix; dùng nhiều prefix để song song hóa, và S3 scale dần nên vẫn cần retry.

Loại:

  • B: Transfer Acceleration tăng tốc truyền đường xa qua edge, không tăng giới hạn request theo prefix.
  • C: Versioning không tăng throughput, còn tạo thêm phiên bản.
  • D: Giới hạn request tính theo prefix ở mọi Region; vấn đề vẫn còn.

Nguồn: S3 performance, Transfer Acceleration.

Task 3.2 — compute hiệu năng cao và đàn hồi (câu 55–57)

55. Lambda xử lý ảnh, phần lớn thời gian dùng CPU, chạy 8 giây với 512 MB memory. Muốn chạy nhanh hơn mà không sửa code. Chọn gì?

  • A. Tăng timeout.
  • B. Đặt reserved concurrency cao hơn.
  • C. Tăng memory của function; CPU được cấp tăng theo tỷ lệ memory.
  • D. Gắn Lambda vào VPC.
Đáp án

C — Lambda cấp CPU tỷ lệ với memory cấu hình; tải CPU-bound thường nhanh hơn khi tăng memory. Đo lại vì chi phí tính theo GB-giây.

Loại:

  • A: Chỉ cho phép chạy lâu hơn, không nhanh hơn.
  • B: Tăng số bản chạy song song, không tăng tốc từng lần chạy.
  • D: Thay đổi đường mạng, không thêm CPU.

Nguồn: Lambda memory.

56. Web stateless sau ALB: CPU luôn thấp nhưng độ trễ tăng mạnh khi số request trên mỗi instance vượt khoảng 1.000 mỗi phút. Traffic không theo lịch cố định. Chọn chính sách scaling?

  • A. Target tracking CPU 50%.
  • B. Target tracking với metric ALBRequestCountPerTarget.
  • C. Scheduled scaling theo giờ hành chính.
  • D. Đổi thủ công sang instance lớn hơn.
Đáp án

B — ALBRequestCountPerTarget là predefined metric của target tracking, khớp trực tiếp với điểm nghẽn đã đo.

Loại:

  • A: CPU không phản ánh điểm nghẽn ở đây, ASG sẽ không scale kịp.
  • C: Traffic không theo lịch.
  • D: Không tự động, và điểm nghẽn là số request mỗi instance.

Nguồn: Target tracking scaling.

57. Hàng nghìn job mô phỏng, mỗi job chạy 1-6 giờ, cần hàng đợi có ưu tiên và tự cấp compute theo số job. Team không muốn tự viết scheduler. Chọn gì?

  • A. AWS Lambda.
  • B. Một EC2 lớn chạy cron.
  • C. AWS Batch.
  • D. Step Functions Express workflow cho mỗi job.
Đáp án

C — AWS Batch nhận job đã submit và tự cấp compute theo nhu cầu của job, loại bỏ việc tự lo capacity.

Loại:

  • A: Timeout tối đa của Lambda thông thường là 900 giây, ngắn hơn job.
  • B: Không tự scale theo số job và là điểm lỗi đơn.
  • D: Express chạy tối đa 5 phút.

Nguồn: What is AWS Batch, Lambda timeout, Choosing workflow type.

Task 3.3 — database hiệu năng cao (câu 58–60)

58. Bảng DynamoDB đọc rất nhiều; cần độ trễ đọc cỡ micro giây, sửa code ít nhất, chấp nhận eventually consistent read. Chọn gì?

  • A. ElastiCache với logic cache tự viết.
  • B. Tăng read capacity của bảng.
  • C. Bật global tables.
  • D. Amazon DynamoDB Accelerator (DAX).
Đáp án

D — DAX là cache in-memory tương thích API DynamoDB, đọc cỡ micro giây; nó chỉ cache eventually consistent read; strongly consistent read được chuyển thẳng xuống DynamoDB.

Loại:

  • A: Được nhưng phải tự viết cache-aside, invalidation; trái yêu cầu sửa code ít nhất.
  • B: Giảm throttling chứ không đổi độ trễ cơ bản của mỗi lần đọc thành micro giây.
  • C: Global tables dành cho nhân bản nhiều Region, không phải cache.

Nguồn: DynamoDB Accelerator.

59. Bảng DynamoDB provisioned. Item 6 KB, cần 100 strongly consistent read mỗi giây. Cần bao nhiêu RCU?

  • A. 100 RCU.
  • B. 150 RCU.
  • C. 300 RCU.
  • D. 200 RCU.
Đáp án

D — Một RCU là một strongly consistent read mỗi giây cho item tới 4 KB; 6 KB làm tròn lên 8 KB nên cần 2 RCU mỗi lần đọc, 2 × 100 = 200.

Loại:

  • A: Tính mỗi item một RCU, quên rằng một RCU chỉ đọc 4 KB.
  • B: Chia 6/4 = 1,5 mà không làm tròn lên; kích thước item làm tròn lên bội số 4 KB.
  • C: Làm tròn quá mức; 6 KB làm tròn lên 8 KB, tức 2 RCU mỗi lần đọc.

Nguồn: Provisioned capacity mode.

60. Chuyển MySQL tự quản sang Amazon Aurora MySQL. Phát biểu nào về Aurora là đúng? Chọn HAI.

  • A. Phải cấp trước dung lượng storage tối đa khi tạo cluster.
  • B. Storage của cluster tự tăng theo dữ liệu và lưu bản sao trải ba AZ.
  • C. Aurora chỉ tương thích PostgreSQL.
  • D. Cluster hỗ trợ tới 15 Aurora Replicas dùng chung storage với writer.
  • E. Ứng dụng có thể ghi trực tiếp vào Aurora Replica.
Đáp án

B, D — Aurora tách compute và storage dùng chung; storage tự tăng, nhân bản qua ba AZ, và replicas đọc từ cùng volume nên độ trễ replica thấp.

Loại:

  • A: Storage của Aurora tự tăng, không phải cấp trước.
  • C: Aurora tương thích cả MySQL và PostgreSQL.
  • E: Các DB instance ngoài writer là read-only.

Nguồn: Aurora storage, Aurora replication, What is Aurora.

Task 3.4 — kiến trúc mạng hiệu năng cao (câu 61–62)

61. Game server dùng UDP chạy ở hai Region. Người chơi ở nhiều châu lục; đối tác cần IP tĩnh để whitelist; traffic phải tới endpoint khỏe gần nhất. Chọn gì?

  • A. Amazon CloudFront.
  • B. Route 53 latency routing.
  • C. AWS Global Accelerator với listener UDP và endpoint group ở hai Region.
  • D. Một NLB ở mỗi Region và cho người chơi tự chọn IP.
Đáp án

C — Global Accelerator cấp hai IPv4 anycast tĩnh, listener TCP hoặc UDP, và route tới endpoint khỏe gần người dùng.

Loại:

  • A: CloudFront dành cho nội dung web qua HTTP(S)/WebSocket, không làm front cho game UDP tùy biến.
  • B: Là DNS, không cung cấp bộ IP anycast tĩnh dùng chung cho cả hai Region.
  • D: Hai bộ IP khác nhau và không tự chuyển khi một Region lỗi.

Nguồn: What is Global Accelerator, Global Accelerator components.

62. Dịch vụ dùng giao thức TCP tùy biến (không phải HTTP) cần xử lý lượng kết nối rất lớn với độ trễ thấp, và đối tác cần một IP tĩnh ở mỗi AZ. Chọn gì?

  • A. Network Load Balancer với một Elastic IP cho mỗi subnet.
  • B. Application Load Balancer.
  • C. Amazon CloudFront.
  • D. Route 53 multivalue answer.
Đáp án

A — NLB hoạt động ở tầng 4, xử lý hàng triệu request mỗi giây, và cho phép gán một Elastic IP cho mỗi subnet.

Loại:

  • B: ALB hoạt động ở tầng 7 cho HTTP/HTTPS, không hợp giao thức TCP tùy biến.
  • C: CloudFront dành cho nội dung web qua HTTP(S)/WebSocket.
  • D: Chỉ trả nhiều IP qua DNS, không cân bằng kết nối hay cấp IP tĩnh cho load balancer.

Nguồn: What is a Network Load Balancer, What is an Application Load Balancer.

Task 3.5 — thu thập và biến đổi dữ liệu (câu 63–68)

63. Thiết bị IoT gửi liên tục khoảng 50.000 bản ghi mỗi giây. Ba ứng dụng độc lập cần đọc cùng dữ liệu, và khi phát hiện lỗi phải đọc lại được dữ liệu 3 ngày trước. Chọn gì?

  • A. SQS Standard queue.
  • B. Amazon Kinesis Data Streams với retention từ 72 giờ trở lên; dùng enhanced fan-out nếu mỗi consumer cần throughput riêng.
  • C. SQS FIFO queue.
  • D. Amazon Data Firehose ghi thẳng ra S3.
Đáp án

B — Kinesis Data Streams giữ bản ghi 24 giờ mặc định, tăng được tới 8.760 giờ; nhiều consumer đọc cùng stream, enhanced fan-out cấp throughput riêng cho mỗi consumer.

Loại:

  • A: Message bị xóa sau khi consumer xử lý và các consumer cạnh tranh nhau, không đọc lại được.
  • C: Cũng xóa message sau xử lý; không cho ba ứng dụng cùng đọc mọi bản ghi.
  • D: Firehose giao dữ liệu tới đích, không phải stream để nhiều consumer tự đọc lại theo vị trí.

Nguồn: Kinesis data retention, Enhanced fan-out consumers, What is Amazon Data Firehose.

64. Team có hàng trăm job Apache Spark và Hive đang chạy trên cụm Hadoop on-premises. Muốn chuyển lên AWS, sửa code ít nhất, xử lý vài trăm TB dữ liệu đặt trên S3. Chọn gì?

  • A. Viết lại mọi job thành Lambda function.
  • B. Một EC2 rất lớn cài Spark standalone.
  • C. Amazon Kinesis Data Streams.
  • D. Amazon EMR.
Đáp án

D — EMR là nền tảng cluster managed chạy Hadoop, Spark và các framework liên quan, đọc ghi dữ liệu trên S3.

Loại:

  • A: Trái yêu cầu sửa ít, và job lớn vượt timeout của Lambda.
  • B: Tự quản lý cluster, không scale theo job và là điểm lỗi đơn.
  • C: Dịch vụ thu thập dữ liệu streaming, không chạy job batch Spark/Hive.

Nguồn: What is Amazon EMR.

65. Data lake trên S3 đã có Glue Data Catalog và analysts đang truy vấn bằng Athena. Yêu cầu mới: (1) nhóm marketing không được thấy cột PII trong cùng bảng; (2) business users cần dashboard tương tác mà không viết SQL. Chọn HAI.

  • A. Dùng AWS Lake Formation cấp quyền theo cột cho từng nhóm.
  • B. Dùng Amazon Macie.
  • C. Dùng CloudWatch dashboards.
  • D. Dùng Amazon Quick Sight dựng dashboard trên dữ liệu đó.
  • E. Copy dữ liệu cho mỗi nhóm ra bucket riêng đã bỏ cột PII.
Đáp án

A, D — Lake Formation quản lý quyền chi tiết tới cột, hàng và ô trên data lake. Amazon Quick Sight (trước là QuickSight, nay là một tính năng của Amazon Quick) dựng dashboard tương tác.

Loại:

  • B: Macie phát hiện dữ liệu nhạy cảm, không cấp hay chặn quyền theo cột.
  • C: Hiển thị metric và log vận hành, không phải công cụ BI cho dữ liệu nghiệp vụ.
  • E: Nhân bản dữ liệu, khó đồng bộ và khó quản lý khi thêm nhóm.

Nguồn: What is Lake Formation, What is Amazon Quick.

66. Cần chuyển 200 TB từ NAS NFS on-premises lên S3 qua đường mạng 10 Gbps sẵn có, mã hóa khi truyền, kiểm tra toàn vẹn dữ liệu, và đồng bộ phần thay đổi trong 2 tuần trước cutover. Chọn gì?

  • A. Chạy aws s3 sync bằng cron trên một máy.
  • B. Đặt thêm một kết nối Direct Connect.
  • C. AWS DataSync với agent on-premises, chạy task theo lịch.
  • D. Amazon Kinesis Data Streams.
Đáp án

C — DataSync chuyển dữ liệu giữa on-premises (NFS, SMB...) và dịch vụ storage AWS, có mã hóa và kiểm tra toàn vẹn.

Loại:

  • A: Tự lo song song, retry, kiểm tra toàn vẹn và giám sát; một máy dễ thành nút cổ chai.
  • B: Đây là đường mạng, không phải công cụ chuyển dữ liệu; mạng hiện có đã đủ.
  • D: Dành cho bản ghi streaming, không phải sao chép file từ NAS.

Nguồn: What is DataSync.

67. Chi nhánh có ứng dụng cũ chỉ ghi file qua SMB vào share cục bộ. Muốn file nằm trên S3 để đưa vào data lake, và file đọc gần đây có độ trễ thấp nhờ cache tại chỗ. Chọn gì?

  • A. Amazon EFS.
  • B. Chạy DataSync một lần.
  • C. Amazon S3 File Gateway (AWS Storage Gateway).
  • D. FSx for Windows File Server trong Region.
Đáp án

C — S3 File Gateway cung cấp share NFS/SMB, lưu file thành object S3 và cache dữ liệu dùng gần đây tại chỗ.

Loại:

  • A: EFS dùng NFS và không hỗ trợ Windows client SMB; dữ liệu cũng không thành object S3.
  • B: Chuyển một lần, không cung cấp share SMB cho ứng dụng ghi liên tục.
  • D: Có SMB, nhưng file nằm trên FSx chứ không là object S3, và không có cache tại chi nhánh.

Nguồn: What is S3 File Gateway, What is Amazon EFS.

68. Mỗi ngày nhận hàng nghìn file CSV vào raw/ trên S3. Analysts truy vấn SQL chậm và tốn vì phải quét toàn bộ CSV. Muốn chuyển sang Parquet và truy vấn serverless trả theo dữ liệu quét. Chọn HAI.

  • A. Chạy Redshift provisioned cluster 24/7 để nạp CSV.
  • B. Bật S3 Transfer Acceleration.
  • C. Nạp CSV vào DynamoDB để analysts truy vấn.
  • D. Dùng Glue crawler cập nhật Data Catalog và Glue ETL job chuyển CSV sang Parquet có phân vùng.
  • E. Dùng Amazon Athena truy vấn bảng Parquet trong Data Catalog.
Đáp án

D, E — Glue crawler điền Data Catalog; Glue ETL (Spark serverless) đổi định dạng. Athena là SQL serverless trên S3, tính phí theo dữ liệu quét; định dạng cột như Parquet giảm dữ liệu cần đọc.

Loại:

  • A: Cluster provisioned không phải serverless và trả tiền cả lúc không truy vấn.
  • B: Tăng tốc upload đường xa, không giảm dữ liệu bị quét khi truy vấn.
  • C: DynamoDB là NoSQL key-value cho truy cập theo key, không phải công cụ truy vấn phân tích SQL trên data lake.

Nguồn: Glue crawlers, What is AWS Glue, What is Athena, Athena pricing.

Domain 4 — Design Cost-Optimized Architectures (20%, câu 69–81)#

Task 4.1 — storage tối ưu chi phí (câu 69–72)

69. Log ứng dụng: 30 ngày đầu đọc thường xuyên; từ ngày 30 đến 180 hiếm khi đọc nhưng khi cần phải có ngay; sau 180 ngày chỉ giữ cho audit, chấp nhận chờ vài giờ khi đọc; xóa sau 2 năm. Chọn lifecycle nào chi phí hợp lý nhất?

  • A. Chuyển sang Glacier Deep Archive ngay ngày 0.
  • B. S3 Standard, sang Standard-IA ở ngày 30, sang Glacier Flexible Retrieval ở ngày 180, expire ở ngày 730.
  • C. Giữ ở S3 Standard suốt 2 năm rồi expire.
  • D. S3 Intelligent-Tiering, không đặt expiration.
Đáp án

B — Lifecycle chuyển class theo tuổi object và xóa khi hết hạn. Standard-IA cho truy cập ngay nhưng hiếm; Glacier Flexible Retrieval restore Standard mất 3-5 giờ, hợp với "chờ vài giờ".

Loại:

  • A: 30 ngày đầu cần đọc thường xuyên; mỗi lần đọc phải restore.
  • C: Trả giá Standard cho dữ liệu hiếm khi đọc.
  • D: Không xóa sau 2 năm, trái yêu cầu.

Nguồn: Storage classes, Restore retrieval options.

70. Viện nghiên cứu chia sẻ bộ dữ liệu 500 TB trên S3 cho các tổ chức khác đều có account AWS. Muốn bên tải dữ liệu trả phí request và data transfer. Chọn gì?

  • A. Phục vụ qua CloudFront public.
  • B. Bật S3 Transfer Acceleration.
  • C. Chuyển dữ liệu sang Glacier Deep Archive.
  • D. Bật Requester Pays cho bucket.
Đáp án

D — Với Requester Pays, bên gửi request trả phí request và data transfer, chủ bucket trả phí lưu trữ.

Loại:

  • A: Chủ bucket vẫn trả phí CloudFront và request.
  • B: Tăng tốc truyền, thêm phí, không chuyển phí sang bên tải.
  • C: Giảm phí lưu trữ nhưng bên tải phải chờ restore và chủ bucket vẫn trả phí truy cập.

Nguồn: Requester Pays buckets.

71. Bucket 400 TB, object trung bình 5 MB, mẫu truy cập thay đổi và không đoán trước được. Không muốn trả phí retrieval khi bất ngờ đọc lại dữ liệu cũ. Chọn storage class nào?

  • A. S3 Standard-IA.
  • B. S3 One Zone-IA.
  • C. S3 Intelligent-Tiering.
  • D. S3 Glacier Flexible Retrieval.
Đáp án

C — Intelligent-Tiering tự chuyển object giữa các tier theo truy cập và không có phí retrieval; có phí monitoring mỗi object, và object dưới 128 KB không được giám sát. Object 5 MB nằm trong vùng phù hợp.

Loại:

  • A: Có phí retrieval theo GB khi đọc.
  • B: Có phí retrieval và chỉ lưu dữ liệu ở một AZ.
  • D: Phải restore mới đọc được và có phí retrieval.

Nguồn: Storage classes, How Intelligent-Tiering works.

72. Organization nhiều account. Tài nguyên đã gắn tag Project nhưng finance không thấy tag này khi group chi phí trong Cost Explorer. Cần làm gì?

  • A. Kích hoạt Project thành user-defined cost allocation tag trong Billing của management account, chờ dữ liệu cập nhật rồi group theo tag.
  • B. Gắn tag lại lên mọi tài nguyên.
  • C. Tạo một AWS Budget.
  • D. Bật CloudTrail.
Đáp án

A — Tag phải được kích hoạt làm cost allocation tag mới dùng được trong Cost Explorer; trong organization chỉ management account kích hoạt được.

Loại:

  • B: Tag đã có; thiếu bước kích hoạt tag cho billing.
  • C: Budget cảnh báo theo ngưỡng, không làm tag xuất hiện trong báo cáo chi phí.
  • D: CloudTrail ghi lời gọi API, không liên quan báo cáo chi phí theo tag.

Nguồn: Cost allocation tags.

Task 4.2 — compute tối ưu chi phí (câu 73–76)

73. Môi trường dev chạy ứng dụng mất 20 phút để nạp cache vào RAM khi khởi động. Muốn tắt máy ngoài giờ làm việc để tiết kiệm, rồi bật lại nhanh với RAM giữ nguyên. Chọn gì?

  • A. Bật hibernation cho instance và hibernate ngoài giờ.
  • B. Stop thông thường.
  • C. Terminate rồi tạo lại từ AMI mỗi sáng.
  • D. Mua Reserved Instance cho máy dev.
Đáp án

A — Hibernation lưu RAM vào EBS root volume. Khi hibernate không tính phí sử dụng instance, nhưng vẫn tính phí EBS.

Loại:

  • B: Nội dung RAM mất, khởi động lại vẫn mất 20 phút nạp cache.
  • C: Phải khởi động và nạp cache lại từ đầu.
  • D: Cam kết dùng liên tục; không phải tắt ngoài giờ.

Nguồn: EC2 hibernation.

74. Cache in-memory tự quản trên EC2 cần khoảng 512 GB RAM; CPU dùng thấp. Chọn họ instance nào?

  • A. Họ C (compute optimized).
  • B. Họ R (memory optimized).
  • C. Họ T (burstable).
  • D. Họ I (storage optimized).
Đáp án

B — Tên họ instance cho biết mục tiêu tối ưu: R là memory optimized.

Loại:

  • A: Tối ưu cho tính toán, trong khi tải này cần RAM lớn và dùng ít CPU.
  • C: Hiệu năng burstable nói về CPU, không nhắm tới RAM rất lớn.
  • D: Tối ưu cho storage cục bộ hiệu năng cao, không phải RAM.

Nguồn: Instance type naming.

75. API nội bộ nhận vài trăm request mỗi ngày, rải rác; mỗi request xử lý khoảng 200 ms. Hiện chạy trên hai EC2 bật 24/7. Hướng nào giảm chi phí compute rõ nhất?

  • A. Mua Reserved Instances cho hai EC2.
  • B. Đổi sang EC2 lớn hơn để xử lý nhanh hơn.
  • C. Chuyển sang API Gateway và Lambda.
  • D. Chạy hai task Fargate liên tục.
Đáp án

C — Lambda tính phí theo số request và thời gian chạy (GB-giây), nên tải rải rác chỉ trả cho phần thực sự chạy.

Loại:

  • A: Vẫn trả cho máy chạy 24/7 dù gần như không có tải.
  • B: Tăng chi phí cho tải vốn rất nhỏ.
  • D: Vẫn trả cho capacity chạy suốt ngày.

Nguồn: Lambda pricing.

76. Worker xử lý queue stateless, chịu được gián đoạn. Tải nền ổn định 4 instance, cao điểm tới 20 instance. Muốn tối ưu chi phí mà giảm rủi ro bị thu hồi hàng loạt. Chọn HAI.

  • A. Auto Scaling group mixed instances: phần nền On-Demand, phần trên Spot.
  • B. Chỉ dùng một instance type Spot ở một AZ.
  • C. Đa dạng nhiều instance type và nhiều AZ, dùng allocation strategy price-capacity-optimized.
  • D. Dùng Dedicated Hosts.
  • E. Reserved Instances cho cả 20 instance.
Đáp án

A, C — Mixed instances group trộn On-Demand và Spot với nhiều instance type. Spot hợp với tải stateless chịu lỗi; đa dạng type và AZ cùng price-capacity-optimized giảm rủi ro gián đoạn; Spot báo trước hai phút khi thu hồi.

Loại:

  • B: Phụ thuộc một Spot pool; pool đó cạn là mất hàng loạt.
  • D: Cho yêu cầu license hoặc tuân thủ, không phải tối ưu chi phí.
  • E: Trả cam kết cho capacity cao điểm mà phần lớn thời gian không dùng.

Nguồn: Mixed instances groups, Spot best practices.

Task 4.3 — database tối ưu chi phí (câu 77–78)

77. Ứng dụng mới, chưa biết lưu lượng; khi khuyến mãi có thể tăng 50 lần trong vài phút, còn lại rất thấp. Dữ liệu đã thiết kế cho DynamoDB. Chọn capacity mode nào?

  • A. Provisioned cố định ở mức cao điểm.
  • B. DynamoDB on-demand.
  • C. Provisioned cố định ở mức thấp.
  • D. Chuyển sang RDS instance lớn nhất.
Đáp án

B — On-demand tính phí theo request, tự scale theo tải, và là mode mặc định, được khuyến nghị cho phần lớn workload.

Loại:

  • A: Trả cho capacity cao điểm cả lúc rảnh.
  • C: Bị throttling khi tải tăng đột ngột.
  • D: Đổi mô hình dữ liệu và trả cho máy lớn 24/7.

Nguồn: On-demand capacity mode.

78. Chuyển Oracle on-premises sang Aurora PostgreSQL. Database có nhiều stored procedure; downtime khi cutover phải ngắn. Chọn gì?

  • A. DMS Schema Conversion để chuyển schema và code, rồi AWS DMS full load cộng CDC tới lúc cutover.
  • B. AWS DataSync.
  • C. Restore snapshot Oracle trực tiếp vào Aurora.
  • D. Export CSV một lần rồi import.
Đáp án

A — DMS Schema Conversion chuyển schema, view, stored procedure sang engine đích; DMS full load cộng change data capture giữ đích bắt kịp nguồn tới lúc cutover.

Loại:

  • B: DataSync chuyển file và object, không chuyển schema hay replicate thay đổi database.
  • C: Khác engine; snapshot không dùng chéo được.
  • D: Downtime dài và mất thay đổi xảy ra trong lúc chuyển.

Nguồn: DMS Schema Conversion, What is DataSync.

Task 4.4 — mạng tối ưu chi phí (câu 79–81)

79. Môi trường dev/test chạy ở hai AZ, chấp nhận gián đoạn khi một AZ lỗi. Instance private cần ra Internet tải package. Muốn giảm chi phí cố định. Chọn cấu hình nào?

  • A. Một NAT gateway mỗi AZ.
  • B. Một NAT gateway dùng chung; route table private của cả hai AZ trỏ về nó.
  • C. Gán public IPv4 cho mọi instance dev.
  • D. Bỏ NAT, dùng gateway endpoint cho mọi dịch vụ Internet.
Đáp án

B — Exam guide nêu đúng lựa chọn này: một NAT dùng chung so với NAT mỗi AZ. NAT dùng chung tạo phụ thuộc AZ, chấp nhận được khi môi trường chịu được gián đoạn. NAT tính phí theo giờ và theo GB xử lý; public IPv4 tính phí theo giờ.

Loại:

  • A: Tăng tính sẵn sàng mà dev/test không cần, và NAT tính phí theo từng giờ mỗi gateway.
  • C: Mỗi public IPv4 tính phí theo giờ và mở instance ra Internet.
  • D: Gateway endpoint chỉ có cho S3 và DynamoDB, không thay đường ra Internet.

Nguồn: Exam guide SAA-C03 Domain 4, NAT gateway basics, VPC pricing, Gateway endpoints.

80. 50 VPC trong nhiều account cần kết nối lẫn nhau và tới on-premises. Full-mesh VPC peering sẽ cần 1.225 kết nối. Chọn gì?

  • A. Nối VPC peering thành chuỗi.
  • B. Một Site-to-Site VPN cho mỗi cặp VPC.
  • C. Cho các VPC nói chuyện qua Internet công khai.
  • D. AWS Transit Gateway làm hub, các VPC và kết nối on-premises gắn vào.
Đáp án

D — Transit Gateway là hub trung chuyển nối VPC và mạng on-premises, thay mesh bằng mô hình hub-and-spoke.

Loại:

  • A: Peering không hỗ trợ transitive; VPC đầu chuỗi không tới được VPC cuối chuỗi.
  • B: Vẫn là full-mesh, còn thêm phí và vận hành VPN.
  • C: Lộ traffic nội bộ ra Internet và phải mở public endpoint.

Nguồn: What is Transit Gateway, VPC peering basics.

81. Công ty có Direct Connect 1 Gbps làm đường chính tới VPC. Cần đường dự phòng chi phí thấp khi Direct Connect lỗi, và dữ liệu nhạy cảm phải được mã hóa khi đi qua đường chính. Chọn HAI.

  • A. Coi như Direct Connect đã mã hóa sẵn.
  • B. Dùng VPC peering làm đường dự phòng.
  • C. Thêm Site-to-Site VPN qua Internet làm đường dự phòng.
  • D. Nâng Direct Connect lên 10 Gbps.
  • E. Mã hóa trên Direct Connect bằng MACsec (nếu connection hỗ trợ) hoặc chạy IPsec VPN trên Direct Connect.
Đáp án

C, E — Theo FAQ Direct Connect, khi có VPN dự phòng, traffic VPC tự chuyển sang VPN nếu Direct Connect lỗi. Direct Connect không mã hóa mặc định; có MACsec, hoặc chạy IPsec qua public VIF để kết hợp độ ổn định của Direct Connect với mã hóa đầu cuối.

Loại:

  • A: Direct Connect mặc định không mã hóa traffic.
  • B: Peering nối hai VPC, không nối mạng on-premises.
  • D: Thêm băng thông trên cùng một đường, không tạo đường dự phòng.

Nguồn: Direct Connect FAQs, Direct Connect encryption in transit, Direct Connect + Site-to-Site VPN.

14. Error notebook và chuẩn bị trước khi thi#

Sau mỗi câu sai, ghi: requirement đã bỏ sót, lý do đáp án đúng đáp ứng yêu cầu, vì sao từng distractor sai, link docs và một tình huống mà phương án sai lại có thể đúng. Ví dụ read replica không phải lựa chọn cho “standby tự failover” nhưng có thể đúng cho “offload reports chấp nhận lag”.

Đọc lại bốn domain và danh sách services/concepts chính thức; bổ sung mục chưa biết. Dùng official practice questions/exam trên Skill Builder theo khả năng truy cập. Bộ 16 câu ở mục 10–13 và ngân hàng 65 câu theo domain ngay trước mục này chỉ là tự kiểm tra kiến thức, không đủ mô phỏng độ khó, coverage hoặc xác suất đỗ.

Một chuẩn tự đánh giá do guide đề xuất: giải thích được từng quyết định không nhìn tài liệu, làm được các lab phù hợp ngân sách, và đạt kết quả ổn định trên bộ practice mới có review lỗi. Không đổi scaled passing score thành tỷ lệ cần đạt ở practice set.

Nguồn: Exam guide, AWS Skill Builder.

15. Done khi#

  • Có sơ đồ và decision record cho ít nhất hai kiến trúc cùng requirement.

    Đáp án

    Tự kiểm: có hai sơ đồ ASCII (ví dụ MVP và +AZ ở mục 8), mỗi sơ đồ một decision record theo mẫu ở mục 1 với dòng "Loại: vì sao" cho phương án bị bỏ. Sai thường gặp: hai sơ đồ nhưng khác requirement nên không so sánh được.

  • Có evidence IAM allow/deny và versioning, hoặc tabletop ghi rõ chưa thực hành.

    Đáp án

    Làm Lab A: cùng principal đọc raw/ thành công và other/ bị AccessDenied (implicit deny), hai version, delete marker. Nếu chưa làm, ghi "tabletop, chưa chạy" cùng dự đoán kết quả và lý do. Lưu ý 403 cũng xuất hiện cho key không tồn tại khi principal không có s3:ListBucket.

  • Giải thích replacement instance khác mô phỏng AZ outage.

    Đáp án

    Terminate một instance (Lab B) chứng minh ASG thay thế một máy hỏng và ALB loại target unhealthy. Nó không chứng minh chịu mất cả AZ: AZ outage làm hỏng nhiều thành phần cùng lúc (instance, NAT, DB nếu một AZ). Cách kiểm: liệt kê từng thành phần nằm ở AZ nào; điểm đơn nào còn thì chưa chịu được mất AZ.

    textReady
    mất instance: ASG thay 1 máy            mất AZ-a: app-a + NAT-a + DB(a?)[app-a x] [app-b ok]  -> replacement    [AZ-a toàn bộ x] [AZ-b ok] -> còn đủ?
  • Chứng minh queue retry và phân biệt với business idempotency.

    Đáp án

    Lab C: receive không delete làm message hiện lại, receive count tăng, vượt maxReceiveCount thì vào DLQ. Đó mới là retry. Business idempotency chứng minh ở bước nâng cao: hai lần giao, một hàng kết quả nhờ ràng buộc duy nhất theo jobId. SQS giao ít nhất một lần nên handler luôn phải idempotent.

  • Restore được dữ liệu lab và ghi thời gian; không suy ra RTO production.

    Đáp án

    Lab D: restore tạo DB mới, dữ liệu đúng thời điểm snapshot/PITR, ghi thời gian bắt đầu-kết thúc. Thời gian này không phải RTO production, vì RTO gồm cả dựng network/app, đổi endpoint, validate và DNS. Sai thường gặp: báo "RTO 12 phút" từ lab nhỏ.

  • Phân biệt OAC bảo vệ origin và signed URL bảo vệ viewer.

    Đáp án

    OAC làm CloudFront ký request tới S3 để chỉ CloudFront đọc được bucket (S3 URL trực tiếp trả 403); ai có URL CloudFront vẫn xem được. Signed URL/cookie (trusted key group) quyết định viewer nào được xem qua CloudFront. Cần nội dung private theo user thì cần cả hai lớp. Xem Lab E.

  • Có estimate đầy đủ hơn compute-only và alarm đã trigger/recover nếu làm lab.

    Đáp án

    Estimate có các dòng ALB/NAT/endpoints/log/transfer/backup và ghi "chưa tính"; hai phương án cùng giả định (Lab F). Alarm: có lịch sử chuyển OK -> ALARM -> OK; set-alarm-state chỉ chứng minh đường thông báo, cần cả lần gây lỗi thật. Nếu chưa làm lab, ghi rõ "tabletop".

  • Giải thích cả đáp án đúng lẫn phương án loại trong 16 câu tự luyện.

    Đáp án

    Tự kiểm: với mỗi câu, bạn nói được yêu cầu quyết định, vì sao đáp án đúng đáp ứng nó, và vì sao từng phương án còn lại sai (các dòng Loại ở mục 10-13 là đáp án mẫu). Câu sai thì ghi vào error notebook (mục 14) cùng một tình huống mà phương án sai lại đúng. Bộ 16 câu chỉ là tự kiểm tra, không mô phỏng độ khó đề thi. Làm tiếp ngân hàng 65 câu theo domain (câu 17–81) với cùng cách tự kiểm.

  • Dọn tài nguyên đã tạo, kiểm tra retained storage/snapshots/EIP/endpoints/logs.

    Đáp án

    Với mỗi lab dùng lệnh dọn trong block lời giải và lệnh kiểm "không còn gì": S3 versions và multipart uploads, RDS manual snapshots và automated backups, Elastic IP và NAT, endpoints, log groups, CloudFront distribution/OAC, SNS/CloudWatch alarms, KMS key (đang chờ xóa 7-30 ngày). Quét theo từng Region, rồi xem Billing sau độ trễ billing; không kết luận "zero cost" ngay.

  • Đối chiếu exam guide hiện tại trước khi chọn tài liệu luyện thi.

    Đáp án

    Mở trang chứng chỉ và exam guide online của AWS trước khi đặt lịch. Đối chiếu ngày 2026-10-05 với exam guide SAA-C03 và trang chứng chỉ: SAA-C03 là bản hiện hành, 65 câu (50 tính điểm và 15 không tính), 130 phút, thang 100-1000 và đạt 720 (chấm bù trừ), trọng số bốn domain 30/26/24/20 (Secure, Resilient, High-Performing, Cost-Optimized), không trừ điểm khi sai. Không có tiếng Việt: thi tiếng Anh và đăng ký ESL +30 (thêm 30 phút) một lần trước khi đăng ký thi. Trượt thì chờ 14 ngày để thi lại (chính sách sau khi thi); ESL +30 xem chính sách trước khi thi. Đừng dùng thông tin "SAA-C04" hay ngày retire từ site bên thứ ba: chưa có nguồn AWS.

  • Làm hết ngân hàng 65 câu theo domain, ghi câu sai và domain còn yếu vào error notebook.

    Đáp án

    Tự kiểm: làm từng khối task trước khi mở đáp án, chấm riêng theo bốn domain. Với mỗi câu sai, ghi requirement đã bỏ sót, đọc lại trang "Nguồn" của câu đó và viết một câu vì sao từng phương án bị loại. Domain có tỷ lệ sai cao hơn các domain khác là chỗ cần ôn lại từ GĐ29 đến GĐ32. Sai thường gặp: nhớ chữ cái đáp án thay vì nhớ điều kiện chọn; coi tỷ lệ đúng trên bộ này là xác suất đỗ.

Ghi chú chung: Kiểm chứng ngày 2026-10-05 theo tài liệu AWS (các URL nằm trong đáp án trên). Chưa chạy trên AWS thật. Số liệu về kỳ thi lấy từ exam guide và trang chính sách chứng chỉ của AWS; mở lại exam guide trước ngày thi.

Quay lại GĐ28 — bản đồ học SAA hoặc tiếp tục project GĐ25 — AI SaaS để dùng kiến thức AWS vào sản phẩm.