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

Tìm thấy 1356 câu.

Câu 681 Chọn nhiều đáp án AWS Networking & Content Delivery

An organization needs to add encryption in-transit to an existing website running behind an Elastic Load Balancer. The website’s Amazon EC2 instances are CPU-constrained and therefore load on their CPUs should not be increased. What should be done to secure the website? (Select TWO.)

  1. A

    Configure an Elastic Load Balancer with a KMS CMK

  2. B

    Configure SSL certificates on an Elastic Load Balancer

  3. C

    Install SSL certificates on the EC2 instances

  4. D

    Configure an Elastic Load Balancer with SSL termination

  5. E

    Configure an Elastic Load Balancer with SSL pass-through

Xem giải thích

Đáp án

B và D.

  • B — Cấu hình chứng chỉ SSL trên Elastic Load Balancer
  • D — Cấu hình ELB làm SSL termination

Vì sao đúng

Ràng buộc quyết định nằm ở đề: EC2 instance đang bị giới hạn CPU, và không được tăng tải CPU thêm.

SSL termination tại load balancer làm đúng điều đó — toàn bộ công việc mã hoá và giải mã diễn ra trên ELB, không phải trên instance:

Client ──HTTPS (ELB giải mã ở đây)──→ ELB ──HTTP──→ EC2 (không tốn CPU cho TLS)

Bắt tay TLS là thao tác tốn CPU đáng kể — nhất là phần mã hoá bất đối xứng lúc khởi tạo mỗi kết nối. Đẩy nó sang ELB nghĩa là EC2 dành trọn CPU cho việc xử lý ứng dụng.

Hai bước cấu hình chính là hai đáp án:

aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:loadbalancer/app/web/abc \
  --protocol HTTPS --port 443 \
  --certificates CertificateArn=arn:aws:acm:...:certificate/xyz \
  --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
  --default-actions Type=forward,TargetGroupArn=<target-group-HTTP>

Lợi ích kèm theo: quản lý chứng chỉ tập trung ở một chỗ thay vì cài lên từng instance, và chứng chỉ ACM miễn phí, tự gia hạn vĩnh viễn.

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

  • C. Cài chứng chỉ SSL lên các EC2 instance — vi phạm thẳng ràng buộc của đề: instance phải tự xử lý TLS, tốn thêm CPU mà chúng đang thiếu. Ngoài ra phải cài và gia hạn chứng chỉ trên từng máy.
  • E. Cấu hình ELB với SSL pass-through — passthrough chuyển tiếp traffic đã mã hoá xuống instance nguyên vẹn, nên instance vẫn phải giải mã — cùng vấn đề với C. (Và với ALB thì không làm được: ALB ở tầng 7 nên bắt buộc phải giải mã để đọc HTTP. Passthrough chỉ có ở NLB, vốn ở tầng 4.)
  • A. Cấu hình ELB với KMS CMK — nhầm hai loại mã hoá: KMS mã hoá dữ liệu khi lưu (at rest), còn đề hỏi về mã hoá khi truyền (in transit) — việc của TLS. Và ELB không nhận CMK làm cơ chế mã hoá đường truyền.

Ghi nhớ

Ba mô hình mã hoá với load balancer: | Mô hình | Client → ELB | ELB → EC2 | CPU của EC2 | |---|---|---|---| | SSL termination | HTTPS | HTTP | không tốn | | End-to-end encryption | HTTPS | HTTPS | tốn | | SSL passthrough (chỉ NLB) | HTTPS | HTTPS nguyên vẹn | tốn |

Cách chọn theo từ khoá trong đề: | Đề nói | Chọn | |---|---| | "không tăng tải CPU cho EC2", "CPU-constrained" | termination | | "tuân thủ đòi mã hoá toàn tuyến" | end-to-end | | "ELB không được thấy nội dung" | passthrough với NLB |

Với end-to-end, có một chi tiết tiện lợi: ALB không kiểm tra chứng chỉ của backend, nên EC2 dùng được chứng chỉ tự ký — không tốn thêm chi phí nào.

Vài lưu ý về chứng chỉ ACM: | Điểm | Chi tiết | |---|---| | Chứng chỉ công cộng | miễn phí, tự gia hạn (với DNS validation) | | Không xuất được private key | nên không cài lên EC2 được | | Dùng với | ELB, CloudFront, API Gateway — không dùng trực tiếp trên EC2 | | SNI | ALB gắn được nhiều chứng chỉ trên một listener |

Và hai việc nên làm kèm theo:

  1. Chọn SSL policy đủ mới (ELBSecurityPolicy-TLS13-1-2-...) — bản cũ vẫn cho phép TLS 1.0/1.1 vốn đã bị coi là không an toàn.
  2. Đọc header X-Forwarded-Proto trong ứng dụng — thiếu nó, ứng dụng tưởng client dùng HTTP và có thể sinh link sai giao thức hoặc lặp vô hạn khi tự chuyển hướng.
Câu 682 AWS Storage

You run an ad-supported photo sharing website using Amazon S3 to serve photos to visitors of your site. At some point you find out that other sites have been linking to the photos on your site, causing loss to your business.
What is an effective method to mitigate this?

  1. A

    Block the IPs of the offending websites in Security Groups

  2. B

    Store photos on an EBS volume of the web server

  3. C

    Use CloudFront distributions for static content

  4. D

    Remove public read access and use signed URLs with expiry dates

Xem giải thích

Đáp án

D — Gỡ quyền đọc công khai và dùng signed URL có thời hạn.

Vì sao đúng

