Ngân hàng đề — AWS Certified Developer Associate

Tìm thấy 1356 câu.

Câu 431 AWS Application Integration

To reduce the cost of API actions performed on an Amazon SQS queue, a Developer has decided to implement long polling. Which of the following modifications should the Developer make to the API actions?

  1. A

    Set the SetQueueAttributes with a MessageRetentionPeriod of 60

  2. B

    Set the ReceiveMessage API with a WaitTimeSeconds of 20

  3. C

    Set the SetQueueAttributes API with a DelaySeconds of 20

  4. D

    Set the ReceiveMessage API with a VisibilityTimeout of 30

Xem giải thích

Đáp án

B — Đặt API ReceiveMessage với WaitTimeSeconds bằng 20.

Vì sao đúng

Long polling chính là việc đặt WaitTimeSeconds > 0, và 20 giây là giá trị tối đa.

Khác biệt với short polling:

Short polling (WaitTimeSeconds=0) Long polling (WaitTimeSeconds=20)
Khi hàng đợi rỗng trả về NGAY, rỗng chờ tới 20 giây cho message xuất hiện
Số request rỗng rất nhiều ít hơn ~20 lần
Độ trễ nhận message phụ thuộc chu kỳ hỏi lại gần như tức thì khi có message
Phạm vi quét chỉ một tập con server toàn bộ server

Vì SQS tính tiền theo số request API, đây là cách giảm chi phí đơn giản nhất:

Consumer hỏi liên tục, hàng đợi rỗng:
  short polling → khoảng 3.600 request/giờ (mỗi giây một lần)
  long polling  → khoảng   180 request/giờ  ← giảm 95%

Và có một lợi ích thứ hai ít người để ý: long polling quét toàn bộ server của SQS, nên giảm hẳn trường hợp trả về rỗng dù hàng đợi có message — vấn đề cố hữu của short polling do SQS lưu trữ phân tán.

Hai cách bật:

# Mỗi lời gọi
aws sqs receive-message --queue-url <url> --wait-time-seconds 20

# Hoặc mặc định cho cả hàng đợi
aws sqs set-queue-attributes --queue-url <url> \
  --attributes ReceiveMessageWaitTimeSeconds=20

Vì sao các phương án khác sai

  • D. ReceiveMessage với VisibilityTimeout = 30 — đúng API nhưng sai tham số: VisibilityTimeout quyết định message bị ẩn bao lâu sau khi được nhận, để consumer khác không xử lý trùng. Không liên quan gì tới polling.
  • C. SetQueueAttributes với DelaySeconds = 20 — DelaySeconds hoãn message MỚI trước khi nó xuất hiện lần đầu (delay queue). Nó làm chậm việc xử lý, không giảm số request.
  • A. SetQueueAttributes với MessageRetentionPeriod = 60 — quyết định message được giữ bao lâu trước khi bị xoá (60 giây – 14 ngày). Đặt 60 giây thì message chưa kịp xử lý đã bị xoá mất — vừa không giảm chi phí, vừa gây mất dữ liệu.

Ghi nhớ

Bốn tham số thời gian của SQS, phân biệt cho rõ: | Tham số | Phạm vi | Tác dụng | |---|---|---| | WaitTimeSeconds | 0 – 20 giây | long polling | | VisibilityTimeout | 0 – 12 giờ | ẩn message đang xử lý | | DelaySeconds | 0 – 15 phút | hoãn message mới xuất hiện | | MessageRetentionPeriod | 60 giây – 14 ngày | giữ message bao lâu |

Cấu hình tối ưu cho consumer thông thường:

sqs.receive_message(
    QueueUrl=url,
    MaxNumberOfMessages=10,   # ← nhận theo lô, giảm 90% số request
    WaitTimeSeconds=20        # ← long polling, giảm request rỗng
)

Hai tham số này cùng nhau giảm chi phí API nhiều hơn hẳn so với dùng riêng lẻ.

Lưu ý: nếu dùng SQS làm event source cho Lambda, Lambda tự dùng long polling — bạn không phải cấu hình gì.

Câu 432 AWS Networking & Content Delivery

An organization is hosting a website on an Amazon EC2 instance in a public subnet. The website should allow public access for HTTPS traffic on TCP port 443 but should only accept SSH traffic on TCP port 22 from a corporate address range accessible over a VPN.

Which security group configuration will support both requirements?

  1. A

    Allow traffic to both port 443 and port 22 from 0.0.0.0/0 and 192.168.0.0/16.

  2. B

    Allow traffic to port 443 from 0.0.0.0/0 and allow traffic to port 22 from 192.168.0.0/16.

  3. C

    Allow traffic to both port 443 and port 22 from the VPC CIDR block.

  4. D

    Allow traffic to port 22 from 0.0.0.0/0 and allow traffic to port 443 from 192.168.0.0/16.

Xem giải thích

Đáp án

B — Cho phép port 443 từ 0.0.0.0/0, và port 22 chỉ từ 192.168.0.0/16.

Vì sao đúng

Đề nêu hai yêu cầu khác nhau cho hai cổng, và security group cho phép khai nguồn riêng cho từng rule — đó là toàn bộ câu trả lời:

Rule Cổng Nguồn Vì sao
HTTPS 443 0.0.0.0/0 website phải công khai cho mọi người
SSH 22 192.168.0.0/16 chỉ dải địa chỉ nội bộ công ty, qua VPN
aws ec2 authorize-security-group-ingress --group-id sg-xxx \
  --protocol tcp --port 443 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress --group-id sg-xxx \
  --protocol tcp --port 22 --cidr 192.168.0.0/16

Đây là nguyên tắc đặc quyền tối thiểu áp dụng ở tầng mạng: mở đúng thứ cần công khai, và giới hạn tối đa cửa quản trị.

Vì sao SSH mở ra Internet lại nguy hiểm đến vậy: cổng 22 mở với 0.0.0.0/0 sẽ bị quét và thử mật khẩu liên tục trong vòng vài phút kể từ khi instance có IP công khai. Đây là một trong những nguyên nhân xâm nhập phổ biến nhất trên đám mây.

Vì sao các phương án khác sai

  • D. Port 22 từ 0.0.0.0/0 và port 443 từ 192.168.0.0/16 — đảo ngược hoàn toàn: mở SSH cho cả thế giới (rất nguy hiểm) và giới hạn website chỉ cho nhân viên (website công khai thành không ai vào được). Sai cả về bảo mật lẫn chức năng.
  • A. Cho phép cả 443 và 22 từ 0.0.0.0/0 và 192.168.0.0/16 — mở SSH ra Internet. Việc thêm dải nội bộ vào không thu hẹp gì cả: security group rule là phép HỢP (union), không phải phép giao. Có 0.0.0.0/0 là mở cho tất cả.
  • C. Cả 443 và 22 từ VPC CIDR block — website sẽ không ai truy cập được từ Internet, vì chỉ tài nguyên trong VPC mới gọi được. Trái yêu cầu "allow public access for HTTPS".

Ghi nhớ

Đặc điểm của security group, đáng nhớ vì hay bị hỏi: | Đặc điểm | Chi tiết | |---|---| | Chỉ có rule ALLOW | không khai được Deny (khác NACL) | | Stateful | traffic vào được cho phép thì phản hồi ra tự động được phép | | Rule là phép hợp | nhiều rule chồng nhau ⇒ rộng nhất thắng | | Nguồn có thể là SG khác | rất hữu ích cho kiến trúc nhiều tầng | | Mặc định | chặn hết inbound, cho hết outbound |

So sánh nhanh với NACL: | | Security Group | NACL | |---|---|---| | Mức | instance/ENI | subnet | | Rule | chỉ Allow | Allow và Deny | | Trạng thái | stateful | stateless (phải mở cả hai chiều) | | Đánh giá | tất cả rule | theo số thứ tự, dừng ở rule khớp đầu tiên |

Và cách tốt hơn cả việc mở port 22: dùng AWS Systems Manager Session Manager — không cần mở cổng SSH nào cả, không cần khoá SSH, và mọi phiên đều được ghi vào CloudTrail.

Câu 433 AWS Database

A Developer is building a three-tier web application that must be able to handle a minimum of 10,000 requests per minute. The requirements state that the web tier should be completely stateless while the application maintains session state data for users.

How can the session state data be maintained externally, whilst keeping latency at the LOWEST possible value?

  1. A

    Implement a shared Amazon EFS file system solution across the underlying Amazon EC2 instances, then implement session handling at the application level to leverage the EFS file system for session data storage

  2. B

    Create an Amazon RedShift instance, then implement session handling at the application level to leverage a database inside the RedShift database instance for session data storage

  3. C

    Create an Amazon ElastiCache Redis cluster, then implement session handling at the application level to leverage the cluster for session data storage

  4. D

    Create an Amazon DynamoDB table, then implement session handling at the application level to leverage the table for session data storage

Xem giải thích

Đáp án

C — Tạo cụm Amazon ElastiCache Redis và lưu session ở đó.

Vì sao đúng

Điểm phân biệt của đề nằm ở hai chữ viết hoa: "keeping latency at the LOWEST possible value".

Khi yêu cầu là độ trễ thấp nhất, câu trả lời là kho trong bộ nhớ — và ElastiCache Redis là lựa chọn đó:

Kho Độ trễ điển hình
ElastiCache Redis dưới mili giây (~0,5 ms)
DynamoDB mili giây một chữ số (~5–10 ms)
EFS vài mili giây tới hàng chục
Redshift giây

Redis còn có các đặc điểm hợp với session:

r.setex(f'session:{sid}', 3600, json.dumps(du_lieu))   # TTL sẵn có
r.hset(f'session:{sid}', mapping=du_lieu)              # cấu trúc hash
  • TTL gốc — session tự hết hạn, không cần job dọn
  • Cấu trúc dữ liệu phong phú — hash hợp với dữ liệu session nhiều trường
  • Multi-AZ với tự động failover — chống mất session khi một node hỏng
  • Read replica — mở rộng đọc

Với 10.000 request/phút (≈167/giây), Redis xử lý thoải mái — nó chịu được hàng trăm nghìn thao tác mỗi giây.