Vấn đề trong đề gọi là hotlinking: website khác nhúng thẳng ảnh từ S3 của bạn vào trang của họ. Người xem tải ảnh từ bucket của bạn, còn quảng cáo thì hiện trên trang của họ — bạn trả tiền băng thông mà không có doanh thu.

Nguyên nhân gốc: ảnh đang ở chế độ đọc công khai, nên bất kỳ URL nào cũng dùng được vĩnh viễn.

Presigned URL cắt đứt điều đó: mỗi URL mang chữ ký và thời hạn:

url = s3.generate_presigned_url(
    'get_object',
    Params={'Bucket': 'kho-anh', 'Key': 'anh-123.jpg'},
    ExpiresIn=300          # hết hạn sau 5 phút
)

Vì sao nó giải quyết được hotlinking:

Trước: <img src="https://kho-anh.s3.amazonaws.com/anh-123.jpg">
       → URL cố định, ai copy cũng dùng được MÃI MÃI

Sau:   <img src="https://kho-anh.s3.amazonaws.com/anh-123.jpg?X-Amz-Signature=...&X-Amz-Expires=300">
       → URL HẾT HẠN sau 5 phút
       → website khác copy về thì vài phút sau ảnh vỡ

Ứng dụng của bạn sinh URL mới ở mỗi lần người dùng tải trang, nên trải nghiệm không đổi. Còn ai copy URL đem đi nơi khác thì URL đó tự chết.

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

  • C. Dùng CloudFront cho nội dung tĩnh — giảm chi phí băng thông (CloudFront rẻ hơn S3 trực tiếp) nhưng không ngăn được hotlinking: URL của CloudFront vẫn công khai và vĩnh viễn. (CloudFront có cơ chế chống hotlinking — signed URL/cookie kèm giới hạn IP, hoặc kiểm tra header Referer bằng WAF — nhưng phương án chỉ nói dùng CloudFront chung chung, không nêu cơ chế nào.)
  • A. Chặn IP của các website vi phạm bằng Security Group — hiểu sai cách hotlinking hoạt động: trình duyệt của người dùng cuối tải ảnh, không phải máy chủ của website kia. Bạn sẽ phải chặn IP của hàng triệu người dùng — bất khả thi. Và Security Group không áp cho S3 (S3 không nằm trong VPC).
  • B. Lưu ảnh trên EBS volume của web server — không giải quyết gì: nếu ảnh vẫn phục vụ công khai qua HTTP thì hotlinking vẫn xảy ra y hệt. Và nó còn kém hơn về mọi mặt: không co giãn, không bền bằng S3, và tốn kém hơn.

Ghi nhớ

Các cách chống hotlinking, từ đơn giản tới chặt chẽ: | Cách | Hiệu quả | |---|---| | Kiểm tra header Referer (bằng WAF hoặc bucket policy) | dễ vượt qua — trình duyệt tự đặt được | | S3 presigned URL | ✅ URL tự hết hạn | | CloudFront signed URL/cookie | ✅ hết hạn + GIỚI HẠN IP | | Đóng dấu chìm lên ảnh | không ngăn được, nhưng giữ nhận diện thương hiệu |

So sánh hai loại signed URL: | | S3 presigned | CloudFront signed | |---|---|---| | Tạo bằng | credential IAM | cặp khoá riêng | | Thời hạn tối đa | 7 ngày | không giới hạn | | Giới hạn theo IP | ❌ | ✅ | | Qua CDN | ❌ | ✅ rẻ hơn và nhanh hơn | | Chống hotlink | ✅ | ✅ mạnh hơn |

Với một website ảnh có lưu lượng lớn, kiến trúc tốt nhất là kết hợp cả hai ý tưởng:

Người dùng → CloudFront (signed URL, giới hạn IP) → S3 bucket RIÊNG TƯ (qua OAC)

Bucket không công khai chút nào, CloudFront giảm chi phí băng thông, và signed URL chặn hotlinking. Đề chỉ hỏi cách ngăn hotlinking nên D là đáp án, nhưng trong thực tế nên đi thẳng tới kiến trúc này.

Ba lưu ý khi dùng presigned URL:

  1. Thời hạn kế thừa từ credential tạo URL — URL tạo bằng credential tạm thời của Lambda role sẽ hết hiệu lực khi credential đó hết hạn.
  2. Đặt thời hạn ngắn nhất có thể cho ảnh hiển thị trên trang.
  3. Sinh URL ở phía máy chủ, không bao giờ để logic ký nằm trong JavaScript của trình duyệt.
Câu 683 Chọn nhiều đáp án AWS Security, Identity, & Compliance

An application is running on a cluster of Amazon EC2 instances. The application has received an error when trying to read objects stored within an Amazon S3 bucket. The bucket is encrypted with server-side encryption and AWS KMS managed keys (SSE-KMS). The error is as follows:

Service: AWSKMS; Status Code: 400, Error Code: ThrottlingException

Which combination of steps should be taken to prevent this failure? (Select TWO.)

  1. A

    Import a customer master key (CMK) with a larger key size

  2. B

    Contact AWS support to request an AWS KMS rate limit increase

  3. C

    Use more than once customer master key (CMK) to encrypt S3 data

  4. D

    Contact AWS support to request an S3 rate limit increase

  5. E

    Perform error retries with exponential backoff in the application code

Xem giải thích

Đáp án

B và E.

  • E — Thử lại với exponential backoff trong mã ứng dụng
  • B — Liên hệ AWS Support xin tăng hạn mức của KMS

Vì sao đúng

Lỗi ThrottlingException từ KMS khi đọc object mã hoá bằng SSE-KMS có nguyên nhân rõ ràng: mỗi lần đọc object là một lời gọi kms:Decrypt, và cụm EC2 đang vượt hạn mức request mỗi giây của KMS.

Có hai hướng xử lý, và đề yêu cầu cả hai.

E — thử lại với backoff. Throttle thường là hiện tượng tạm thời ở các đỉnh ngắn, nên thử lại sau khoảng chờ tăng dần là cách chữa rẻ nhất:

import time, random
from botocore.exceptions import ClientError

def doc_object_co_backoff(bucket, key, so_lan=5):
    for lan in range(so_lan):
        try:
            return s3.get_object(Bucket=bucket, Key=key)
        except ClientError as e:
            if e.response['Error']['Code'] not in ('ThrottlingException', 'SlowDown'):
                raise
            time.sleep((2 ** lan) * 0.1 + random.uniform(0, 0.1))
    raise Exception('Vẫn bị throttle sau nhiều lần thử')

Jitter (thành phần ngẫu nhiên) rất quan trọng ở đây: đề nói đây là một cụm EC2, nên nếu tất cả instance cùng bị throttle và cùng thử lại đúng một thời điểm, chúng tạo ra đỉnh mới — hiện tượng thundering herd.

B — xin tăng hạn mức. Hạn mức request của KMS là hạn mức mềm, tăng được qua Service Quotas hoặc AWS Support. Với ứng dụng đọc S3 khối lượng lớn, đây là bước hợp lý.

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

  • C. Dùng nhiều CMK để mã hoá dữ liệu S3 — đây là phương án đáng bàn nhất vì nghe hợp lý. Nhưng hạn mức request của KMS áp cho cả TÀI KHOẢN trong một Region, không phải cho từng khoá. Chia ra nhiều CMK không tăng tổng năng lực, chỉ làm phức tạp việc quản lý khoá.
  • A. Nhập CMK với kích thước khoá lớn hơn — kích thước khoá không liên quan tới hạn mức request. Và với khoá đối xứng, KMS chỉ hỗ trợ AES-256 — không có lựa chọn "lớn hơn".
  • D. Xin tăng hạn mức của S3 — sai dịch vụ: thông báo lỗi ghi rõ Service: AWSKMS. S3 không phải nơi bị nghẽn.

Ghi nhớ

Giải pháp hiệu quả nhất cho tình huống này lại không nằm trong bộ phương án: bật S3 Bucket Keys.

aws s3api put-bucket-encryption --bucket kho-du-lieu \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms",
        "KMSMasterKeyID": "arn:aws:kms:...:key/abc"},
      "BucketKeyEnabled": true
    }]}'

Nó dùng một khoá ở mức bucket cho nhiều object thay vì gọi KMS cho từng object — giảm số lời gọi KMS tới 99% và giảm cả chi phí. Đây là điều nên làm đầu tiên trong thực tế.

Ba cách xử lý throttle của KMS, theo thứ tự nên thử: | Cách | Hiệu quả | |---|---| | S3 Bucket Keys (với SSE-KMS trên S3) | giảm ~99% lời gọi | | Data key caching (khi tự mã hoá) | giảm hàng trăm lần | | Exponential backoff + jitter | xử lý đỉnh tạm thời | | Xin tăng hạn mức | khi nhu cầu thật sự vượt mức |

Hạn mức request của KMS — điểm quan trọng nhất của câu này: | Đặc điểm | Chi tiết | |---|---| | Phạm vi | TÀI KHOẢN + REGION, không phải từng khoá | | Loại | hạn mức mềm, tăng được | | Khoá đối xứng | vài chục nghìn request/giây (tuỳ Region) | | Khoá bất đối xứng | thấp hơn nhiều | | Custom key store (CloudHSM) | thấp hơn hẳn |

Và các lỗi nên thử lại với backoff — bảng chung cho mọi dịch vụ AWS: | Lỗi | Thử lại? | |---|---| | ThrottlingException, SlowDown, RequestLimitExceeded | ✅ với backoff + jitter | | 5xx (lỗi máy chủ) | ✅ | | AccessDenied, ValidationException | ❌ thử lại vô ích |

Câu 684 AWS Developer Tools

A Developer is creating an AWS Lambda function that generates a new file each time it runs. Each new file must be checked into an AWS CodeCommit repository hosted in the same AWS account.

How should the Developer accomplish this?

  1. A

    Upload the new file to an Amazon S3 bucket. Create an AWS Step Function to accept S3 events. In the Step Function, add the new file to the repository

  2. B

    After the new file is created in Lambda, use cURL to invoke the CodeCommit API. Send the file to the repository

  3. C

    When the Lambda function starts, use the Git CLI to clone the repository. Check the new file into the cloned repository and push the change

  4. D

    Use an AWS SDK to instantiate a CodeCommit client. Invoke the put_file method to add the file to the repository

Xem giải thích

Đáp án

D — Dùng AWS SDK tạo client của CodeCommit, gọi phương thức put_file để thêm tệp vào repository.

Vì sao đúng

CodeCommit có API đầy đủ để thao tác với tệp mà không cần Git client — rất hợp với Lambda, nơi bạn không có sẵn Git và không muốn cài thêm.

import boto3
codecommit = boto3.client('codecommit')

def lambda_handler(event, context):
    noi_dung = tao_tep()
    codecommit.put_file(
        repositoryName='kho-du-lieu',
        branchName='main',
        fileContent=noi_dung.encode('utf-8'),
        filePath=f'bao-cao/{context.aws_request_id}.json',
        commitMessage='Thêm tệp tự động',
        name='Lambda Bot',
        email='bot@congty.com'
    )

Điểm hay: put_file tự tạo commit — không cần gọi thêm API nào. Và AWS SDK tự lấy credential từ execution role, nên không có thông tin xác thực nào phải quản lý.