Vì sao các phương án khác sai

  • D. DynamoDB — đây là phương án gần nhất và hoàn toàn hợp lệ về mặt kiến trúc: bền hơn, không phải quản lý cụm, có TTL. Nhưng độ trễ của nó là mili giây một chữ số, cao hơn Redis vài lần. Với đề nhấn mạnh "LOWEST possible", Redis thắng. (Nếu đề nhấn mạnh độ bền hoặc không muốn quản lý gì, DynamoDB mới là câu trả lời — hai câu hỏi rất giống nhau nhưng đáp án khác nhau chỉ vì một tính từ.)
  • A. EFS chia sẻ — hệ thống tệp qua NFS trên mạng, độ trễ cao hơn hẳn kho trong bộ nhớ. Ngoài ra đọc/ghi tệp cho mỗi request là mẫu rất kém hiệu quả, và khoá tệp khi nhiều instance ghi đồng thời sẽ thành nút thắt.
  • B. Amazon Redshift — sai bản chất dịch vụ nghiêm trọng nhất. Redshift là kho dữ liệu phân tích (OLAP), tối ưu cho quét hàng tỷ dòng trong các truy vấn phức tạp, không phải cho hàng nghìn thao tác đọc/ghi khoá–giá trị mỗi giây. Độ trễ tính bằng giây, và nó còn không chịu nổi mẫu truy cập kiểu này.

Ghi nhớ

Chọn kho session theo tính từ trong đề: | Đề nhấn mạnh | Chọn | |---|---| | "lowest latency", "fastest", "in-memory" | ElastiCache Redis | | "durable", "serverless", "no management", "TTL" | DynamoDB | | "shared file system", POSIX | EFS |

Và phân biệt hai engine của ElastiCache: | | Redis | Memcached | |---|---|---| | Cấu trúc dữ liệu | hash, list, set, sorted set | chỉ chuỗi | | Bền vững | có snapshot, AOF | ❌ | | Nhân bản, Multi-AZ failover | ✅ | ❌ | | Pub/Sub, transaction | ✅ | ❌ | | Đa luồng | ❌ (Redis 6+ có I/O đa luồng) | ✅ |

Cho session, gần như luôn chọn Redis — vì có nhân bản và failover, còn Memcached mất toàn bộ dữ liệu khi một node hỏng.

Câu 434 AWS Database

The Lambda function needs to write this data to an Amazon DynamoDB table. After deploying the function, the developer notices that the write operations to the DynamoDB table occasionally fail due to throttling.

What should the developer do to reduce the likelihood of these throttling issues without significantly over-provisioning the DynamoDB table's write capacity?

  1. A

    Convert the DynamoDB table to an on-demand capacity mode to automatically adjust its write capacity to match the workload.

  2. B

    Use Amazon SQS to queue data before writing it to the DynamoDB table, ensuring a steady and controlled write rate.

  3. C

    Implement exponential backoff in the Lambda function's error handling code to retry failed write operations.

  4. D

    Increase the Lambda function's timeout setting to allow for retries in case of throttling.

Xem giải thích

Đáp án

C — Cài đặt exponential backoff trong phần xử lý lỗi của hàm Lambda để thử lại các thao tác ghi thất bại.

Vì sao đúng

Ràng buộc của đề là chìa khoá: giảm throttle mà không cấp thừa write capacity đáng kể.

Throttle của DynamoDB (ProvisionedThroughputExceededException) thường là hiện tượng tạm thời — nó xảy ra ở các đỉnh ngắn, trong khi tải trung bình vẫn nằm trong khả năng của bảng. Cấp thêm WCU để phủ đỉnh nghĩa là trả tiền cho năng lực nằm không suốt phần còn lại của thời gian.

Exponential backoff xử lý đúng bản chất tạm thời đó: thử lại sau các khoảng chờ tăng dần, cho DynamoDB thời gian phân bổ lại năng lực:

import time, random
from botocore.exceptions import ClientError

def ghi_co_backoff(item, so_lan_toi_da=5):
    for lan in range(so_lan_toi_da):
        try:
            table.put_item(Item=item)
            return True
        except ClientError as e:
            if e.response['Error']['Code'] != 'ProvisionedThroughputExceededException':
                raise
            cho = (2 ** lan) * 0.1 + random.uniform(0, 0.1)   # jitter
            time.sleep(cho)      # 0,1s → 0,2s → 0,4s → 0,8s → 1,6s
    return False

Jitter (thành phần ngẫu nhiên) rất quan trọng: nếu nhiều hàm cùng thử lại đúng một thời điểm, chúng sẽ tạo ra đỉnh mới — hiện tượng gọi là thundering herd.

DynamoDB cũng có burst capacity: năng lực chưa dùng trong 300 giây trước được tích luỹ và dùng cho đỉnh ngắn — nên chờ một chút thường là đủ để thành công.