Quyền cần cho execution role:

{"Effect": "Allow",
 "Action": ["codecommit:PutFile", "codecommit:GetBranch"],
 "Resource": "arn:aws:codecommit:ap-southeast-1:123456789012:kho-du-lieu"}

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

  • C. Dùng Git CLI để clone repository trong Lambda — không khả thi: môi trường Lambda không có Git cài sẵn, /var/task chỉ đọc, và clone cả kho ở mỗi lần chạy là cực kỳ tốn thời gian với kho lớn. Bạn cũng phải tự lo credential helper.
  • B. Dùng cURL gọi API CodeCommit — về lý thuyết làm được, nhưng phải tự cài đặt ký SigV4 — băm payload, dựng canonical request, tính chữ ký HMAC nhiều bước. Hàng chục dòng dễ sai cho việc mà SDK làm sẵn. Và curl chưa chắc có trong runtime Lambda.
  • A. Tải lên S3 → Step Functions → thêm vào repository — thêm hai dịch vụ mà không giải quyết được gì: cuối cùng vẫn phải có mã gọi API CodeCommit, tức là vẫn cần phương án D. Nhiều thành phần hơn, nhiều chỗ hỏng hơn.

Ghi nhớ

Các API thao tác tệp của CodeCommit — cho phép làm việc với kho mã hoàn toàn không cần Git: | API | Việc | |---|---| | PutFile | thêm hoặc sửa MỘT tệp (tự tạo commit) | | CreateCommit | nhiều thay đổi trong một commit | | DeleteFile | xoá tệp | | GetFile | đọc nội dung | | GetBranch, CreateBranch | quản lý nhánh |

Khi cần nhiều tệp trong một commit, dùng create_commit:

codecommit.create_commit(
    repositoryName='kho-du-lieu',
    branchName='main',
    parentCommitId=commit_cha,
    putFiles=[{'filePath': 'a.json', 'fileContent': noi_dung_a},
              {'filePath': 'b.json', 'fileContent': noi_dung_b}]
)

Hai lưu ý thực tế:

  1. Xung đột commit song song: nhiều lần gọi Lambda cùng ghi vào một nhánh có thể làm parentCommitId lỗi thời. Hãy thử lại với exponential backoff, hoặc cho mỗi lần chạy ghi vào đường dẫn riêng như ví dụ trên.
  2. Kho mã không phải nơi lưu dữ liệu vận hành. Nếu tệp sinh ra ở mọi lần chạy chỉ là dữ liệu chứ không phải mã nguồn, S3 mới là chỗ đúng — Git sẽ phình rất nhanh và không có cơ chế dọn.

(Ghi chú thời sự: CodeCommit ngừng nhận khách hàng mới từ 7/2024; tài khoản đã dùng vẫn hoạt động bình thường.)

Câu 685 AWS Database

An application writes items to an Amazon DynamoDB table. As the application scales to thousands of instances, calls to the DynamoDB API generate occasional ThrottlingException errors. The application is coded in a language that is incompatible with the AWS SDK.

What can be done to prevent the errors from occurring?

  1. A

    Pass API calls through Amazon API Gateway

  2. B

    Send the items to DynamoDB through Amazon Kinesis Data Firehose

  3. C

    Add exponential backoff to the application logic

  4. D

    Use Amazon SQS as an API message bus

Xem giải thích

Đáp án

C — Thêm exponential backoff vào logic ứng dụng.

Vì sao đúng

Chi tiết quyết định nằm ở câu cuối của đề: ứng dụng viết bằng ngôn ngữ không tương thích với AWS SDK.

Điều đó quan trọng vì AWS SDK vốn đã có sẵn cơ chế thử lại với exponential backoff cho các lỗi như ThrottlingException. Không dùng được SDK nghĩa là không có cơ chế đó, và phải tự cài đặt.

Cách cài đặt, bằng bất kỳ ngôn ngữ nào:

lan_thu = 0
lặp:
    goi_api_dynamodb()
    nếu thành công: dừng
    nếu lỗi là ThrottlingException:
        cho = (2 ^ lan_thu) * 100ms + ngẫu_nhiên(0..100ms)
        ngủ(cho)
        lan_thu += 1
    ngược lại: ném lỗi

Các khoảng chờ tăng theo cấp số nhân: 100ms → 200ms → 400ms → 800ms → 1,6s, cho DynamoDB thời gian phân bổ lại năng lực.

Thành phần ngẫu nhiên (jitter) không phải trang trí. Đề nói ứng dụng đã mở rộng tới hàng nghìn instance — nếu tất cả cùng bị throttle và cùng thử lại đúng một thời điểm, chúng tạo ra đỉnh mới ngay lập tức. Hiện tượng này gọi là thundering herd.

ThrottlingException là lỗi tạm thời — thử lại sau một chút thường thành công, nhất là khi DynamoDB có burst capacity tích luỹ từ 300 giây trước đó.

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

  • D. Dùng SQS làm bus tin nhắn cho API — san phẳng đỉnh được, nhưng nó thay đổi hẳn mô hình ứng dụng: ghi trở thành bất đồng bộ, phải viết consumer, phải xử lý thứ tự và trùng lặp. Quá nặng cho vấn đề mà backoff giải quyết bằng vài chục dòng.
  • B. Gửi item qua Kinesis Data Firehose — Firehose không hỗ trợ DynamoDB làm đích. Đích của nó là S3, Redshift, OpenSearch, Splunk và HTTP endpoint. Phương án này không chạy được.
  • A. Cho lời gọi API đi qua API Gateway — thêm một tầng mà không giải quyết gì: DynamoDB vẫn throttle như cũ. API Gateway có throttling riêng nhưng đó là để bảo vệ chính nó.

Ghi nhớ

Các lỗi nên và không nên thử lại: | Lỗi | Thử lại? | |---|---| | ThrottlingException, ProvisionedThroughputExceededException | ✅ với backoff + jitter | | RequestLimitExceeded, 5xx | ✅ | | ValidationException, AccessDenied | ❌ thử lại vô ích | | ConditionalCheckFailedException | ❌ (phải đọc lại rồi mới thử) |

Ngoài backoff, các cách giảm throttle cho DynamoDB: | Cách | Chi tiết | |---|---| | On-demand mode | không bao giờ throttle, đắt hơn khi tải đều | | Auto Scaling cho provisioned | tự tăng WCU, phản ứng chậm vài phút | | Sửa partition key | nếu nguyên nhân là hot partition | | Giảm kích thước item | ít WCU hơn cho mỗi lần ghi |

Dòng thứ ba đáng kiểm tra trước tiên. Cách phân biệt: | Dấu hiệu | Kết luận | |---|---| | ThrottledRequests > 0 nhưng ConsumedWriteCapacityUnits thấp | hot partition — phải sửa thiết kế khoá | | Tiêu thụ chạm sát mức cấp phát | thiếu capacity thật — tăng WCU |

Với ứng dụng không dùng SDK, hãy xem hai metric này trong CloudWatch để biết vấn đề là thiếu năng lực toàn cục hay chỉ nóng ở một phân vùng.

Câu 686 AWS Developer Tools

A Development team have moved their continuous integration and delivery (CI/CD) pipeline into the AWS Cloud. The team is leveraging AWS CodeCommit for management of source code. The team need to compile their source code, run tests, and produce software packages that are ready for deployment.

Which AWS service can deliver these outcomes?

  1. A

    AWS CodeBuild

  2. B

    AWS Cloud9

  3. C

    AWS CodePipeline

  4. D

    AWS CodeCommit

Xem giải thích

Đáp án

A — AWS CodeBuild.

Vì sao đúng

Đề liệt kê đúng ba việc, và cả ba đều là chức năng cốt lõi của CodeBuild:

  1. Biên dịch mã nguồn
  2. Chạy kiểm thử
  3. Tạo ra gói phần mềm sẵn sàng triển khai

CodeBuild là dịch vụ build được quản lý hoàn toàn — không có máy chủ build nào để bạn nuôi:

version: 0.2
phases:
  install:
    runtime-versions: {java: corretto21}
  pre_build:
    commands: [mvn dependency:resolve]
  build:
    commands:
      - mvn compile          # ① biên dịch
      - mvn test             # ② chạy test
      - mvn package          # ③ đóng gói
artifacts:
  files: [target/ung-dung.jar]
reports:
  bao-cao-test:
    files: ['target/surefire-reports/*.xml']
    file-format: JUNITXML

Phần reports đáng chú ý: CodeBuild hiển thị kết quả test trực quan trong Console, kèm tỷ lệ đạt và xu hướng theo thời gian.

Và vì nó trả tiền theo phút build, không có chi phí khi không ai build — khác hẳn việc nuôi một máy chủ Jenkins.

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

  • C. AWS CodePipeline — điều phối quy trình, nó không tự build hay test. Nó gọi CodeBuild làm việc đó. Nó là cái bao trùm, không phải cái thực thi.
  • D. AWS CodeCommit — lưu trữ mã nguồn (Git). Đề đã nói đội đang dùng nó cho việc đó rồi; câu hỏi là bước tiếp theo.
  • B. AWS Cloud9 — IDE trên trình duyệt. Bạn chạy build thủ công trong đó khi phát triển, nhưng nó không phải bước tự động trong pipeline.

Ghi nhớ

Vai trò từng dịch vụ trong pipeline CI/CD:

CodeCommit → CodeBuild → CodeDeploy
 (lưu mã)   (build+test)  (triển khai)
      └────── CodePipeline điều phối ──────┘
Dịch vụ Việc
CodeCommit lưu trữ mã nguồn
CodeBuild biên dịch, CHẠY TEST, đóng gói
CodeDeploy triển khai lên EC2, on-premises, ECS, Lambda
CodePipeline điều phối — cái bao trùm
CodeArtifact kho package (npm, Maven, PyPI)

Câu thần chú: CodePipeline là nhạc trưởng; CodeBuild và CodeDeploy là nhạc công.

Bốn giai đoạn của buildspec, và điều kiện chạy: | Phase | Chạy khi | |---|---| | install | luôn (đầu tiên) — cài runtime, công cụ | | pre_build | install xong — đăng nhập ECR, tải dependency | | build | pre_build xong — biên dịch, test | | post_build | build THÀNH CÔNG — đẩy image, đóng gói |

Quy tắc quan trọng: phase thất bại thì các phase sau bị bỏ qua — trừ khối finally của chính phase đó, vốn luôn chạy (dùng để in log chẩn đoán, dọn dẹp).

Và ba mẹo thực dụng: bật caching để tăng tốc build lặp lại, dùng privilegedMode: true nếu cần chạy Docker, và set -x ở đầu phần commands để in ra mọi lệnh trước khi chạy.

Câu 687 AWS Developer Tools

A development team require a fully-managed source control service that is compatible with Git.

Which service should they use?

  1. A

    AWS CodePipeline

  2. B

    AWS CodeDeploy

  3. C

    AWS CodeCommit

  4. D

    AWS Cloud9

Xem giải thích

Đáp án

C — AWS CodeCommit.