Vì sao các phương án khác sai

  • A. Chuyển sang on-demand capacity mode — đây là phương án hợp lý trong thực tế và cần nói rõ: on-demand thật sự loại bỏ throttle cho tải biến động, và với workload thưa thớt nó còn rẻ hơn. Nhưng nó đắt hơn khoảng 6–7 lần trên mỗi request so với provisioned khi tải đều — nên với vấn đề chỉ là đỉnh thỉnh thoảng, nó là cách chữa tốn kém. Đề hỏi cách giảm throttle mà không đổi năng lực nhiều, tức là hướng về xử lý ở phía ứng dụng.
  • B. Dùng SQS làm đệm trước khi ghi — hiệu quả về mặt kiến trúc (san phẳng đỉnh là mẫu chuẩn), nhưng thêm hẳn một dịch vụ, một consumer, và độ trễ. Quá nặng cho vấn đề mà backoff giải quyết được.
  • D. Tăng timeout của Lambda "để có chỗ thử lại" — timeout chỉ cho phép hàm chạy lâu hơn; nó không tự thử lại gì cả. Không có mã retry thì tăng timeout chẳng thay đổi điều gì.

Ghi nhớ

Cách chống throttle Đặc điểm
Exponential backoff + jitter rẻ nhất, xử lý đỉnh tạm thời
Auto scaling cho provisioned tự tăng WCU, nhưng phản ứng chậm (vài phút)
On-demand mode không bao giờ throttle, đắt hơn khi tải đều
SQS làm đệm san phẳng đỉnh, thêm độ trễ
Sửa partition key nếu nguyên nhân là hot partition

Một ghi chú thực dụng: AWS SDK đã có sẵn exponential backoff cho các lỗi có thể thử lại (mặc định max_attempts=3 với standard retry mode). Nên "implement exponential backoff" trong thực tế thường nghĩa là tăng số lần thử và điều chỉnh tham số:

from botocore.config import Config
cfg = Config(retries={'max_attempts': 10, 'mode': 'adaptive'})

Chế độ adaptive còn tự điều tiết tốc độ gửi theo tín hiệu throttle nhận được — đáng dùng cho đúng tình huống này.

Và luôn kiểm tra nguyên nhân gốc trước: nếu throttle tập trung vào một partition key, thì không lượng WCU nào cứu được — phải thiết kế lại khoá.

Câu 435 AWS Application Integration

An application needs to generate SMS text messages and emails for a large number of subscribers. Which AWS service can be used to send these messages to customers?

  1. A

    Amazon SNS

  2. B

    Amazon SQS

  3. C

    Amazon SWF

  4. D

    Amazon SES

Xem giải thích

Đáp án

A — Amazon SNS.

Vì sao đúng

Điểm mấu chốt: đề cần gửi CẢ SMS LẪN EMAIL, và SNS là dịch vụ duy nhất làm được cả hai.

SNS là dịch vụ pub/sub hỗ trợ nhiều loại đích đăng ký: | Giao thức | Đích | |---|---| | sms | tin nhắn văn bản | | email / email-json | email | | lambda | hàm Lambda | | sqs | hàng đợi | | http/https | webhook | | application | push cho thiết bị di động |

Mô hình rất hợp với "a large number of subscribers":

                       ┌→ người đăng ký SMS
Ứng dụng → SNS topic ──┼→ người đăng ký email
                       └→ hàng đợi SQS…

Ứng dụng publish một lần, SNS fan-out tới mọi người đăng ký — không cần vòng lặp gửi từng người.

sns.publish(TopicArn=topic, Message='Đơn hàng đã được xác nhận',
            Subject='Thông báo đơn hàng')

Vì sao các phương án khác sai

  • D. Amazon SES — đây là phương án gần nhất và cần phân biệt rõ: SES chuyên về email và làm việc đó tốt hơn SNS rất nhiều (template, theo dõi bounce/complaint, email marketing, HTML phong phú). Nhưng SES không gửi SMS — nên nó chỉ đáp ứng một nửa yêu cầu.
  • B. Amazon SQS — hàng đợi tin nhắn giữa các thành phần phần mềm. Nó không gửi gì tới người dùng cuối; consumer phải chủ động lấy message ra.
  • C. Amazon SWF — Simple Workflow Service, dùng để điều phối các bước trong quy trình nghiệp vụ. Không phải dịch vụ thông báo. (Và AWS khuyến nghị dùng Step Functions cho workflow mới.)

Ghi nhớ

Dịch vụ Việc SMS Email
SNS pub/sub, thông báo ✅ ✅ (đơn giản)
SES email chuyên dụng ❌ ✅ (đầy đủ)
SQS hàng đợi giữa các thành phần ❌ ❌
Pinpoint chiến dịch marketing đa kênh ✅ ✅

Cách chọn nhanh:

  • Cần cả SMS và email ⇒ SNS
  • Chỉ email, cần template và theo dõi bounce ⇒ SES
  • Chiến dịch marketing, phân khúc người dùng, phân tích ⇒ Pinpoint

(Lưu ý thực tế: gửi SMS bằng SNS ra ngoài sandbox cần xin tăng hạn mức chi tiêu, và ở nhiều quốc gia — kể cả Việt Nam — còn phải đăng ký sender ID với nhà mạng.)

Câu 436 AWS Management & Governance