Vì sao đúng

Đề nêu hai yêu cầu, và CodeCommit khớp cả hai:

  1. Dịch vụ quản lý mã nguồn được quản lý hoàn toàn (fully-managed)
  2. Tương thích với Git

CodeCommit lưu trữ kho Git chuẩn — mọi lệnh Git bạn quen dùng đều hoạt động bình thường:

git clone https://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/du-an
git checkout -b tinh-nang/moi
git add . && git commit -m "Thêm tính năng"
git push origin tinh-nang/moi

Và vế "fully-managed" nghĩa là bạn không phải vận hành gì: | Việc | AWS lo | |---|---| | Máy chủ, vá lỗi, nâng cấp | ✅ | | Mã hoá at-rest và in-transit | ✅ mặc định | | Sao lưu, sẵn sàng cao | ✅ dư thừa đa AZ | | Dung lượng kho | ✅ không giới hạn | | Phân quyền | ✅ bằng IAM |

Thêm một điểm về bảo mật: CodeCommit không có khái niệm kho công khai — mọi truy cập đều qua IAM, nên không thể vô tình để lộ mã nguồn như với GitHub.

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

  • A. AWS CodePipeline — điều phối quy trình CI/CD: nó lấy mã từ nơi khác rồi chạy build và deploy. Không lưu trữ mã.
  • B. AWS CodeDeploy — triển khai mã đã đóng gói lên EC2, on-premises, ECS, Lambda. Nó lấy gói từ S3 hoặc GitHub.
  • D. AWS Cloud9 — IDE trên trình duyệt. Nó kết nối tới kho mã để làm việc, nhưng bản thân nó không lưu trữ — đóng môi trường là hết.

Ghi nhớ

Vai trò từng dịch vụ: | Dịch vụ | Việc | |---|---| | CodeCommit | lưu trữ mã nguồn (Git) | | CodeBuild | biên dịch, test, đóng gói | | CodeDeploy | triển khai | | CodePipeline | điều phối | | CodeArtifact | kho package (npm, Maven, PyPI) | | Cloud9 | IDE |

Nhận dạng nhanh: đề nói "source control", "Git-compatible", "repository" ⇒ CodeCommit.

Bốn cách xác thực với CodeCommit: | Cách | Giao thức | Dùng khi | |---|---|---| | Git credentials (IAM) | HTTPS | đơn giản nhất cho người dùng | | SSH key | SSH | quen dùng SSH | | git-remote-codecommit | HTTPS (grc://) | dùng được với role, SSO, MFA | | Credential helper | HTTPS | trên EC2, CodeBuild |

Cách thứ ba được AWS khuyến nghị hiện nay vì nó không cần IAM user cố định:

pip install git-remote-codecommit
git clone codecommit://ho-so-aws@kho-cua-toi

(Ghi chú thời sự quan trọng: từ 25/7/2024, AWS ngừng cho khách hàng mới tạo repository trên CodeCommit; các tài khoản đã dùng vẫn hoạt động bình thường và AWS cam kết tiếp tục vận hành. Với dự án mới, dùng GitHub, GitLab hoặc Bitbucket — chúng nối vào CodePipeline qua CodeStar Connections. Câu hỏi vẫn nằm trong phạm vi kỳ thi, nhưng đừng chọn CodeCommit cho hệ thống mới.)

Câu 688 AWS Management & Governance

A Developer has created a serverless function that processes log files. The function should be invoked once every 15 minutes. How can the Developer automatically invoke the function using serverless services?

  1. A

    Configure the Lambda scheduler to run based on recurring time value

  2. B

    Create an Amazon SNS rule to send a notification to Lambda to instruct it to run

  3. C

    Launch an EC2 Linux instance and add a command to periodically invoke the function to its /etc/crontab file

  4. D

    Create an Amazon CloudWatch Events rule that is scheduled to run and invoke the function

Xem giải thích

Đáp án

D — Tạo CloudWatch Events (EventBridge) rule chạy theo lịch và gọi hàm.

Vì sao đúng

Đề nêu hai yêu cầu: chạy mỗi 15 phút một lần, và dùng dịch vụ serverless.

EventBridge Scheduler làm đúng việc đó — không có máy chủ nào, không có gì phải vận hành:

aws events put-rule --name chay-moi-15-phut \
  --schedule-expression "rate(15 minutes)"

aws events put-targets --rule chay-moi-15-phut \
  --targets "Id"="1","Arn"="arn:aws:lambda:...:function:xu-ly-log"

aws lambda add-permission --function-name xu-ly-log \
  --statement-id EventBridgeInvoke --action lambda:InvokeFunction \
  --principal events.amazonaws.com \
  --source-arn arn:aws:events:...:rule/chay-moi-15-phut

Hai kiểu biểu thức lịch: | Kiểu | Ví dụ | Dùng khi | |---|---|---| | rate() | rate(15 minutes), rate(1 hour), rate(7 days) | chu kỳ đều | | cron() | cron(0 2 * * ? *) — 2 giờ sáng mỗi ngày | mốc thời gian cụ thể |

Với chu kỳ đơn giản như đề bài, rate(15 minutes) là cách gọn nhất.

Chi phí: EventBridge rule theo lịch miễn phí, bạn chỉ trả tiền cho các lần chạy Lambda.

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

  • A. Cấu hình "Lambda scheduler" chạy theo chu kỳ — Lambda không có bộ lập lịch tích hợp. Việc lên lịch hoàn toàn thuộc về EventBridge. (Console của Lambda có mục thêm trigger kiểu "EventBridge (CloudWatch Events)" — nhưng đó chính là tạo EventBridge rule, không phải một tính năng riêng của Lambda.)
  • B. Tạo "SNS rule" gửi thông báo bảo Lambda chạy — SNS không có khái niệm rule hay lịch. Nó là dịch vụ pub/sub, phản ứng khi có message được publish, không tự phát sinh sự kiện theo thời gian.
  • C. Chạy EC2 Linux và thêm lệnh vào /etc/crontab — không phải serverless, trái yêu cầu của đề. Bạn phải nuôi một EC2 chạy 24/7 chỉ để gọi một hàm mỗi 15 phút — vừa tốn tiền, vừa phải vá và giám sát, vừa là điểm hỏng đơn lẻ.

Ghi nhớ

Hai cách lên lịch trên AWS: | | EventBridge Rule | EventBridge Scheduler | |---|---|---| | Ra đời | cũ hơn, phổ biến | mới hơn (2022), nhiều tính năng hơn | | Đích | ~20 loại | hơn 270 API của AWS | | Múi giờ | chỉ UTC | ✅ hỗ trợ múi giờ và giờ mùa hè | | Chạy một lần | ❌ | ✅ at() | | Cửa sổ linh hoạt | ❌ | ✅ rải tải trong một khoảng | | Số lịch | giới hạn theo rule | hàng triệu |

Với nhu cầu mới, EventBridge Scheduler thường là lựa chọn tốt hơn:

aws scheduler create-schedule --name xu-ly-log \
  --schedule-expression "rate(15 minutes)" \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{"Arn":"arn:aws:lambda:...:function:xu-ly-log",
             "RoleArn":"arn:aws:iam::...:role/SchedulerRole"}'

Cú pháp cron() của AWS có sáu trường (khác cron của Linux vốn có năm):

cron(phút giờ ngày-tháng tháng ngày-tuần năm)
cron(0 2 * * ? *)        2 giờ sáng mỗi ngày
cron(0/15 * * * ? *)     mỗi 15 phút
cron(0 9 ? * MON-FRI *)  9 giờ sáng các ngày làm việc

Chú ý dấu ?: một trong hai trường ngày-tháng và ngày-tuần phải là ? — không được khai cả hai.

Và nhớ: lịch của EventBridge chạy theo UTC. Muốn "2 giờ sáng giờ Việt Nam" thì phải tự trừ 7 giờ, hoặc dùng EventBridge Scheduler vốn hỗ trợ múi giờ trực tiếp.

Câu 689 AWS Networking & Content Delivery

A Developer manages a website running behind an Elastic Load Balancer in the us-east-1 region. The Developer has recently deployed an identical copy of the website in us-west-1 and needs to send 20% of the traffic to the new site.

How can the Developer achieve this requirement?

  1. A

    Use a blue/green deployment with Amazon Elastic Beanstalk

  2. B

    Use an Amazon Route 53 Geolocation Routing Policy

  3. C

    Use a blue/green deployment with Amazon CodeDeploy

  4. D

    Use an Amazon Route 53 Weighted Routing Policy

Xem giải thích

Đáp án

D — Dùng Route 53 Weighted Routing Policy.

Vì sao đúng

Yêu cầu rất cụ thể: gửi 20% traffic sang site mới ở Region khác. Weighted routing là chính sách duy nhất của Route 53 chia được traffic theo tỷ lệ.

Bạn tạo nhiều bản ghi cùng tên với trọng số khác nhau:

# Site cũ ở us-east-1 — trọng số 80
aws route53 change-resource-record-sets --hosted-zone-id Z123 --change-batch '{
  "Changes": [{"Action":"CREATE","ResourceRecordSet":{
    "Name":"www.example.com","Type":"A",
    "SetIdentifier":"site-cu","Weight":80,
    "AliasTarget":{"DNSName":"elb-dong...elb.amazonaws.com",
                   "HostedZoneId":"Z35SXDOTRQ7X7K","EvaluateTargetHealth":true}}}]}'

(Rồi bản ghi thứ hai với SetIdentifier: "site-moi" và Weight: 20.)

Cách Route 53 tính tỷ lệ:

Tỷ lệ = trọng số của bản ghi / TỔNG các trọng số
      = 80 / (80 + 20) = 80%  cho site cũ
      = 20 / (80 + 20) = 20%  cho site mới

Trọng số không nhất thiết phải cộng thành 100 — dùng 80/20 chỉ vì dễ đọc.

Điểm hay: tăng dần tỷ lệ chỉ là sửa số, và đặt Weight: 0 cho site mới là rollback tức thì (Route 53 ngừng trả về bản ghi đó).

Và nên đặt EvaluateTargetHealth: true để Route 53 tự bỏ qua Region đang có sự cố.

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

  • B. Geolocation Routing Policy — chia traffic theo vị trí địa lý của người dùng, không theo tỷ lệ phần trăm. Bạn khai được "người ở châu Á thì tới Region này", nhưng không khai được "20% traffic".
  • A. Blue/green deployment với Elastic Beanstalk — cơ chế của Beanstalk là hoán đổi CNAME giữa hai môi trường, tức là chuyển 100% traffic cùng lúc. Nó không chia được theo tỷ lệ, và cũng không hoạt động xuyên Region như đề mô tả. (Beanstalk có tính năng traffic splitting chia được %, nhưng chỉ trong một môi trường, không phải giữa hai Region.)
  • C. Blue/green deployment với CodeDeploy — CodeDeploy chia traffic được (canary, linear), nhưng nó làm việc ở mức target group của một load balancer hoặc mức Lambda alias — không định tuyến giữa hai Region.

Ghi nhớ