A Developer is writing code to run in a cron job on an Amazon EC2 instance that sends status information about the application to Amazon CloudWatch.

Which method should the Developer use?

  1. A

    Use the AWS CLI put-metric-alarm command.

  2. B

    Use the unified CloudWatch agent to publish custom metrics.

  3. C

    Use the AWS CLI put-metric-data command.

  4. D

    Use the CloudWatch console with detailed monitoring.

Xem giải thích

Đáp án

C — Dùng lệnh AWS CLI put-metric-data.

Vì sao đúng

Đề mô tả: mã chạy trong cron job, gửi thông tin trạng thái của ứng dụng lên CloudWatch. Đó chính là định nghĩa của custom metric, và put-metric-data là API để đăng nó:

aws cloudwatch put-metric-data \
  --namespace "UngDungCuaToi" \
  --metric-name "SoDonChoXuLy" \
  --value 42 \
  --unit Count \
  --dimensions InstanceId=i-1234567890abcdef0,MoiTruong=production

Gửi nhiều metric trong một lời gọi để tiết kiệm request:

aws cloudwatch put-metric-data --namespace "UngDungCuaToi" \
  --metric-data \
    MetricName=SoDonChoXuLy,Value=42,Unit=Count \
    MetricName=DoTreXuLy,Value=1.23,Unit=Seconds

Quyền IAM cần cho instance role:

{"Effect": "Allow", "Action": "cloudwatch:PutMetricData", "Resource": "*"}

(PutMetricData không hỗ trợ giới hạn theo resource — phải để "*", nhưng có thể giới hạn bằng điều kiện cloudwatch:namespace.)

Vì sao các phương án khác sai

  • A. put-metric-alarm — đây là bẫy chính, và hai lệnh chỉ khác nhau một từ. put-metric-alarm TẠO CẢNH BÁO trên một metric đã tồn tại; nó không gửi dữ liệu nào. Không có dữ liệu thì cảnh báo ở trạng thái INSUFFICIENT_DATA mãi mãi.
  • B. Dùng unified CloudWatch agent — agent là công cụ rất tốt cho việc thu thập metric hệ thống (RAM, ổ đĩa) và log, và nó có đọc được custom metric qua giao thức StatsD/collectd. Nhưng đề nói rõ là "writing code to run in a cron job" — tức là mã tự sinh ra số liệu và tự gửi. Cài thêm agent cho việc đó là thừa.
  • D. Dùng Console với detailed monitoring — detailed monitoring chỉ đổi chu kỳ metric của EC2 từ 5 phút xuống 1 phút. Nó không tạo ra custom metric nào từ ứng dụng, và Console không phải nơi để cron job gửi dữ liệu.

Ghi nhớ

Lệnh Việc
put-metric-data GỬI dữ liệu metric lên
put-metric-alarm TẠO cảnh báo trên metric có sẵn
get-metric-statistics đọc dữ liệu ra
get-metric-data đọc nhiều metric, hỗ trợ biểu thức

Vài đặc điểm của custom metric: | Đặc điểm | Chi tiết | |---|---| | Chu kỳ chuẩn | 60 giây | | High resolution | --storage-resolution 1 — tới 1 giây, tính phí cao hơn | | Dimension | tối đa 30 mỗi metric; mỗi tổ hợp là một metric riêng (và một khoản phí riêng) | | Dữ liệu quá khứ | gửi được tới 2 tuần trước hoặc 2 giờ sau |

Mẹo giảm chi phí và số lời gọi: dùng statistic set thay vì gửi từng điểm:

--metric-data MetricName=DoTre,StatisticValues={Sum=500,Minimum=1,Maximum=50,SampleCount=100}
Câu 437 AWS Security, Identity, & Compliance

A developer is writing an application for a company. The program needs to access and read the file named "secret-data.xlsx" located in the root directory of an Amazon S3 bucket named "DATA-BUCKET". The company's security policies mandate the enforcement of the principle of least privilege for the IAM policy associated with the application.

Which IAM policy statement will comply with these security stipulations?

  1. A

    {"Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DATA-BUCKET/*"}

  2. B

    {"Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::DATA-BUCKET"}

  3. C

    {"Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DATA-BUCKET/secret-data.xlsx"}

  4. D

    {"Effect": "Allow", "Action": "s3:*", "Resource": "arn:aws:s3:::DATA-BUCKET/*"}

Xem giải thích

Đáp án

C — {"Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DATA-BUCKET/secret-data.xlsx"}

Vì sao đúng

Nguyên tắc đặc quyền tối thiểu đòi hỏi thu hẹp trên cả hai trục, và chỉ phương án C làm cả hai:

Trục Yêu cầu Phương án C
Action chỉ cần đọc s3:GetObject — đúng một action
Resource chỉ cần một tệp ARN trỏ đúng tệp đó
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::DATA-BUCKET/secret-data.xlsx"
  }]
}

Chú ý định dạng ARN của S3 — đây là chỗ hay sai:

arn:aws:s3:::DATA-BUCKET               ← chính BUCKET (cho ListBucket)
arn:aws:s3:::DATA-BUCKET/*             ← MỌI object trong bucket
arn:aws:s3:::DATA-BUCKET/secret-data.xlsx  ← ĐÚNG MỘT object

S3 ARN không có phần region và account (ba dấu hai chấm liền nhau) vì tên bucket vốn là duy nhất toàn cầu.

Vì sao các phương án khác sai

  • A. s3:GetObject trên DATA-BUCKET/* — đúng action nhưng quá rộng về resource: cho phép đọc mọi object trong bucket, kể cả những tệp ứng dụng không cần biết tới. Vi phạm đặc quyền tối thiểu ở trục thứ hai.
  • D. s3:* trên DATA-BUCKET/* — rộng nhất và nguy hiểm nhất: s3:* bao gồm cả s3:DeleteObject và s3:PutObject. Một ứng dụng chỉ cần đọc lại có quyền xoá sạch dữ liệu.
  • B. s3:ListBucket trên DATA-BUCKET — sai action: ListBucket cho phép liệt kê danh sách tệp, nhưng không cho đọc nội dung tệp nào. Ứng dụng sẽ thấy tên tệp rồi nhận AccessDenied khi cố mở.

Ghi nhớ

Phân biệt hai nhóm action của S3 — nhầm chỗ này là lỗi phổ biến nhất khi viết policy cho S3: | Nhóm | Action | Resource ARN | |---|---|---| | Mức bucket | ListBucket, GetBucketLocation, ListBucketVersions | arn:aws:s3:::bucket (không có /*) | | Mức object | GetObject, PutObject, DeleteObject | arn:aws:s3:::bucket/* |

Policy cho ứng dụng vừa cần liệt kê vừa cần đọc phải có hai statement:

[
  {"Effect":"Allow","Action":"s3:ListBucket","Resource":"arn:aws:s3:::DATA-BUCKET",
   "Condition":{"StringLike":{"s3:prefix":"bao-cao/*"}}},
  {"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::DATA-BUCKET/bao-cao/*"}
]

Mẹo kiểm tra khi làm bài: nếu resource có /* thì đó là quyền trên object; nếu không có thì là quyền trên bucket. Nhìn cặp action–resource có khớp nhóm không là loại được ngay các phương án sai.

Câu 438 AWS Application Integration

An application asynchronously invokes an AWS Lambda function. The application has recently been experiencing occasional errors that result in failed invocations. A developer wants to store the messages that resulted in failed invocations such that the application can automatically retry processing them.

What should the developer do to accomplish this goal with the LEAST operational overhead?

  1. A

    Configure an Amazon S3 bucket as a destination for failed invocations. Configure event notifications to trigger the Lambda function to process the events.

  2. B

    Configure logging to an Amazon CloudWatch Logs group. Configure Lambda to read failed invocation events from the log group.

  3. C

    Configure Amazon EventBridge to send the messages to Amazon SNS to initiate the Lambda function again.

  4. D

    Configure a redrive policy on an Amazon SQS queue. Set the dead-letter queue as an event source to the Lambda function.

Xem giải thích

Đáp án

D — Cấu hình redrive policy trên hàng đợi SQS, và đặt dead-letter queue làm event source cho hàm Lambda.

Vì sao đúng

Yêu cầu có hai vế: lưu lại message của các lần gọi thất bại, và tự động xử lý lại — với ít công sức vận hành nhất.

Redrive policy là cấu hình trên hàng đợi chính, quy định message bị chuyển sang dead-letter queue sau bao nhiêu lần xử lý hỏng:

{
  "deadLetterTargetArn": "arn:aws:sqs:ap-southeast-1:123456789012:hang-doi-loi",
  "maxReceiveCount": 3
}

Đọc thế này: message nào bị nhận và xử lý hỏng 3 lần thì tự động chuyển sang DLQ — không mất đi.

Rồi đặt DLQ làm event source cho Lambda, nghĩa là hàm tự động lấy message từ DLQ ra xử lý lại:

Message hỏng → DLQ → Lambda tự đọc (event source mapping) → xử lý lại

Vì sao đây là "least operational overhead": cả hai bước đều là cấu hình, không có mã tự viết, không có dịch vụ trung gian nào phải vận hành. AWS lo việc thử lại, đếm số lần, và chuyển hàng đợi.

Vì sao các phương án khác sai

  • A. S3 làm destination cho lần gọi thất bại, rồi dùng S3 event notification kích hoạt lại Lambda — chạy được (Lambda destination có hỗ trợ S3 gián tiếp qua EventBridge), nhưng đây là đường vòng: message thành tệp trên S3, mất hẳn ngữ cảnh hàng đợi, mất cơ chế đếm số lần thử, và bạn phải tự lo việc tránh vòng lặp vô hạn nếu xử lý lại vẫn hỏng.
  • B. Ghi vào CloudWatch Logs rồi cho Lambda đọc từ log group — log không phải hàng đợi. Không có cơ chế "đã xử lý xong thì xoá", không có visibility timeout, không chống trùng lặp. Xây một hệ thống retry trên log là rất nhiều công sức và rất dễ sai.
  • C. EventBridge gửi message sang SNS để gọi lại Lambda — SNS fan-out, không lưu trữ: nếu lần gọi lại cũng hỏng thì message mất luôn. Trái yêu cầu "store the messages".

Ghi nhớ

Hai loại DLQ trong hệ sinh thái Lambda — hay bị lẫn: | | SQS redrive policy | Lambda DLQ / destination | |---|---|---| | Đặt ở | hàng đợi SQS | cấu hình hàm Lambda | | Kích hoạt khi | message hỏng maxReceiveCount lần | lần gọi bất đồng bộ hỏng hết số lần thử | | Đích | hàng đợi khác | SQS, SNS, Lambda, EventBridge |

Với gọi bất đồng bộ, Lambda tự thử lại 2 lần (tổng 3 lần) trước khi đưa vào destination. On-failure destination là bản hiện đại và mạnh hơn DLQ cũ vì nó gửi kèm cả ngữ cảnh lỗi:

aws lambda put-function-event-invoke-config --function-name xu-ly \
  --maximum-retry-attempts 2 \
  --destination-config '{"OnFailure":{"Destination":"arn:aws:sqs:...:hang-doi-loi"}}'

Và một cảnh báo thực tế: đặt DLQ làm event source cho chính hàm đã gây lỗi có thể tạo vòng lặp vô tận nếu nguyên nhân lỗi là dữ liệu hỏng (poison message). Nên DLQ thường nên trỏ tới một hàm xử lý riêng, hoặc ít nhất có logic phát hiện message đã thử quá nhiều lần.

Câu 439 AWS Compute

A business operates a web app on Amazon EC2 instances utilizing a bespoke Amazon Machine Image (AMI). They employ AWS CloudFormation for deploying their app, which is currently active in the us-east-1 Region. However, their goal is to extend the deployment to the us-west-1 Region.

During an initial attempt to create an AWS CloudFormation stack in us-west-1, the action fails, and an error message indicates that the AMI ID does not exist. A developer is tasked with addressing this error through a method that minimizes operational complexity.

Which action should the developer take?

  1. A

    Use AWS Lambda to create an AMI in the us-west-1 Region during stack creation.

  2. B

    Modify the CloudFormation template to refer to the AMI in us-east-1 Region.

  3. C

    Create a new AMI in the us-west-1 Region and update the CloudFormation template with the new AMI ID.

  4. D

    Copy the AMI from the us-east-1 Region to the us-west-1 Region and use the new AMI ID in the CloudFormation template.

Xem giải thích

Đáp án

D — Sao chép AMI từ us-east-1 sang us-west-1 và dùng AMI ID mới trong template CloudFormation.

Vì sao đúng

Nguyên nhân lỗi nằm ở một tính chất cơ bản của AMI:

AMI ID là tài nguyên theo Region. Cùng một AMI được sao chép sang Region khác sẽ có ID hoàn toàn khác:

us-east-1: ami-0abc123def456
us-west-1: ami-0987fed654321   ← cùng nội dung, ID khác

Nên template ghi cứng ID của us-east-1 sẽ báo "AMI ID does not exist" khi chạy ở Region khác — đúng thông báo trong đề.

copy-image là cách ít công sức nhất: một lệnh, AWS lo phần còn lại:

aws ec2 copy-image \
  --source-region us-east-1 \
  --source-image-id ami-0abc123def456 \
  --region us-west-1 \
  --name "ung-dung-web-v1" \
  --description "Bản sao từ us-east-1"

Nó sao chép cả snapshot của các EBS volume đi kèm, và AMI mới hoàn toàn độc lập với bản gốc.

Để template dùng được ở nhiều Region mà không phải sửa tay mỗi lần, dùng mapping:

Mappings:
  AmiTheoRegion:
    us-east-1: {AMI: ami-0abc123def456}
    us-west-1: {AMI: ami-0987fed654321}
Resources:
  MayChu:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [AmiTheoRegion, !Ref "AWS::Region", AMI]

Vì sao các phương án khác sai

  • C. Tạo AMI MỚI ở us-west-1 — cho ra kết quả dùng được, nhưng nhiều công sức hơn hẳn: phải dựng lại instance, cài lại phần mềm, cấu hình lại, rồi mới tạo AMI. Và rủi ro AMI hai Region không giống nhau — chính vấn đề mà copy-image tránh được.
  • B. Sửa template để trỏ tới AMI ở us-east-1 — không làm được: EC2 chỉ khởi chạy được từ AMI trong cùng Region. Không có cú pháp nào để tham chiếu AMI xuyên Region.
  • A. Dùng Lambda tạo AMI trong lúc tạo stack — về lý thuyết làm được bằng custom resource, nhưng đây là cách phức tạp nhất trong bốn phương án: phải viết hàm Lambda, xử lý tín hiệu thành công/thất bại về CloudFormation, xử lý cả trường hợp rollback. Trái hẳn yêu cầu "minimizes operational complexity".

Ghi nhớ

Các tài nguyên theo Region — không dùng chung được: | Tài nguyên | Phạm vi | |---|---| | AMI, EBS snapshot | Region (sao chép được) | | Security group, VPC, subnet | Region (không sao chép được, phải tạo lại) | | Key pair | Region | | IAM user, role, policy | toàn cầu | | Route 53, CloudFront, WAF (CloudFront scope) | toàn cầu | | S3 bucket | tên toàn cầu, dữ liệu ở một Region |

Cách tốt nhất để tránh hẳn vấn đề AMI ID: dùng SSM Parameter Store public parameter, vốn tự phân giải theo Region:

Parameters:
  AmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64

Cách này luôn lấy AMI mới nhất, đúng Region, không cần mapping và không cần sửa template. Với AMI tuỳ chỉnh, bạn tự tạo parameter tương ứng ở mỗi Region rồi tham chiếu theo cùng một tên.

Câu 440 AWS Database

A Developer is creating a serverless application that uses an Amazon DynamoDB table. The application must make idempotent, all-or-nothing operations for multiple groups of write actions.

Which solution will meet these requirements?

  1. A

    Enable DynamoDB streams and capture new images. Update the items in the table using the BatchWriteltem.

  2. B

    Create an Amazon SQS FIFO queue and use the SendMessageBatch operation to group the changes.

  3. C

    Update the items in the table using the TransactWriteltems operation to group the changes.

  4. D

    Update the items in the table using the BatchWriteltem operation and configure idempotency at the table level.

Xem giải thích

Đáp án

C — Cập nhật item bằng thao tác TransactWriteItems để gom các thay đổi lại.

Vì sao đúng

Đề dùng hai thuật ngữ, và cả hai đều trỏ thẳng tới giao dịch:

  • "all-or-nothing" — hoặc mọi thao tác thành công, hoặc không thao tác nào được áp dụng
  • "idempotent" — gọi lại nhiều lần cho cùng kết quả

TransactWriteItems là API giao dịch của DynamoDB, cung cấp tính nguyên tử ACID cho tối đa 100 item trên nhiều bảng:

dynamodb.transact_write_items(
    TransactItems=[
        {'Update': {'TableName': 'TaiKhoan',
                    'Key': {'id': {'S': 'A'}},
                    'UpdateExpression': 'SET soDu = soDu - :x',
                    'ConditionExpression': 'soDu >= :x',
                    'ExpressionAttributeValues': {':x': {'N': '100'}}}},
        {'Update': {'TableName': 'TaiKhoan',
                    'Key': {'id': {'S': 'B'}},
                    'UpdateExpression': 'SET soDu = soDu + :x',
                    'ExpressionAttributeValues': {':x': {'N': '100'}}}}
    ],
    ClientRequestToken='ma-giao-dich-duy-nhat-123'    # ← tính idempotent
)

Nếu điều kiện soDu >= 100 không thoả, cả hai thao tác đều bị huỷ — không có chuyện trừ tiền mà không cộng.

ClientRequestToken lo vế idempotent: gửi lại cùng token trong 10 phút thì DynamoDB không thực hiện lại, chỉ trả về kết quả cũ. Đây chính xác là thứ đề yêu cầu.

Chi phí: giao dịch tốn gấp đôi WCU so với ghi thường — cái giá của tính nguyên tử.

Vì sao các phương án khác sai

  • D. BatchWriteItem và "cấu hình idempotency ở mức bảng" — sai hai chỗ. Thứ nhất, BatchWriteItem KHÔNG nguyên tử: mỗi item được xử lý độc lập, và một số có thể thành công trong khi số khác trả về trong UnprocessedItems. Thứ hai, không có thiết lập "idempotency ở mức bảng" trong DynamoDB.
  • A. Bật DynamoDB Streams rồi dùng BatchWriteItem — Streams là cơ chế ghi lại thay đổi để xử lý về sau; nó không làm cho thao tác ghi trở nên nguyên tử. Và BatchWriteItem vẫn không nguyên tử như đã nói.
  • B. Dùng SQS FIFO với SendMessageBatch — SQS FIFO có thứ tự và khử trùng lặp trong 5 phút, nhưng nó không tạo giao dịch trên DynamoDB. Message vào hàng đợi rồi consumer vẫn phải tự ghi từng cái — và nếu một cái hỏng thì các cái kia đã ghi rồi.

Ghi nhớ

Ba nhóm API ghi của DynamoDB: | API | Nguyên tử | Số item | Chi phí | |---|---|---|---| | PutItem / UpdateItem | một item | 1 | 1× | | BatchWriteItem | ❌ từng item độc lập | 25 | 1× | | TransactWriteItems | ✅ tất cả hoặc không | 100 | 2× |

Bốn thao tác dùng được trong một giao dịch: | Thao tác | Việc | |---|---| | Put | ghi item | | Update | cập nhật item | | Delete | xoá item | | ConditionCheck | kiểm tra điều kiện trên item KHÁC mà không sửa nó |

ConditionCheck rất hữu ích: ví dụ chỉ cho đặt hàng nếu tài khoản đang ở trạng thái hoạt động, mà không cần sửa gì trong bản ghi tài khoản.

Giới hạn cần biết: không được có hai thao tác trên cùng một item trong một giao dịch, và tổng kích thước không quá 4 MB.