Các chính sách định tuyến của Route 53: | Chính sách | Chọn endpoint theo | |---|---| | Simple | một bản ghi duy nhất | | Weighted | tỷ lệ % — canary, A/B testing, chia tải | | Latency-based | độ trễ mạng đo được — nhanh nhất | | Failover | chủ động – dự phòng | | Geolocation | vị trí địa lý của người dùng | | Geoproximity | khoảng cách + bias | | Multivalue answer | trả nhiều IP kèm health check | | IP-based | theo dải IP của client |

Ba chính sách hay bị lẫn: | | Chọn theo | Dùng khi | |---|---|---| | Weighted | tỷ lệ bạn đặt | canary, chia tải giữa Region | | Latency-based | tốc độ mạng | muốn nhanh nhất | | Geolocation | quốc gia của người dùng | tuân thủ pháp lý, nội dung theo vùng |

Nhận dạng nhanh: đề nói "X% traffic", "gradually shift", "A/B testing" ⇒ weighted routing.

Một hạn chế của cách này cần biết: chuyển traffic bằng DNS phụ thuộc TTL. Client đã cache kết quả cũ vẫn tới site cũ trong khoảng TTL — nên đặt TTL ngắn (60 giây) khi đang chạy canary, và đừng huỷ site cũ ngay sau khi chuyển hết.

Với nhu cầu chuyển traffic nhanh và chính xác hơn giữa các Region, cân nhắc AWS Global Accelerator — nó cũng có traffic dial theo % nhưng chuyển hướng trong vài giây, không phụ thuộc DNS TTL.

Câu 690 AWS Developer Tools

An application is being instrumented to send trace data using AWS X-Ray. A Developer needs to upload segment documents using JSON-formatted strings to X-Ray using the API. Which API action should the developer use?

  1. A

    The UpdateGroup API action

  2. B

    The PutTelemetryRecords API action

  3. C

    The PutTraceSegments API action

  4. D

    The GetTraceSummaries API action

Xem giải thích

Đáp án

C — API action PutTraceSegments.

Vì sao đúng

PutTraceSegments là API dùng để tải segment document lên X-Ray, và nó nhận chuỗi JSON:

aws xray put-trace-segments --trace-segment-documents '{
  "trace_id": "1-5f84c7a1-9d2e1f3a4b5c6d7e8f9a0b1c",
  "id": "6226467e3f845502",
  "name": "api-don-hang",
  "start_time": 1754380800.0,
  "end_time": 1754380800.5,
  "http": {"request": {"method": "POST", "url": "https://api.example.com/don-hang"},
           "response": {"status": 200}},
  "annotations": {"don_hang_id": "DH-123"}
}'

Đây chính xác là điều đề mô tả: "upload segment documents using JSON-formatted strings".

Trong thực tế, X-Ray daemon là bên gọi API này — SDK gửi segment qua UDP cổng 2000 tới daemon, daemon gom lô rồi gọi PutTraceSegments:

Ứng dụng (X-Ray SDK) --UDP 2000--> X-Ray daemon --PutTraceSegments--> Dịch vụ X-Ray

Bạn chỉ gọi trực tiếp API này khi tự viết bộ đo đạc cho một môi trường không có SDK hoặc daemon.

Ba trường bắt buộc trong mọi segment: trace_id, id, và name, cộng với start_time và end_time (hoặc in_progress: true nếu segment chưa kết thúc).

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

  • B. PutTelemetryRecords — đây là phương án gần nhất và cần phân biệt kỹ: nó gửi số liệu vận hành của chính daemon (bao nhiêu segment đã gửi, bao nhiêu bị bỏ, bao nhiêu lỗi). Đó là metric về sức khoẻ của daemon, không phải dữ liệu trace.
  • D. GetTraceSummaries — API ĐỌC, dùng để tìm kiếm trace bằng filter expression. Ngược chiều với việc gửi dữ liệu lên.
  • A. UpdateGroup — quản lý group trong X-Ray (tập hợp trace theo một filter expression, để nhóm dashboard và metric). Không liên quan tới việc gửi segment.

Ghi nhớ

Các API của X-Ray, chia theo chiều: | Chiều | API | Việc | |---|---|---| | Ghi | PutTraceSegments | gửi segment document | | Ghi | PutTelemetryRecords | số liệu sức khoẻ của daemon | | Đọc | GetTraceSummaries | tìm trace bằng filter expression | | Đọc | BatchGetTraces | lấy chi tiết đầy đủ theo trace ID | | Đọc | GetServiceGraph | dựng service map | | Quản lý | CreateGroup, UpdateGroup | nhóm trace | | Quản lý | PutEncryptionConfig, GetSamplingRules | cấu hình |

Cấu trúc của Trace ID — định dạng cố định, không nhét thêm dữ liệu được:

1-5f84c7a1-9d2e1f3a4b5c6d7e8f9a0b1c
│  │        └─ 96 bit ngẫu nhiên
│  └─ thời điểm (epoch, dạng hex)
└─ phiên bản

Hai khái niệm cần phân biệt khi gắn dữ liệu vào segment: | | Annotation | Metadata | |---|---|---| | Tìm kiếm được | ✅ | ❌ | | Số lượng tối đa | 50 mỗi trace | không giới hạn | | Kiểu dữ liệu | chuỗi, số, boolean | bất kỳ JSON nào |

Nguyên tắc: thứ gì cần TÌM thì là annotation, thứ gì chỉ để ĐỌC thì là metadata.

Và nơi chạy daemon khác nhau theo môi trường: Lambda thì AWS tự chạy (chỉ cần bật TracingConfig: Active), còn ECS và EKS thì phải chạy daemon dưới dạng container sidecar.