Ngân hàng đề — AWS Certified Solutions Architect Professional

Tìm thấy 1221 câu.

Câu 441 Chọn nhiều đáp án Accelerate Workload Migration and Modernization

A media company has its users accessing the content from different platforms including mobile, tablet, and desktop. Each platform is customized to provide a different user experience based on various viewing modes. Path-based headers are used to serve the content for different platforms, hosted on different Amazon EC2 instances. An Auto Scaling group (ASG) has also been configured for the EC2 instances to ensure that the solution is highly scalable.

Which of the following combination of services can help minimize the cost while maximizing the performance? (Select two)

  1. A

    Application Load Balancer

  2. B

    Amazon Route 53 with traffic flow policies

  3. C

    Amazon CloudFront with Lambda@Edge

  4. D

    Amazon S3 configured as a static website

  5. E

    Network Load Balancer

Xem giải thích

Đáp án

**A và C — Dùng Application Load Balancer trước tầng ứng dụng; và dùng Amazon CloudFront với Lambda@Edge.

Vì sao đúng

Hai lựa chọn này bổ trợ nhau, mỗi cái lo một tầng của bài toán: | Thành phần | Việc | |---|---| | Application Load Balancer | định tuyến theo nội dung ở tầng 7, health check, kiểm tra được | | CloudFront + Lambda@Edge | cache ở biên và xử lý logic ngay tại điểm biên |

⚠ Điểm mấu chốt: Lambda@Edge chạy MÃ ở điểm biên, không phải ở Region:

Yêu cầu tới điểm biên gần người dùng
        ↓
    Lambda@Edge chạy ngay tại đó
        ↓
    Sửa header, viết lại URL, kiểm
      thực xác thực, A/B test
        ↓
    → phản hồi mà không phải đi tới
      origin

Bốn thời điểm gọi được Lambda@Edge:

Viewer Request  → sau khi CloudFront nhận
                  yêu cầu
        ↓
Origin Request  → trước khi gọi origin
                  (chỉ khi cache miss)
        ↓
Origin Response → sau khi origin trả lời
        ↓
Viewer Response → trước khi trả cho người
                  dùng

⚠ Và chọn sai thời điểm làm hỏng hiệu quả cache: | Thời điểm | Chạy khi nào | |---|---| | Viewer Request/Response | MỌI yêu cầu, kể cả cache hit | | Origin Request/Response | chỉ khi cache miss |

Đặt logic nặng ở Viewer Request
        ↓
    Chạy cả khi CloudFront đã có sẵn
      nội dung trong cache
        ↓
    Trả tiền và trả độ trễ cho mọi
      lượt truy cập
    → logic không phụ thuộc người
      dùng thì đặt ở Origin Request

Ví dụ viết lại URL ở Origin Request:

export const handler = async (event) => {
  const yeuCau = event.Records[0].cf.request;
  if (yeuCau.uri.endsWith('/')) {
    yeuCau.uri += 'index.html';
  }
  return yeuCau;
};

Ví dụ thêm header bảo mật ở Viewer Response:

export const handler = async (event) => {
  const phanHoi = event.Records[0].cf.response;
  phanHoi.headers['strict-transport-security'] = [{
    key: 'Strict-Transport-Security',
    value: 'max-age=31536000; includeSubDomains'}];
  return phanHoi;
};

⚠ Nhưng với việc chỉ sửa header thì CloudFront Functions rẻ hơn nhiều: | | CloudFront Functions | Lambda@Edge | |---|---|---| | Ngôn ngữ | JavaScript ES5 | Node.js, Python | | Thời gian chạy tối đa | 1 ms | 5 giây (viewer), 30 giây (origin) | | Bộ nhớ | 2 MB | tới 10 GB | | Gọi mạng | KHÔNG | có | | Thời điểm | chỉ viewer | cả bốn | | Giá | rẻ hơn ~1/6 | |

Chỉ sửa header hoặc chuyển hướng
        ↓
    → CloudFront Functions
        ↓
    Cần gọi API, đọc S3, xử lý phức
      tạp
    → Lambda@Edge

⚠ Và Application Load Balancer là lựa chọn đúng ở tầng ứng dụng:

Định tuyến theo đường dẫn, host,
  header, query string
        ↓
    Health check ở tầng HTTP
        ↓
    Tích hợp WAF, Cognito, ACM
        ↓
    Đích là EC2, IP, Lambda, container

Định tuyến theo đường dẫn:

aws elbv2 create-rule \
  --listener-arn <arn-listener> --priority 10 \
  --conditions Field=path-pattern,Values='/api/*' \
  --actions Type=forward,TargetGroupArn=<arn-api>

⚠ Và ALB xác thực được người dùng trước khi tới ứng dụng:

--actions '[{
  "Type": "authenticate-cognito",
  "Order": 1,
  "AuthenticateCognitoConfig": {
    "UserPoolArn": "<arn-user-pool>",
    "UserPoolClientId": "<client-id>",
    "UserPoolDomain": "<domain>"}},
  {"Type": "forward", "Order": 2,
   "TargetGroupArn": "<arn-tg>"}]'

⚠ Và vì sao Network Load Balancer không phải lựa chọn ở đây:

NLB làm việc ở tầng 4
        ↓
    Không đọc được đường dẫn HTTP hay
      header
        ↓
    Không định tuyến theo nội dung
        ↓
    Hợp khi cần IP tĩnh, TCP/UDP,
      hoặc độ trễ cực thấp

⚠ Và Classic Load Balancer là thế hệ cũ:

Không có định tuyến theo nội dung
        ↓
    Không tích hợp WAF
        ↓
    AWS khuyến nghị chuyển sang ALB
      hoặc NLB
    → không chọn cho thiết kế mới

Kiến trúc kết hợp:

Người dùng
    ↓
CloudFront (cache tĩnh, Lambda@Edge)
    ↓  (cache miss)
Application Load Balancer
    ↓  (định tuyến theo đường dẫn)
Target group EC2 / ECS / Lambda

⚠ Và nên chặn đường vào ALB trực tiếp:

Người ta tìm ra DNS của ALB
        ↓
    Gọi thẳng, bỏ qua CloudFront và
      WAF
        ↓
    Bịt bằng:
      - custom header bí mật
      - hoặc VPC origin (mới hơn)

Kiểm header bí mật ở ALB:

aws elbv2 create-rule --listener-arn <arn> --priority 1 \
  --conditions '[{"Field": "http-header",
    "HttpHeaderConfig": {"HttpHeaderName": "X-Origin-Secret",
      "Values": ["<chuoi-bi-mat>"]}}]' \
  --actions Type=forward,TargetGroupArn=<arn-tg>
Và luật mặc định trả 403
        ↓
    Mọi yêu cầu không qua CloudFront
      bị chặn

⚠ Và VPC origin bỏ hẳn nhu cầu để ALB công khai:

CloudFront VPC origin kết nối riêng
  tới ALB nội bộ
        ↓
    ALB không có địa chỉ công khai
        ↓
    Không có đường nào đi vòng
    → chặt hơn header bí mật

Ba lợi ích của kiến trúc này: | Lợi ích | Chi tiết | |---|---| | Nội dung tĩnh phục vụ từ biên | | | Logic đơn giản chạy ngay ở biên | | | Định tuyến tầng 7 linh hoạt ở ALB | |

⚠ Và Lambda@Edge có giới hạn phải biết: | Giới hạn | Giá trị | |---|---| | Không dùng được biến môi trường | | | Không đặt trong VPC được | | | Chỉ triển khai từ us-east-1 | | | Kích thước gói: 1 MB (viewer), 50 MB (origin) | | | Không có /tmp lớn như Lambda thường | |

⚠ Và không dùng được biến môi trường là hạn chế thật:

Cấu hình phải nhúng thẳng vào mã
        ↓
    Hoặc đọc từ nguồn ngoài mỗi lần
      chạy
        ↓
    Đổi cấu hình = triển khai lại
      phiên bản mới
    → và chờ nhân bản ra mọi điểm
      biên

⚠ Và triển khai Lambda@Edge chậm:

Publish phiên bản mới
        ↓
    Gắn vào distribution
        ↓
    CloudFront nhân bản mã ra toàn
      cầu
        ↓
    Mất vài phút
    → không hợp với việc đổi cấu hình
      thường xuyên

⚠ Và xoá Lambda@Edge cũng chậm:

Gỡ khỏi distribution
        ↓
    Vẫn không xoá hàm được ngay
        ↓
    Phải chờ CloudFront dọn bản sao
      ở mọi điểm biên
    → có thể vài giờ

⚠ Và log của Lambda@Edge nằm ở Region gần điểm biên:

Người dùng ở Singapore
        ↓
    Log ghi vào CloudWatch của
      `ap-southeast-1`
        ↓
    Không nằm ở `us-east-1` nơi triển
      khai
    → phải tìm log ở nhiều Region

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

  • **Dùng Network Load Balancer — đây là phương án gần nhất và NLB thật sự cho thông lượng cao và độ trễ thấp, nhưng nó làm việc ở tầng 4 nên không đọc được đường dẫn, header hay cookie để định tuyến theo nội dung.
  • **Dùng Classic Load Balancer — thế hệ cũ, không có định tuyến theo nội dung, không tích hợp WAF; AWS khuyến nghị chuyển sang ALB hoặc NLB.
  • **Chỉ dùng CloudFront không kèm Lambda@Edge — chỉ cache tĩnh, không xử lý được logic tại biên như đề yêu cầu.

Ghi nhớ

⚠ Bốn lựa chọn cân bằng tải — bảng phải thuộc: | Loại | Tầng | Chọn khi | |---|---|---| | ALB | 7 | định tuyến theo nội dung, HTTP/HTTPS | | NLB | 4 | IP tĩnh, TCP/UDP, độ trễ cực thấp | | GWLB | 3 | chèn thiết bị bảo mật | | CLB | cũ | không chọn cho thiết kế mới |

Từ khoá nhận diện:

"logic at the edge" → Lambda@Edge hoặc CloudFront Functions "route by URL path" → ALB "static IP, millions of requests" → NLB "header rewrite only" → CloudFront Functions, rẻ hơn

Ba lưu ý về Lambda@Edge: | Lưu ý | Chi tiết | |---|---| | Triển khai từ us-east-1 | | | Không dùng biến môi trường | | | Không đặt trong VPC | |

Ba lưu ý về thời điểm gọi: | Thời điểm | Chạy khi | |---|---| | Viewer Request/Response | mọi yêu cầu | | Origin Request/Response | chỉ cache miss | | Chọn Origin nếu logic không phụ thuộc người dùng | |

Ba lưu ý về CloudFront Functions: | Lưu ý | Chi tiết | |---|---| | Chỉ ES5, chỉ 1 ms | | | Không gọi mạng, không đọc thân yêu cầu | | | Rẻ hơn Lambda@Edge nhiều lần | |

Ba lưu ý về ALB: | Lưu ý | Chi tiết | |---|---| | Định tuyến theo path, host, header, query, IP nguồn | | | Tích hợp Cognito và OIDC | | | Đích có thể là Lambda | |

Ba lưu ý về bảo vệ origin: | Cách | Chi tiết | |---|---| | Custom header bí mật | ALB kiểm | | VPC origin | ALB nội bộ, chặt nhất | | WAF trên CloudFront | chặn ở biên |

Ba lưu ý về giám sát: | Lưu ý | Chi tiết | |---|---| | Log Lambda@Edge nằm ở Region gần biên | | | LambdaExecutionError trong CloudWatch của CloudFront | | | Bật standard log của CloudFront | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gọi thẳng DNS của ALB — phải bị 403 | | | Xem header do Lambda@Edge thêm | | | Đo tỷ lệ cache hit trước và sau | |

Và một lời khuyên: hãy cân nhắc CloudFront Functions trước khi chọn Lambda@Edge. Phần lớn logic ở biên trong thực tế chỉ là viết lại URL, chuyển hướng hoặc thêm header — và với những việc đó thì Functions chạy nhanh hơn, rẻ hơn nhiều lần, lại triển khai trong vài giây thay vì vài phút.

Câu 442 Accelerate Workload Migration and Modernization

A research agency processes multiple compressed (gzip) CSV files containing data about contagious diseases for the past month aggregated from healthcare facilities. The files are about ~200 GB and are stored in Amazon S3 Glacier Flexible Storage Class. As per the reporting guidelines, the agency needs to query a portion of this data to prepare a report every month.

Which of the following is the most cost-effective way to query this data?

  1. A

    Ingest the data into Amazon S3 and query it with Amazon Redshift Spectrum

  2. B

    Leverage Amazon Glacier Select to query data from S3 Glacier directly

  3. C

    Ingest the data into Amazon S3 from S3 Glacier and query the required data with Amazon Athena

  4. D

    Ingest the data into Amazon S3 from S3 Glacier and query the required data with Amazon S3 Select

Xem giải thích

Đáp án

**D — Nạp dữ liệu từ Amazon S3 Glacier vào Amazon S3, rồi dùng Amazon S3 Select để truy vấn.

Vì sao đúng

Đề mô tả dữ liệu đang nằm ở kho lưu trữ dài hạn và cần chạy truy vấn trên đó. Trình tự bắt buộc là:

Dữ liệu ở Glacier
        ↓
    Khôi phục (restore) về S3
        ↓
    Truy vấn bằng công cụ chạy trên
      S3

⚠ Điểm mấu chốt: không truy vấn trực tiếp trên object đã lưu trữ:

Object ở lớp Glacier Flexible
  Retrieval hoặc Deep Archive
        ↓
    KHÔNG đọc được bằng `GetObject`
      thông thường
        ↓
    Phải `RestoreObject` trước
        ↓
    → tạo bản sao tạm ở lớp truy cập
      được

Khôi phục object:

aws s3api restore-object \
  --bucket kho-luu-tru --key du-lieu/2024/log.gz \
  --restore-request '{"Days": 7,
    "GlacierJobParameters": {"Tier": "Standard"}}'

Ba mức khôi phục của Glacier Flexible Retrieval: | Mức | Thời gian | Chi phí | |---|---|---| | Expedited | 1-5 phút | cao nhất | | Standard | 3-5 giờ | trung bình | | Bulk | 5-12 giờ | rẻ nhất, miễn phí lấy |

Deep Archive: | Mức | Thời gian | |---|---| | Standard | trong 12 giờ | | Bulk | trong 48 giờ |

⚠ Và bản khôi phục là BẢN SAO TẠM, không đổi lớp gốc:

`Days: 7` → bản sao tồn tại 7 ngày
        ↓
    Object gốc vẫn ở Glacier
        ↓
    Trả tiền cho CẢ HAI trong thời
      gian đó
        ↓
    Hết hạn → bản sao biến mất

Kiểm tra trạng thái khôi phục:

aws s3api head-object --bucket kho-luu-tru \
  --key du-lieu/2024/log.gz \
  --query 'Restore'
'ongoing-request="true"'  → đang khôi phục
'ongoing-request="false", expiry-date="..."'
                          → đã sẵn sàng

⚠ Và Glacier Instant Retrieval là ngoại lệ:

Glacier Instant Retrieval đọc được
  NGAY bằng `GetObject`
        ↓
    Không cần khôi phục
        ↓
    Rẻ hơn Standard-IA khoảng 68%
        ↓
    Đổi lại: phí lấy dữ liệu cao hơn
    → hợp với dữ liệu truy cập quý
      một lần

Bảng ba lớp Glacier: | Lớp | Truy cập | Tối thiểu lưu | |---|---|---| | Glacier Instant Retrieval | tức thì | 90 ngày | | Glacier Flexible Retrieval | phút tới giờ | 90 ngày | | Glacier Deep Archive | giờ | 180 ngày |

⚠ Và phí xoá sớm là chi tiết hay bị bỏ qua:

Đưa object vào Deep Archive
        ↓
    Xoá sau 30 ngày
        ↓
    Vẫn tính tiền đủ 180 ngày
    → di chuyển dữ liệu ngắn hạn vào
      Deep Archive là lãng phí

⚠ Và có thể tự động khôi phục theo lô bằng S3 Batch Operations:

aws s3control create-job --account-id 111122223333 \
  --operation '{"S3InitiateRestoreObject": {
    "ExpirationInDays": 7, "GlacierJobTier": "BULK"}}' \
  --manifest file://manifest.json \
  --report file://report.json \
  --role-arn <arn-role> --priority 10
Hàng triệu object cần khôi phục
        ↓
    Gọi `RestoreObject` từng cái là
      không khả thi
    → Batch Operations làm theo lô

Ghi nhớ về chất lượng câu hỏi

⚠ S3 Select đã đóng với khách hàng mới từ tháng 7/2024:

AWS ngừng nhận khách mới cho S3
  Select
        ↓
    Khách đang dùng vẫn chạy tiếp
        ↓
    Tài khoản mới không bật được
        ↓
    → phần "dùng S3 Select" của đáp
      án này đã lỗi thời

⚠ Và Glacier Select cũng đã ngừng:

Trước đây chạy được truy vấn SQL
  THẲNG trên object Glacier
        ↓
    Không cần khôi phục về S3
        ↓
    Tính năng này cũng đã ngừng
    → nên trình tự "khôi phục rồi
      truy vấn" giờ là con đường duy
      nhất

Cách làm hiện đại — Athena:

CREATE EXTERNAL TABLE nhat_ky (
  thoi_gian string, ma_nguoi_dung string, hanh_dong string)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://kho-luu-tru/du-lieu/';
aws athena start-query-execution \
  --query-string "SELECT * FROM nhat_ky WHERE hanh_dong='loi'" \
  --result-configuration OutputLocation=s3://ket-qua/

⚠ Và Athena bỏ qua object chưa khôi phục:

Athena quét tiền tố có object Glacier
        ↓
    Object chưa khôi phục bị BỎ QUA
      âm thầm
        ↓
    Truy vấn chạy xong, trả kết quả
      THIẾU
    → không có lỗi nào
Đây là cái bẫy nguy hiểm nhất:
    kết quả sai mà trông như đúng
        ↓
    Luôn khôi phục hết trước khi truy
      vấn

⚠ Và ba khác biệt giữa S3 Select và Athena: | | S3 Select | Athena | |---|---|---| | Phạm vi | MỘT object | nhiều object, cả tiền tố | | JOIN, GROUP BY | không | có | | Trạng thái | đóng với khách mới | đang phát triển |

Ba lợi ích của cách làm này: | Lợi ích | Chi tiết | |---|---| | Dữ liệu vẫn nằm ở kho rẻ nhất | | | Chỉ khôi phục phần cần dùng | | | Không phải dựng CSDL riêng | |

⚠ Và nên nghĩ tới việc chuyển sang định dạng cột:

Dữ liệu ở dạng CSV hoặc JSON
        ↓
    Athena quét toàn bộ tệp
        ↓
    Chuyển sang Parquet
    → giảm dữ liệu quét 90%+
    → và Athena tính tiền theo lượng
      quét
CREATE TABLE nhat_ky_parquet
WITH (format = 'PARQUET',
      partitioned_by = ARRAY['nam','thang'],
      external_location = 's3://kho/parquet/')
AS SELECT * FROM nhat_ky;

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

  • **Truy vấn thẳng bằng Amazon Athena trên Glacier — đây là phương án gần nhất và nghe rất hợp lý, nhưng Athena bỏ qua object ở lớp lưu trữ chưa khôi phục và trả kết quả thiếu mà không báo lỗi.
  • **Nạp dữ liệu vào Amazon Redshift rồi truy vấn — đòi dựng cụm, thiết kế lược đồ và nạp toàn bộ dữ liệu; quá nặng cho việc truy vấn dữ liệu lưu trữ thỉnh thoảng.
  • **Dùng Amazon RDS — CSDL quan hệ không phải nơi để truy vấn dữ liệu lưu trữ trên object storage.

Ghi nhớ

⚠ Bốn bước truy vấn dữ liệu lưu trữ — bảng phải thuộc: | Bước | Việc | |---|---| | 1. RestoreObject | chọn mức theo yêu cầu thời gian | | 2. Chờ hoàn tất | kiểm bằng head-object | | 3. Truy vấn bằng Athena | hoặc công cụ khác trên S3 | | 4. Bản sao tự hết hạn | theo Days đã khai |

Từ khoá nhận diện:

"query archived data" → restore trước, truy vấn sau "instant access to archive" → Glacier Instant Retrieval "cheapest archive" → Deep Archive "query across many objects" → Athena, không phải S3 Select

Ba lưu ý về khôi phục: | Lưu ý | Chi tiết | |---|---| | Bản khôi phục là bản sao tạm | | | Trả tiền cho cả bản gốc và bản sao | | | RestoreObject lại được để gia hạn | |

Ba lưu ý về Athena: | Lưu ý | Chi tiết | |---|---| | Bỏ qua object Glacier chưa khôi phục — âm thầm | | | Tính tiền theo lượng dữ liệu quét | | | Parquet và phân vùng giảm chi phí rất nhiều | |

Ba lưu ý về phí tối thiểu: | Lớp | Tối thiểu | |---|---| | Standard-IA, One Zone-IA | 30 ngày | | Glacier Instant, Flexible | 90 ngày | | Deep Archive | 180 ngày |

Ba lưu ý về S3 Batch Operations: | Lưu ý | Chi tiết | |---|---| | Khôi phục hàng loạt theo manifest | | | Dùng S3 Inventory làm manifest | | | Có báo cáo kết quả | |

Ba lưu ý về Intelligent-Tiering: | Lưu ý | Chi tiết | |---|---| | Tự chuyển tầng theo mẫu truy cập | | | Không có phí lấy dữ liệu | | | Tầng Archive Access vẫn cần khôi phục | |

Ba lưu ý về chi phí truy vấn: | Cách giảm | Chi tiết | |---|---| | Nén dữ liệu | | | Định dạng cột Parquet, ORC | | | Phân vùng theo ngày | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Kiểm mọi object đã khôi phục xong | | | So số dòng kết quả với kỳ vọng | | | Xem lượng dữ liệu Athena đã quét | |

Và một lời khuyên: hãy xác nhận mọi object đã khôi phục xong trước khi chạy truy vấn Athena trên một tiền tố có dữ liệu lưu trữ. Athena không báo lỗi khi gặp object chưa khôi phục — nó lặng lẽ bỏ qua và trả về một kết quả thiếu trông hoàn toàn bình thường, và đó là kiểu sai khó phát hiện nhất trong phân tích dữ liệu.

Câu 443 Accelerate Workload Migration and Modernization

A solutions architect at a company is managing the migration of the company's IT infrastructure from its on-premises data center to AWS Cloud. The architect needs to automate VPC creation to enforce the company's network and security standards which mandate that each application is isolated in its own VPC. The solution must also ensure that the CIDR range used in each VPC is unique.

Which of the following options would you recommend to address these requirements?

  1. A

    Deploy the VPC infrastructure using AWS OpsWorks and leverage a custom resource to request a unique CIDR range from an external IP address management (IPAM) service

  2. B

    Deploy the VPC infrastructure using AWS CloudFormation and leverage a custom resource to request a unique CIDR range from an external IP address management (IPAM) service

  3. C

    Deploy the VPC infrastructure using AWS CloudFormation and use the intrinsic function Fn::Cidr to request a unique CIDR range

  4. D

    Set up the VPCs using AWS CLI and use the dry-run flag to validate if the requested CIDR range is in use

Xem giải thích

Đáp án

**B — Dùng CloudFormation với một custom resource gọi ra một dịch vụ IPAM bên ngoài để xin một dải CIDR duy nhất, rồi dùng dải đó tạo VPC.

Vì sao đúng

Đề nêu bài toán: nhiều đội tự dựng VPC bằng mẫu chung, và không được trùng dải CIDR vì các VPC sẽ phải nối với nhau. Chỉ có một cách giải quyết đúng bản chất:

Phải có MỘT nguồn duy nhất giữ sổ
  cấp phát
        ↓
    Mỗi lần dựng VPC → hỏi nguồn đó
        ↓
    Nguồn đó cấp dải chưa dùng và ghi
      lại
        ↓
    → không thể trùng

⚠ Điểm mấu chốt: CloudFormation không tự biết dải nào đã dùng:

Mẫu CloudFormation là tệp tĩnh
        ↓
    Chạy hai lần → cùng ra một CIDR
        ↓
    Trừ khi có tham số đầu vào khác
        ↓
    Và người nhập tham số cũng không
      biết ai đã lấy dải nào

⚠ Và custom resource là cơ chế để CloudFormation gọi ra ngoài:

CloudFormation gặp custom resource
        ↓
    Gửi sự kiện tới Lambda hoặc SNS
        ↓
    Mã đó gọi IPAM, xin dải, ghi sổ
        ↓
    Trả về CIDR qua `Data`
        ↓
    Mẫu dùng `!GetAtt` để lấy ra

Khai custom resource:

Resources:
  XinDaiCidr:
    Type: Custom::CapPhatCidr
    Properties:
      ServiceToken: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:cap-phat-cidr
      KichThuoc: 24
      MoiTruong: san-xuat

  MangRieng:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !GetAtt XinDaiCidr.Cidr
      EnableDnsHostnames: true
      EnableDnsSupport: true

⚠ Và custom resource PHẢI gửi tín hiệu về, nếu không stack treo:

import json, urllib.request

def gui_ket_qua(su_kien, trang_thai, du_lieu):
    than = json.dumps({
        'Status': trang_thai,
        'PhysicalResourceId': su_kien.get('PhysicalResourceId', 'cidr'),
        'StackId': su_kien['StackId'],
        'RequestId': su_kien['RequestId'],
        'LogicalResourceId': su_kien['LogicalResourceId'],
        'Data': du_lieu}).encode()
    yc = urllib.request.Request(su_kien['ResponseURL'],
                                data=than, method='PUT')
    urllib.request.urlopen(yc)

⚠ Và đây là bẫy kinh điển của custom resource:

Lambda ném ngoại lệ trước khi gửi
  tín hiệu
        ↓
    CloudFormation không nhận được gì
        ↓
    Chờ tới khi hết giờ — MỘT TIẾNG
        ↓
    → luôn bọc toàn bộ trong try/except
      và gửi FAILED trong except
def handler(su_kien, ngu_canh):
    try:
        if su_kien['RequestType'] == 'Delete':
            tra_lai_dai(su_kien['PhysicalResourceId'])
            return gui_ket_qua(su_kien, 'SUCCESS', {})
        dai = xin_dai(su_kien['ResourceProperties'])
        gui_ket_qua(su_kien, 'SUCCESS', {'Cidr': dai})
    except Exception as loi:
        gui_ket_qua(su_kien, 'FAILED', {'Ly do': str(loi)})

⚠ Và phải xử lý cả Delete để trả dải về sổ:

Xoá stack
        ↓
    VPC bị xoá
        ↓
    Nhưng dải CIDR vẫn ghi là "đã cấp"
      trong sổ
        ↓
    Sau vài chục lần dựng-xoá → hết
      dải
    → xử lý `Delete` là bắt buộc

⚠ Và vì sao Fn::Cidr không giải quyết được:

`Fn::Cidr` chia MỘT dải cha thành
  nhiều dải con
        ↓
    Trong PHẠM VI MỘT stack
        ↓
    Hai stack khác nhau cùng nhận dải
      cha giống nhau
    → cùng cho ra dải con giống nhau
!Select [0, !Cidr [!Ref DaiCha, 4, 8]]
Hữu ích để chia subnet TRONG một VPC
        ↓
    Không hữu ích để tránh trùng GIỮA
      các VPC

⚠ Và tham số đầu vào cũng không giải quyết được:

Bắt người dùng nhập CIDR khi tạo
  stack
        ↓
    Họ tra bảng tính đâu đó
        ↓
    Hai đội cùng tra một bảng cũ
        ↓
    Hoặc quên cập nhật sau khi lấy
    → đây chính là vấn đề đề bài mô tả

Ghi nhớ về chất lượng câu hỏi

⚠ Câu này viết trước khi AWS có IPAM riêng:

Amazon VPC IP Address Manager ra mắt
  tháng 12/2021
        ↓
    Đúng là dịch vụ quản lý cấp phát
      CIDR
        ↓
    Có tích hợp CloudFormation gốc
        ↓
    → không cần custom resource nữa

Cách làm hiện đại — IPAM gốc của AWS:

Resources:
  MangRieng:
    Type: AWS::EC2::VPC
    Properties:
      Ipv4IpamPoolId: ipam-pool-0abc123
      Ipv4NetmaskLength: 24
      EnableDnsHostnames: true
CloudFormation tự xin dải từ pool
        ↓
    IPAM đảm bảo không trùng
        ↓
    Xoá stack → dải tự trả về pool
    → không cần viết một dòng mã nào

Dựng IPAM:

aws ec2 create-ipam \
  --operating-regions RegionName=ap-southeast-1

aws ec2 create-ipam-pool \
  --ipam-scope-id ipam-scope-abc \
  --address-family ipv4 \
  --auto-import \
  --allocation-min-netmask-length 24 \
  --allocation-max-netmask-length 28

aws ec2 provision-ipam-pool-cidr \
  --ipam-pool-id ipam-pool-abc \
  --cidr 10.0.0.0/8

⚠ Và IPAM có cấu trúc phân cấp:

IPAM
  └─ Scope (public / private)
       └─ Pool gốc (10.0.0.0/8)
            └─ Pool theo Region
                 └─ Pool theo môi trường
                      └─ Cấp phát cho VPC
Chia theo Region và môi trường
        ↓
    Mỗi đội chỉ xin từ pool của mình
        ↓
    Và IPAM giám sát mức sử dụng

⚠ Và IPAM còn phát hiện trùng lặp có sẵn:

aws ec2 get-ipam-discovered-resource-cidrs \
  --ipam-resource-discovery-id ipam-res-disco-abc \
  --resource-region ap-southeast-1
Quét toàn tổ chức
        ↓
    Tìm VPC có CIDR chồng lấn
        ↓
    Rất hữu ích khi dọn dẹp môi trường
      đã lộn xộn sẵn

⚠ Và trùng CIDR gây hậu quả gì — cần hiểu rõ:

Hai VPC cùng 10.0.0.0/16
        ↓
    VPC peering: KHÔNG tạo được
        ↓
    Transit Gateway: gắn được nhưng
      định tuyến sai
        ↓
    Chỉ chữa được bằng NAT hoặc
      PrivateLink
    → hoặc đánh số lại toàn bộ VPC

⚠ Và đánh số lại một VPC đang chạy là việc rất nặng:

Không đổi được CIDR chính của VPC
        ↓
    Chỉ thêm được CIDR phụ
        ↓
    Muốn đổi hẳn → dựng VPC mới và
      di chuyển mọi thứ
    → đó là lý do phải chống trùng
      NGAY TỪ ĐẦU

Ba lợi ích của việc cấp phát tập trung: | Lợi ích | Chi tiết | |---|---| | Không bao giờ trùng | | | Đội tự phục vụ, không chờ mạng duyệt | | | Có sổ theo dõi mức sử dụng | |

⚠ Và nên chừa dải dự phòng cho VPC:

Cấp /24 cho mỗi VPC
        ↓
    Sau này cần thêm subnet
        ↓
    Thêm CIDR phụ được, nhưng dải kề
      có thể đã bị cấp cho người khác
    → cấp /20 và chỉ dùng /24 đầu
      là cách phòng xa

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

  • **Dùng Fn::Cidr trong mẫu để tự tính dải — đây là phương án gần nhất và Fn::Cidr thật sự sinh ra các dải con hợp lệ, nhưng nó chỉ chia trong phạm vi một stack; hai stack chạy độc lập với cùng dải cha sẽ cho ra cùng kết quả.
  • **Bắt người dùng nhập CIDR làm tham số khi tạo stack — chính là cách làm thủ công đang gây trùng lặp mà đề bài mô tả.
  • **Dùng StackSets triển khai mẫu ra nhiều tài khoản — StackSets lo việc phân phối mẫu, không lo việc mỗi bản triển khai nhận dải khác nhau.

Ghi nhớ

⚠ Bốn cách cấp phát CIDR — bảng phải thuộc: | Cách | Chống trùng | |---|---| | VPC IPAM (hiện đại) | có, tự động | | Custom resource gọi IPAM ngoài | có, phải tự viết | | Fn::Cidr | chỉ trong một stack | | Tham số nhập tay | không |

Từ khoá nhận diện:

"non-overlapping CIDR across teams" → IPAM "CloudFormation must call an external service" → custom resource "divide a VPC into subnets" → Fn::Cidr "deploy same template to many accounts" → StackSets

Ba lưu ý về custom resource: | Lưu ý | Chi tiết | |---|---| | PHẢI gửi tín hiệu về ResponseURL | | | Xử lý cả Create, Update, Delete | | | Bọc try/except, gửi FAILED khi lỗi | |

Ba lưu ý về IPAM: | Lưu ý | Chi tiết | |---|---| | Cấu trúc pool phân cấp | | | Tích hợp CloudFormation gốc | | | Phát hiện CIDR chồng lấn có sẵn | |

Ba lưu ý về CIDR trùng: | Hậu quả | Chi tiết | |---|---| | VPC peering không tạo được | | | Transit Gateway định tuyến sai | | | Chỉ chữa bằng NAT hoặc PrivateLink | |

Ba lưu ý về kích thước VPC: | Lưu ý | Chi tiết | |---|---| | CIDR chính từ /16 tới /28 | | | Thêm được CIDR phụ, không đổi được cái chính | | | AWS giữ 5 địa chỉ mỗi subnet | |

Ba lưu ý về CloudFormation: | Lưu ý | Chi tiết | |---|---| | Mẫu là tĩnh, không có trạng thái toàn cục | | | Custom resource là cửa ra thế giới ngoài | | | Hết giờ chờ tín hiệu là một tiếng | |

Ba lưu ý về quản trị: | Lưu ý | Chi tiết | |---|---| | Chừa dải dự phòng cho mỗi VPC | | | Ghi sổ cả dải đã trả lại | | | Giám sát mức sử dụng pool | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Dựng hai stack liên tiếp, so CIDR | | | Xoá stack rồi kiểm dải đã trả về pool | | | Chạy get-ipam-discovered-resource-cidrs tìm chồng lấn | |

Và một lời khuyên: hãy dùng VPC IPAM thay vì tự viết custom resource nếu đang dựng mới hôm nay. IPAM ra đời sau khi câu hỏi này được viết và giải quyết đúng bài toán đó ở tầng dịch vụ — bao gồm cả việc trả dải về pool khi xoá stack, vốn là phần dễ quên nhất khi tự viết.

Câu 444 Accelerate Workload Migration and Modernization

A media streaming service delivers billions of hours of content from Amazon S3 to customers around the world. Amazon S3 also serves as the data lake for its data analytics solution. The data lake has a staging zone where intermediary query results are kept only for 24 hours. These results are also heavily referenced by other parts of the analytics pipeline.

Which of the following is the MOST cost-effective solution to store this intermediary query data?

  1. A

    Store the intermediary query results in S3 Glacier Instant Retrieval storage class

  2. B

    Store the intermediary query results in S3 One Zone-Infrequent Access storage class

  3. C

    Store the intermediary query results in S3 Standard-Infrequent Access storage class

  4. D

    Store the intermediary query results in S3 Standard storage class

Xem giải thích

Đáp án

**D — Dùng S3 Standard để lưu kết quả truy vấn trung gian.

Vì sao đúng

Đề nêu đúng một đặc điểm quyết định: kết quả trung gian chỉ tồn tại 24 giờ rồi bị xoá. Với vòng đời ngắn như vậy, mọi lớp lưu trữ rẻ hơn đều đắt hơn vì phí tối thiểu.

⚠ Điểm mấu chốt: các lớp rẻ tính tiền theo thời gian TỐI THIỂU: | Lớp | Tối thiểu tính tiền | |---|---| | S3 Standard | không có | | Standard-IA | 30 ngày | | One Zone-IA | 30 ngày | | Glacier Instant Retrieval | 90 ngày | | Glacier Flexible Retrieval | 90 ngày | | Deep Archive | 180 ngày |

Object sống 1 ngày ở Standard-IA
        ↓
    Vẫn tính tiền đủ 30 ngày
        ↓
    → đắt gấp 30 lần thời gian thật
      dùng

Tính cụ thể cho 1 TB kết quả trung gian mỗi ngày: | Lớp | Giá lưu | Thực trả cho 1 ngày | |---|---|---| | S3 Standard | 0,023 USD/GB/tháng | ~0,77 USD | | Standard-IA | 0,0125 USD/GB/tháng | ~12,50 USD (30 ngày tối thiểu) | | One Zone-IA | 0,01 USD/GB/tháng | ~10 USD |

Standard-IA rẻ hơn 46% mỗi GB-tháng
        ↓
    Nhưng phải trả đủ 30 ngày
        ↓
    → đắt hơn Standard 16 lần cho dữ
      liệu sống 1 ngày

⚠ Và còn phí lấy dữ liệu cộng thêm: | Lớp | Phí lấy | |---|---| | S3 Standard | không có | | Standard-IA | 0,01 USD/GB | | One Zone-IA | 0,01 USD/GB | | Glacier Instant | 0,03 USD/GB |

Kết quả trung gian được ĐỌC LẠI
        ↓
    Đó là mục đích tồn tại của nó
        ↓
    Phí lấy 0,01 USD/GB cộng vào
    → càng làm IA đắt hơn nữa

⚠ Và các lớp Glacier còn không dùng được về mặt chức năng:

Glacier Flexible Retrieval hoặc
  Deep Archive
        ↓
    Phải khôi phục trước khi đọc
        ↓
    Mất từ vài phút tới 48 giờ
        ↓
    Kết quả trung gian cần đọc NGAY
    → không dùng được

⚠ Và phí chuyển lớp cũng đáng kể:

Chuyển sang IA: 0,01 USD mỗi 1.000
  object
        ↓
    Một truy vấn Athena sinh hàng
      nghìn tệp kết quả
        ↓
    Chuyển lớp rồi xoá sau một ngày
    → trả phí chuyển mà không hưởng
      lợi gì

⚠ Và Intelligent-Tiering cũng không hợp:

Intelligent-Tiering theo dõi mẫu
  truy cập
        ↓
    Chỉ chuyển sang tầng IA sau 30
      ngày không truy cập
        ↓
    Object sống 1 ngày không bao giờ
      tới ngưỡng đó
        ↓
    Nhưng vẫn trả phí giám sát
      0,0025 USD mỗi 1.000 object

Cấu hình đúng — Standard + luật vòng đời:

{"Rules": [{
  "ID": "xoa-ket-qua-trung-gian",
  "Filter": {"Prefix": "ket-qua-tam/"},
  "Status": "Enabled",
  "Expiration": {"Days": 1},
  "AbortIncompleteMultipartUpload": {
    "DaysAfterInitiation": 1}}]}
aws s3api put-bucket-lifecycle-configuration \
  --bucket kho-phan-tich \
  --lifecycle-configuration file://vong-doi.json

⚠ Và AbortIncompleteMultipartUpload là phần hay bị quên:

Tải lên nhiều phần thất bại giữa
  chừng
        ↓
    Các phần đã tải vẫn nằm lại
        ↓
    KHÔNG hiện trong danh sách object
        ↓
    Nhưng VẪN tính tiền
    → tích luỹ âm thầm hàng năm trời
aws s3api list-multipart-uploads --bucket kho-phan-tich

⚠ Và luật vòng đời chạy mỗi ngày một lần, không tức thì:

Đặt `Expiration: 1 ngày`
        ↓
    Object bị đánh dấu hết hạn sau
      24 giờ
        ↓
    Việc xoá thật diễn ra trong lần
      quét tiếp theo
        ↓
    Không tính tiền từ lúc đánh dấu
    → nhưng object có thể còn thấy
      được một lúc

⚠ Và với Athena thì có cấu hình riêng:

aws athena update-work-group --work-group phan-tich \
  --configuration-updates '{
    "ResultConfigurationUpdates": {
      "OutputLocation": "s3://kho-phan-tich/ket-qua-tam/"},
    "EnforceWorkGroupConfiguration": true}'
Bắt mọi truy vấn ghi vào đúng tiền
  tố
        ↓
    Luật vòng đời áp cho tiền tố đó
    → không sót kết quả nào

⚠ Và nếu quy trình chạy trong ngày thì có lựa chọn rẻ hơn nữa:

Kết quả chỉ dùng trong cùng một
  quy trình
        ↓
    Cân nhắc không ghi ra S3 chút nào
        ↓
    Giữ trong bộ nhớ hoặc đĩa tạm của
      cụm
    → nhưng mất khả năng thử lại khi
      hỏng

Ba lợi ích của S3 Standard ở đây: | Lợi ích | Chi tiết | |---|---| | Không có phí tối thiểu | | | Không có phí lấy dữ liệu | | | Đọc được tức thì | |

⚠ Và đây là một trong số ít trường hợp lớp ĐẮT NHẤT lại RẺ NHẤT:

Trực giác: chọn lớp giá thấp nhất
        ↓
    Nhưng giá mỗi GB-tháng chỉ là một
      phần
        ↓
    Chi phí thật = lưu trữ + tối thiểu
      + lấy dữ liệu + chuyển lớp + yêu
      cầu
    → với dữ liệu ngắn hạn, Standard
      thắng

⚠ Và ranh giới kinh tế nằm ở khoảng 30 ngày:

Dữ liệu sống dưới 30 ngày
        ↓
    → S3 Standard
        ↓
    Dữ liệu sống trên 30 ngày và ít
      đọc
    → Standard-IA trở đi

⚠ Và nên dùng Storage Lens để tìm chỗ chọn sai lớp:

aws s3control get-storage-lens-configuration \
  --account-id 111122223333 --config-id mac-dinh
Xem phân bố theo lớp và theo tuổi
  object
        ↓
    Tìm object IA bị xoá sớm
    → dấu hiệu đang trả phí tối thiểu
      vô ích

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

  • **Dùng S3 Standard-IA — đây là phương án gần nhất và giá mỗi GB-tháng thật sự thấp hơn 46%, nhưng phí tối thiểu 30 ngày khiến dữ liệu sống 1 ngày đắt hơn Standard khoảng 16 lần, chưa kể phí lấy dữ liệu 0,01 USD/GB.
  • **Dùng S3 One Zone-IA — cùng phí tối thiểu 30 ngày, lại còn giảm độ bền vì chỉ lưu ở một AZ.
  • **Dùng S3 Glacier — phải khôi phục trước khi đọc, không dùng được cho kết quả trung gian cần truy cập ngay.

Ghi nhớ

⚠ Bốn thành phần chi phí S3 — bảng phải thuộc: | Thành phần | Chi tiết | |---|---| | Lưu trữ mỗi GB-tháng | cái duy nhất người ta thường so | | Thời gian tối thiểu | 30/90/180 ngày | | Phí lấy dữ liệu | mỗi GB | | Phí yêu cầu và chuyển lớp | mỗi 1.000 object |

Từ khoá nhận diện:

"deleted after 24 hours" → S3 Standard "accessed once a quarter" → Standard-IA hoặc Glacier IR "unknown access pattern" → Intelligent-Tiering "compliance archive 7 years" → Deep Archive

Ba lưu ý về phí tối thiểu: | Lớp | Ngày | |---|---| | Standard-IA, One Zone-IA | 30 | | Glacier Instant, Flexible | 90 | | Deep Archive | 180 |

Ba lưu ý về luật vòng đời: | Lưu ý | Chi tiết | |---|---| | Chạy mỗi ngày một lần, không tức thì | | | Luôn thêm AbortIncompleteMultipartUpload | | | Lọc theo tiền tố hoặc thẻ | |

Ba lưu ý về Intelligent-Tiering: | Lưu ý | Chi tiết | |---|---| | Có phí giám sát mỗi object | | | Không hợp với object nhỏ hoặc ngắn hạn | | | Không có phí lấy dữ liệu | |

Ba lưu ý về Athena: | Lưu ý | Chi tiết | |---|---| | Đặt OutputLocation theo workgroup | | | Bắt buộc bằng EnforceWorkGroupConfiguration | | | Áp luật vòng đời cho tiền tố kết quả | |

Ba lưu ý về multipart upload: | Lưu ý | Chi tiết | |---|---| | Phần dở dang vẫn tính tiền | | | Không hiện trong list-objects | | | Kiểm bằng list-multipart-uploads | |

Ba công cụ phân tích chi phí: | Công cụ | Việc | |---|---| | S3 Storage Lens | phân bố theo lớp và tuổi | | S3 Inventory | danh sách object đầy đủ | | Cost Explorer theo usage type | tách phí tối thiểu ra |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Xem hoá đơn tách theo lớp lưu trữ | | | Kiểm có object IA nào bị xoá dưới 30 ngày | | | Chạy list-multipart-uploads tìm phần dở dang | |

Và một lời khuyên: hãy luôn kiểm tra vòng đời thật của dữ liệu trước khi chuyển sang lớp rẻ hơn. Chọn lớp lưu trữ theo giá niêm yết mỗi GB là cách chắc chắn nhất để làm hoá đơn tăng lên — với dữ liệu sống dưới 30 ngày thì lớp "đắt nhất" luôn là lớp rẻ nhất.

Câu 445 Continuous Improvement for Existing Solutions

You have hired a Cloud consulting agency, Example Corp, to monitor your AWS account and help optimize costs. To track daily spending, Example Corp needs access to your AWS resources, therefore, you allow Example Corp to assume an IAM role in your account. However, Example Corp also tracks spending for other customers, and there could be a configuration issue in the Example Corp environment that allows another customer to compel Example Corp to attempt to take an action in your AWS account, even though that customer should only be able to take the action in their account.

How will you mitigate the risk of such a cross-account access scenario?

  1. A

    Configure a workforce authentication using SAML 2.0 federation. Employees of Example Corp can access the needed AWS resources with this integration

  2. B

    Create an IAM role in your AWS account with a trust policy that trusts the Partner (Example Corp). Create a unique external ID value for Example Corp and include this external ID condition in the role’s trust policy. Share this unique ID with Example Corp

  3. C

    Create an IAM role in your AWS account with a trust policy that trusts the Partner (Example Corp). Take a unique external ID value from Example Corp and include this external ID condition in the role’s trust policy

  4. D

    Create an IAM role in your AWS account with a trust policy that trusts the Partner (Example Corp). Use the AWS account ID of Example Corp as the principal element of the trust policy that can assume the role

Xem giải thích

Đáp án

**C — Yêu cầu một giá trị external ID từ Example Corp và đưa giá trị đó vào trust policy của IAM role.

Vì sao đúng

Đây là mô hình chuẩn khi cho bên thứ ba truy cập tài khoản AWS của mình. External ID tồn tại để chống một lớp tấn công cụ thể: confused deputy.

⚠ Điểm mấu chốt: bên CUNG CẤP DỊCH VỤ sinh ra external ID, không phải bạn:

Example Corp cấp cho mỗi khách hàng
  một external ID riêng
        ↓
    Bạn xin giá trị đó từ họ
        ↓
    Đưa vào trust policy của role
        ↓
    → Example Corp phải gửi đúng giá
      trị đó khi giả nhận vai trò

Trust policy đúng:

{"Version": "2012-10-17",
 "Statement": [{
   "Effect": "Allow",
   "Principal": {"AWS": "arn:aws:iam::999988887777:root"},
   "Action": "sts:AssumeRole",
   "Condition": {"StringEquals": {
     "sts:ExternalId": "khach-hang-abc-12345"}}}]}

⚠ Và đây là kịch bản confused deputy mà nó ngăn chặn:

Example Corp phục vụ nhiều khách hàng
        ↓
    Mọi khách đều tin cùng một tài
      khoản của Example Corp
        ↓
    Kẻ xấu cũng là khách hàng của
      Example Corp
        ↓
    Hắn khai ARN role CỦA BẠN vào cấu
      hình của hắn
Không có external ID:
        ↓
    Example Corp giả nhận role của bạn
        ↓
    Nó tin rằng đang phục vụ kẻ xấu
        ↓
    Nhưng thao tác trên tài khoản CỦA
      BẠN
    → dữ liệu của bạn lộ cho kẻ xấu
Có external ID:
        ↓
    Kẻ xấu không biết external ID của
      bạn
        ↓
    Example Corp gửi external ID của
      HẮN
        ↓
    Không khớp điều kiện trong trust
      policy
    → `AccessDenied`

⚠ Và "confused deputy" nghĩa là bên trung gian bị lợi dụng:

Example Corp là "deputy" — bên có
  quyền
        ↓
    Nó bị làm cho "confused" — nhầm
      lẫn về việc đang hành động thay
      ai
        ↓
    Chính nó không có ác ý
    → nhưng quyền của nó bị dùng sai

⚠ Và external ID KHÔNG phải bí mật:

Nó không phải mật khẩu
        ↓
    Nó chỉ cần KHÓ ĐOÁN với khách
      hàng khác của cùng nhà cung cấp
        ↓
    Rò rỉ external ID không đủ để
      truy cập
    → vì kẻ tấn công vẫn phải là
      Example Corp

⚠ Và vì thế trách nhiệm sinh giá trị thuộc về nhà cung cấp:

Nếu KHÁCH tự chọn external ID
        ↓
    Hai khách có thể chọn trùng
        ↓
    Hoặc kẻ xấu đoán được giá trị đơn
      giản
        ↓
    → nhà cung cấp sinh giá trị duy
      nhất và không đoán được

⚠ Và vì sao phương án dùng người dùng IAM là sai:

Tạo IAM user cho Example Corp
        ↓
    Cấp access key dài hạn
        ↓
    Khoá đó không tự hết hạn
        ↓
    Phải xoay vòng thủ công
        ↓
    Và nếu Example Corp bị xâm nhập
    → khoá của bạn nằm trong tay kẻ
      tấn công vô thời hạn

Bảng so sánh: | | IAM user + access key | Role + external ID | |---|---|---| | Thời hạn | vĩnh viễn | tối đa 12 giờ | | Xoay vòng | thủ công | tự động mỗi lần | | Thu hồi | xoá khoá | sửa trust policy | | Chống confused deputy | không áp dụng | có | | Khuyến nghị của AWS | không | có |

⚠ Và vì sao MFA không phải câu trả lời ở đây:

MFA đòi con người bấm mã
        ↓
    Example Corp là hệ thống tự động
        ↓
    Không có ai ngồi nhập mã mỗi lần
        ↓
    MFA hợp cho người dùng, không hợp
      cho truy cập giữa các hệ thống

⚠ Và giới hạn theo IP nguồn cũng không đủ:

`aws:SourceIp` giới hạn dải IP
        ↓
    Example Corp chạy trên AWS
        ↓
    IP thay đổi liên tục
        ↓
    Và nhiều khách hàng của họ cùng
      chia sẻ dải IP đó
    → không phân biệt được ai với ai

Tạo role:

aws iam create-role --role-name vai-tro-doi-tac \
  --assume-role-policy-document file://tin-cay.json \
  --max-session-duration 3600

aws iam attach-role-policy --role-name vai-tro-doi-tac \
  --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess

⚠ Và nên cấp quyền tối thiểu, không phải ReadOnlyAccess chung:

Đối tác chỉ cần đọc chi phí
        ↓
    Cấp `ce:GetCostAndUsage` thôi
        ↓
    `ReadOnlyAccess` cho họ đọc CẢ
      nội dung S3, cấu hình mạng...
    → phạm vi rộng hơn nhiều lần mức
      cần

⚠ Và nên đặt permissions boundary làm trần cứng:

{"Effect": "Deny",
 "Action": ["iam:*", "organizations:*", "kms:Decrypt"],
 "Resource": "*"}
Kể cả khi ai đó gắn nhầm chính sách
  rộng
        ↓
    Boundary vẫn chặn

⚠ Và theo dõi việc giả nhận vai trò trong CloudTrail:

{"eventName": "AssumeRole",
 "requestParameters": {
   "roleArn": "arn:aws:iam::111122223333:role/vai-tro-doi-tac",
   "externalId": "khach-hang-abc-12345"},
 "sourceIPAddress": "..."}
aws logs start-query --log-group-name /aws/cloudtrail \
  --start-time <bat-dau> --end-time <ket-thuc> \
  --query-string 'fields @timestamp, sourceIPAddress
    | filter eventName = "AssumeRole"
      and requestParameters.roleArn like /vai-tro-doi-tac/'

⚠ Và nên đặt cảnh báo khi có lần giả nhận thất bại:

`AccessDenied` khi giả nhận role
        ↓
    Có thể là cấu hình sai
        ↓
    Hoặc là ai đó đang thử với
      external ID khác
    → đáng để cảnh báo

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Credential tạm, tự hết hạn | | | Chống confused deputy | | | Thu hồi bằng một lần sửa trust policy | |

⚠ Và có thể thêm điều kiện aws:PrincipalArn để chặt hơn:

{"Condition": {
  "StringEquals": {
    "sts:ExternalId": "khach-hang-abc-12345"},
  "ArnLike": {
    "aws:PrincipalArn":
      "arn:aws:iam::999988887777:role/dich-vu-*"}}}
Không chỉ tin tài khoản Example Corp
        ↓
    Mà chỉ tin những vai trò cụ thể
      trong đó
    → giảm phạm vi thêm một bậc

⚠ Và nên rà soát định kỳ:

aws accessanalyzer list-findings \
  --analyzer-arn <arn> \
  --filter '{"isPublic": {"eq": ["false"]},
             "resourceType": {"eq": ["AWS::IAM::Role"]}}'
Access Analyzer liệt kê mọi vai trò
  tin cậy bên ngoài
        ↓
    Rà xem còn cần thiết không
    → đối tác cũ thường bị quên

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

  • **Yêu cầu Example Corp cung cấp địa chỉ IP rồi giới hạn theo IP nguồn — đây là phương án gần nhất và thêm được một lớp phòng thủ thật, nhưng IP của một nhà cung cấp SaaS chạy trên AWS thay đổi liên tục và được chia sẻ giữa mọi khách hàng của họ, nên không phân biệt được bạn với khách hàng khác.
  • **Tạo một IAM user và gửi access key cho Example Corp — credential dài hạn không tự hết hạn, phải xoay vòng thủ công, và AWS khuyến nghị không dùng cho truy cập bên thứ ba.
  • **Bắt buộc MFA khi giả nhận vai trò — MFA đòi con người thao tác; Example Corp truy cập tự động, không có ai nhập mã.

Ghi nhớ

⚠ Bốn điều về external ID — bảng phải thuộc: | Điều | Chi tiết | |---|---| | Ai sinh ra | nhà cung cấp dịch vụ | | Đặt ở đâu | Condition của trust policy | | Chống gì | confused deputy | | Có phải bí mật không | không, chỉ cần khó đoán |

Từ khoá nhận diện:

"third-party access to my account" → role + external ID "confused deputy" → external ID "cross-account within my organization" → aws:PrincipalOrgID "application on EC2 needs access" → instance profile

Ba lưu ý về trust policy: | Lưu ý | Chi tiết | |---|---| | Principal khai tài khoản hoặc vai trò được tin | | | Condition thu hẹp phạm vi | | | Sửa trust policy là cách thu hồi nhanh nhất | |

Ba điều kiện hay dùng: | Điều kiện | Việc | |---|---| | sts:ExternalId | bên thứ ba | | aws:PrincipalOrgID | trong cùng tổ chức | | aws:SourceIp | giới hạn mạng |

Ba lưu ý về credential tạm: | Lưu ý | Chi tiết | |---|---| | Mặc định 1 giờ, tối đa 12 giờ | | | Không thu hồi được trước hạn | | | Chặn bằng chính sách với aws:TokenIssueTime | |

⚠ Không thu hồi được token đã cấp:

Phát hiện đối tác bị xâm nhập
        ↓
    Sửa trust policy chặn lần giả nhận
      MỚI
        ↓
    Nhưng token đã cấp vẫn sống tới
      khi hết hạn
    → thêm chính sách Deny theo
      `aws:TokenIssueTime`

Ba lưu ý về quyền tối thiểu: | Lưu ý | Chi tiết | |---|---| | Cấp đúng hành động cần, không dùng chính sách chung | | | Đặt permissions boundary làm trần | | | Rà soát bằng Access Analyzer | |

Ba lưu ý về giám sát: | Lưu ý | Chi tiết | |---|---| | CloudTrail ghi mọi AssumeRole | | | Cảnh báo khi giả nhận thất bại | | | Đặt RoleSessionName có ý nghĩa | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Thử giả nhận không có external ID — phải bị từ chối | | | Thử với external ID sai — phải bị từ chối | | | Kiểm quyền của role bằng Policy Simulator | |

Và một lời khuyên: hãy xin external ID từ nhà cung cấp chứ đừng tự nghĩ ra một giá trị. Bảo vệ của cơ chế này nằm ở chỗ giá trị đó gắn với riêng bạn trong hệ thống của họ — tự đặt một chuỗi đơn giản như tên công ty mình là bỏ đi đúng phần khiến nó có tác dụng.

Câu 446 Design for New Solutions

An analytics company runs a web service that is used by client applications deployed in multiple offices worldwide. The application architecture consists of an Elastic Load Balancer (ELB) distributing traffic across ten application servers deployed in an Auto Scaling group across two Availability Zones. The ELB uses a round-robin configuration with no sticky sessions. The development team has configured the NACLs and security groups to allow port 22 from a NAT instance being used as a jump host, and also allow port 80 from 0.0.0.0/0. The client configuration is managed by each regional IT team. The networking team has noticed that a significant number of requests from incorrectly configured client sites are causing a single application server to degrade. The remainder of the requests are equally distributed across all servers with no negative effects.

As an AWS Certified Solutions Architect Professional, what would you recommend to address the situation and prevent future occurrences?

  1. A

    Terminate the affected instance and allow Auto Scaling to create a new instance

  2. B

    Update the Security Groups for the application servers to only allow incoming traffic on port 80 from the ELB

  3. C

    Terminate the ELB and then create another ELB with a new target group for the ten instances

  4. D

    Update the NACL for the application servers to only allow incoming traffic on port 80 from the ELB

Xem giải thích

Đáp án

**B — Cập nhật Security Group để chỉ cho phép lưu lượng cổng 80 từ Elastic Load Balancer.

Vì sao đúng

Vấn đề: các máy chủ web đang nhận được lưu lượng trực tiếp từ Internet, bỏ qua bộ cân bằng tải. Cách chữa đúng là để security group của instance chỉ nhận từ security group của ELB.

⚠ Điểm mấu chốt: security group tham chiếu được security group khác:

aws ec2 authorize-security-group-ingress \
  --group-id sg-may-chu-web \
  --protocol tcp --port 80 \
  --source-group sg-elb
Nguồn không phải dải IP
        ↓
    Mà là ID của security group khác
        ↓
    Chỉ ENI gắn security group đó mới
      vào được
    → chính xác là "chỉ từ ELB"

⚠ Và vì sao KHÔNG dùng dải IP của ELB:

ELB có địa chỉ IP THAY ĐỔI
        ↓
    Nó co giãn theo tải, thêm bớt node
        ↓
    Khai IP hôm nay → mai sai
        ↓
    Tham chiếu security group tự đúng
      mãi mãi

⚠ Và đây là điểm khác nhau giữa ALB và NLB — cần biết: | | ALB | NLB | |---|---|---| | Có security group | có | có (từ 2023) | | IP nguồn tới đích | IP của ALB | IP của CLIENT (mặc định) |

NLB không bật `preserve-client-ip`
        ↓
    Đích thấy IP của NLB
        ↓
    Bật `preserve-client-ip`
        ↓
    Đích thấy IP thật của client
    → và security group phải cho phép
      IP đó, không phải IP của NLB

⚠ Và NLB trước 2023 không có security group:

NLB cũ không gắn được security group
        ↓
    Phải cho phép theo dải CIDR của VPC
        ↓
    Hoặc dùng NACL
        ↓
    Từ 8/2023 NLB gắn được security
      group
    → nhưng chỉ khai được lúc TẠO,
      không thêm sau

Cấu hình đúng ba tầng:

Internet
    ↓  sg-elb: cho phép 80,443 từ 0.0.0.0/0
Elastic Load Balancer
    ↓  sg-web: cho phép 80 từ sg-elb
Máy chủ web
    ↓  sg-db: cho phép 3306 từ sg-web
Cơ sở dữ liệu
Mỗi tầng chỉ nhận từ tầng ngay trên
        ↓
    Không tầng nào lộ ra Internet trừ
      ELB
    → đây là mẫu chuẩn

⚠ Và nên đưa máy chủ web vào subnet riêng tư luôn:

Security group chặn ở tầng ENI
        ↓
    Nhưng instance vẫn có IP công khai
        ↓
    Vẫn bị quét, vẫn tốn tài nguyên xử
      lý gói tin bị từ chối
        ↓
    Đặt trong private subnet
    → không có đường vào nào cả
aws ec2 modify-instance-attribute \
  --instance-id i-abc --no-source-dest-check

⚠ Và tắt gán IP công khai tự động:

aws ec2 modify-subnet-attribute \
  --subnet-id subnet-abc \
  --no-map-public-ip-on-launch

⚠ Và vì sao phương án dùng NACL không tốt bằng:

NACL áp cho cả SUBNET
        ↓
    Mọi instance trong đó bị ảnh hưởng
        ↓
    Và NACL stateless — phải khai cả
      luật ra
        ↓
    Và không tham chiếu được security
      group
    → phải khai dải IP, quay lại vấn
      đề IP thay đổi

⚠ Và vì sao đổi cổng không giải quyết gì:

Đổi máy chủ web sang cổng 8080
        ↓
    Kẻ quét cổng tìm ra trong vài phút
        ↓
    Bảo mật bằng cách giấu không phải
      bảo mật
    → và ELB vẫn phải biết cổng mới

⚠ Và kiểm tra security group hiện tại trước khi sửa:

aws ec2 describe-security-groups --group-ids sg-may-chu-web \
  --query 'SecurityGroups[0].IpPermissions'
Tìm luật có `IpRanges` chứa
  `0.0.0.0/0`
        ↓
    Đó chính là luật cần xoá
aws ec2 revoke-security-group-ingress \
  --group-id sg-may-chu-web \
  --protocol tcp --port 80 --cidr 0.0.0.0/0

⚠ Và xoá luật trước khi thêm luật mới sẽ gây gián đoạn:

Xoá luật 0.0.0.0/0 trước
        ↓
    ELB chưa được cho phép
        ↓
    Health check thất bại → đích bị
      gỡ khỏi target group
        ↓
    → THÊM luật mới trước, XOÁ luật cũ
      sau

⚠ Và health check của ELB cũng đi qua security group:

ELB gửi health check tới đích
        ↓
    Từ cùng security group của ELB
        ↓
    Nếu health check dùng cổng khác
      (8080 chẳng hạn)
    → phải cho phép cả cổng đó

⚠ Và sau khi sửa, đích có thể vẫn nhận lưu lượng cũ một lúc:

Security group là stateful
        ↓
    Kết nối ĐANG MỞ vẫn tiếp tục
        ↓
    Xoá luật chỉ chặn kết nối MỚI
        ↓
    Muốn cắt ngay → khởi động lại
      dịch vụ hoặc dùng NACL

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Mọi lưu lượng buộc qua ELB | | | WAF và log của ELB không bị bỏ qua | | | Tự đúng khi ELB đổi IP | |

⚠ Và đây là lý do quan trọng nhất — bỏ qua ELB là bỏ qua mọi lớp bảo vệ:

Gọi thẳng instance
        ↓
    Không qua WAF
        ↓
    Không qua access log của ELB
        ↓
    Không qua TLS termination
        ↓
    → mọi biện pháp đặt ở ELB đều vô
      dụng

⚠ Và nên đo xem còn ai gọi thẳng không:

aws logs start-query --log-group-name /vpc/flowlogs \
  --start-time <bat-dau> --end-time <ket-thuc> \
  --query-string 'fields srcaddr, dstaddr, dstport, action
    | filter dstport = 80 and action = "ACCEPT"
    | stats count() by srcaddr'
Địa chỉ nguồn không thuộc dải của ELB
        ↓
    → vẫn còn đường đi vòng

⚠ Và security group có giới hạn số luật:

60 luật vào và 60 luật ra mỗi
  security group
        ↓
    5 security group mỗi ENI
        ↓
    Khai từng dải IP sẽ chạm trần
    → tham chiếu security group tiết
      kiệm hơn nhiều

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

  • **Cập nhật network ACL để chỉ cho phép cổng 80 từ dải IP của ELB — đây là phương án gần nhất và thật sự chặn được lưu lượng, nhưng NACL áp cho cả subnet, stateless nên phải khai thêm luật ra, và không tham chiếu được security group nên phải khai dải IP vốn thay đổi.
  • **Đổi máy chủ web sang cổng khác — bảo mật bằng cách giấu, kẻ quét cổng tìm ra ngay.
  • **Đặt máy chủ web trong subnet riêng tư mà không sửa security group — đây là biện pháp tốt và nên làm, nhưng bản thân nó không phải là việc "cập nhật quy tắc" mà đề hỏi, và không chặn được lưu lượng từ trong VPC.

Ghi nhớ

⚠ Bốn tầng kiểm soát lưu lượng — bảng phải thuộc: | Tầng | Phạm vi | Tham chiếu SG | |---|---|---| | Security group | ENI | có | | Network ACL | subnet | không | | Route table | subnet | không | | WAF | ALB, CloudFront, API GW | không |

Từ khoá nhận diện:

"only allow traffic from the load balancer" → tham chiếu security group của ELB "ELB IP changes" → đừng khai dải IP "NLB preserves client IP" → cho phép IP client, không phải IP NLB "bypass the WAF" → có đường vào trực tiếp đích

Ba lưu ý về tham chiếu security group: | Lưu ý | Chi tiết | |---|---| | Chỉ trong cùng VPC hoặc VPC đã peering | | | Không dùng qua Transit Gateway | | | Tự đúng khi ENI thêm bớt | |

Ba lưu ý về NLB: | Lưu ý | Chi tiết | |---|---| | Gắn security group được từ 8/2023 | | | Chỉ khai được lúc tạo | | | preserve-client-ip đổi IP nguồn mà đích thấy | |

Ba lưu ý về thứ tự thao tác: | Bước | Việc | |---|---| | 1. Thêm luật cho phép từ ELB | | | 2. Kiểm health check xanh | | | 3. Xoá luật 0.0.0.0/0 | |

Ba lưu ý về subnet riêng tư: | Lưu ý | Chi tiết | |---|---| | Không gán IP công khai | | | Ra Internet qua NAT Gateway | | | Dùng VPC endpoint cho dịch vụ AWS | |

Ba lưu ý về giới hạn: | Giới hạn | Giá trị | |---|---| | Luật mỗi security group | 60 vào, 60 ra | | Security group mỗi ENI | 5 (nâng tới 16) | | Luật nhân security group mỗi ENI | 1.000 |

Ba lưu ý về giám sát: | Lưu ý | Chi tiết | |---|---| | VPC Flow Log tìm đường vào trực tiếp | | | Config rule cảnh báo luật 0.0.0.0/0 | | | Access log của ELB đối chiếu lưu lượng | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gọi thẳng IP instance — phải hết thời gian chờ | | | Gọi qua ELB — phải bình thường | | | Đọc Flow Log tìm nguồn lạ | |

Và một lời khuyên: hãy thêm luật mới trước rồi mới xoá luật cũ. Health check của ELB đi qua chính security group đang sửa — xoá 0.0.0.0/0 trước khi cho phép ELB sẽ khiến mọi đích rớt khỏi target group và trang web chết ngay lập tức, đúng vào lúc bạn tưởng mình vừa làm nó an toàn hơn.

Câu 447 Continuous Improvement for Existing Solutions

A web application is hosted on Amazon EC2 instances that are fronted by Application Load Balancer (ALB) configured with an Auto Scaling group (ASG). Enhanced security is provided to the ALB by AWS WAF web ACLs. As per the company's security policy, AWS CloudTrail is activated and logs are configured to be stored on Amazon S3 and CloudWatch Logs.

A holiday sales offer was run on the application for a week. The development team has noticed that a few of the instances have rebooted taking down the log files and all temporary data with them. Initial analysis has confirmed that the incident took place during off-peak hours. Even though the incident did not cause any sales or revenue loss, the CTO has asked the development team to fix the security error that has allowed the incident to go unnoticed and eventually untraceable.

Which of the following steps will you implement to permanently record all traffic coming into the application?

  1. A

    Configure Elastic Load Balancing to write access logs to Amazon Kinesis Data Firehose. The logs can be further directed from Firehose into an Amazon S3 bucket for further analysis and reporting

  2. B

    Configure the WAF web ACL to deliver logs to Amazon CloudTrail and create a trail that applies to all Regions. This delivers log files from all Regions to an S3 bucket. Use Athena to query the logs for errors and tracking

  3. C

    To capture information about the IP traffic going to and from network interfaces, configure VPC Flow Logs to be directly streamed to Kinesis Data Streams and create alarms for automatic monitoring

  4. D

    Configure the WAF web ACL to deliver logs to Amazon Kinesis Data Firehose, which should be configured to eventually store the logs in an Amazon S3 bucket. Use Athena to query the logs for errors and tracking

Xem giải thích

Đáp án

**D — Cấu hình WAF web ACL gửi log tới Amazon Data Firehose, Firehose ghi vào một bucket S3; rồi dùng Athena truy vấn log để tìm lỗi và truy vết.

Vì sao đúng

Đề nêu vấn đề rất rõ: log nằm trên máy và biến mất cùng với máy.

Instance khởi động lại
    → log và dữ liệu tạm mất theo
        ↓
    Sự việc "không để lại dấu vết"
        ↓
    Cần: ghi lại VĨNH VIỄN mọi
      lưu lượng đi vào ứng dụng

⚠ Điểm mấu chốt: "toàn bộ lưu lượng đi vào" — WAF nằm đúng chỗ đó:

Lưu lượng vào: WAF → ALB → EC2
        ↓
    WAF là chốt ĐẦU TIÊN
    → thấy mọi yêu cầu HTTP trước
      khi tới bất kỳ đâu
        ↓
    Và đề nói WAF đã được cấu hình
      trên ALB

⚠ Và log của WAF chứa đúng thứ cần cho việc điều tra:

{"timestamp": 1756684800000,
 "httpRequest": {
   "clientIp": "203.0.113.42",
   "country": "VN",
   "uri": "/dat-hang",
   "httpMethod": "POST",
   "headers": [{"name": "User-Agent", "value": "..."}]},
 "action": "ALLOW",
 "terminatingRuleId": "Default_Action",
 "rateBasedRuleList": []}

Bật ghi log cho WAF:

aws wafv2 put-logging-configuration --logging-configuration '{
  "ResourceArn": "arn:aws:wafv2:ap-southeast-1:111122223333:regional/webacl/bao-ve/abc",
  "LogDestinationConfigs": [
    "arn:aws:firehose:ap-southeast-1:111122223333:deliverystream/aws-waf-logs-ung-dung"],
  "RedactedFields": [{"SingleHeader": {"Name": "authorization"}}]}'

⚠ Tên luồng Firehose BẮT BUỘC bắt đầu bằng aws-waf-logs-:

Đặt tên khác
    → WAF từ chối cấu hình
        ↓
    Đây là ràng buộc cứng, rất dễ
      vấp lần đầu

⚠ Và RedactedFields che thông tin nhạy cảm:

Log ghi cả header
    → có thể chứa cookie phiên,
      token uỷ quyền
        ↓
    Che chúng đi trước khi lưu
    → log lưu lâu dài không trở
      thành kho bí mật

Truy vấn bằng Athena:

CREATE EXTERNAL TABLE waf_logs (
  timestamp bigint,
  httprequest struct<clientip:string, country:string,
                     uri:string, httpmethod:string>,
  action string,
  terminatingruleid string)
PARTITIONED BY (nam string, thang string, ngay string)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://log-waf/AWSLogs/';
SELECT httprequest.clientip, COUNT(*) AS so_luot
FROM waf_logs
WHERE nam='2026' AND thang='09' AND action='BLOCK'
GROUP BY httprequest.clientip
ORDER BY so_luot DESC LIMIT 20;

⚠ Và vì sao phương án A (access log của ELB) là lựa chọn hợp lý nhưng thua:

ALB access log ghi được vào S3
        ↓
    Nhưng ALB KHÔNG ghi thẳng vào
      Firehose
    → nó ghi thẳng vào S3
        ↓
    Phương án A mô tả sai luồng
aws elbv2 modify-load-balancer-attributes \
  --load-balancer-arn <arn> --attributes \
    Key=access_logs.s3.enabled,Value=true \
    Key=access_logs.s3.bucket,Value=log-alb
Đây là cách đúng để bật access
  log của ALB — thẳng vào S3

⚠ Và vì sao phương án B sai — CloudTrail không nhận log của WAF:

B nói "cấu hình WAF gửi log tới
  CloudTrail"
        ↓
    CloudTrail ghi lời gọi API
      QUẢN TRỊ
    → ai sửa web ACL, ai thêm luật
        ↓
    Nó KHÔNG ghi lưu lượng người
      dùng đi qua WAF

⚠ Và vì sao phương án C không đủ:

VPC Flow Log ghi ở tầng MẠNG
        ↓
    IP nguồn, IP đích, cổng, giao
      thức, ACCEPT/REJECT
        ↓
    KHÔNG có: đường dẫn URL,
      phương thức HTTP, header,
      user agent
        ↓
    Điều tra sự cố ứng dụng cần
      những thứ đó

⚠ Ba tầng log và nội dung của chúng: | Tầng | Log | Nội dung | |---|---|---| | Mạng | VPC Flow Log | IP, cổng, byte, accept/reject | | Cân bằng tải | ALB access log | URL, mã trạng thái, độ trễ, target | | Tường lửa ứng dụng | WAF log | URL, header, luật nào khớp, hành động |

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Log nằm ngoài instance, sống sót mọi sự cố | | | Chứa đủ chi tiết tầng ứng dụng | | | Athena truy vấn không cần dựng hạ tầng | |

⚠ Và Firehose cho phép biến đổi trước khi lưu:

Lambda trong Firehose
    → thêm trường, lọc bớt, đổi
      sang Parquet
        ↓
    Parquet giảm chi phí truy vấn
      Athena rất nhiều

Ghi nhớ về chất lượng câu hỏi

⚠ Từ 2021, WAF gửi log thẳng tới S3 và CloudWatch Logs được, không cần qua Firehose.

aws wafv2 put-logging-configuration --logging-configuration '{
  "ResourceArn": "<arn-webacl>",
  "LogDestinationConfigs": ["arn:aws:s3:::aws-waf-logs-ung-dung"]}'
Đích Ưu Nhược
S3 trực tiếp đơn giản nhất, rẻ nhất không biến đổi được
CloudWatch Logs truy vấn ngay bằng Insights đắt hơn khi lưu lâu
Firehose biến đổi, chuyển Parquet, gửi nơi khác thêm một thành phần
Với yêu cầu trong đề (lưu lâu dài
  + truy vấn bằng Athena)
        ↓
    S3 trực tiếp là đủ và đơn giản
      nhất
        ↓
    Firehose chỉ đáng thêm khi cần
      chuyển sang Parquet hoặc gửi
      song song sang SIEM

Và bản chất vấn đề trong đề là một vấn đề khác: log ứng dụng nằm trên đĩa instance. Cách chữa đúng cho việc đó là CloudWatch Agent đẩy log ra ngoài liên tục — chứ không phải thay bằng log của WAF, vốn chỉ ghi lưu lượng đi vào chứ không ghi hoạt động bên trong ứng dụng.

[/var/log/ung-dung/*.log]
file = /var/log/ung-dung/*.log
log_group_name = /ung-dung/san-xuat
log_stream_name = {instance_id}

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

  • **A. Cấu hình ELB ghi access log vào Firehose rồi từ đó vào S3 — đây là phương án gần nhất và access log của ALB thật sự ghi được mọi yêu cầu đi vào, nhưng ALB ghi thẳng vào S3 chứ không gửi qua Firehose; luồng mô tả trong phương án không tồn tại.
  • **B. Cấu hình WAF gửi log tới CloudTrail và tạo trail cho mọi Region — CloudTrail ghi lời gọi API quản trị, không ghi lưu lượng người dùng.
  • **C. Dùng VPC Flow Log đẩy vào Kinesis Data Streams — flow log ở tầng mạng, không có URL, phương thức HTTP hay header.

Ghi nhớ

⚠ Bốn nguồn log cho lưu lượng web — bảng phải thuộc: | Nguồn | Tầng | Có URL | |---|---|---| | VPC Flow Log | mạng | KHÔNG | | ALB access log | 7 | CÓ | | WAF log | 7 | CÓ, kèm luật nào khớp | | CloudFront access log | 7, ở biên | CÓ |

Từ khoá nhận diện:

"record all incoming traffic permanently" → WAF log hoặc ALB access log vào S3 "which WAF rule blocked this" → WAF log "who called which AWS API" → CloudTrail "packets between ENIs" → VPC Flow Log

Ba lưu ý về WAF log: | Lưu ý | Chi tiết | |---|---| | Tên luồng Firehose phải bắt đầu aws-waf-logs- | | | RedactedFields che header nhạy cảm | | | Lọc được chỉ ghi yêu cầu bị chặn | |

⚠ Lọc log giảm chi phí đáng kể:

"LoggingFilter": {"DefaultBehavior": "DROP",
  "Filters": [{"Behavior": "KEEP", "Requirement": "MEETS_ANY",
    "Conditions": [{"ActionCondition": {"Action": "BLOCK"}}]}]}
Chỉ ghi yêu cầu bị CHẶN
    → giảm mạnh lượng log
        ↓
    Nhưng mất dấu vết của lưu lượng
      hợp lệ
    → cân nhắc theo mục đích

Ba lưu ý về Athena trên log: | Lưu ý | Chi tiết | |---|---| | Phân vùng theo ngày là bắt buộc | | | Parquet giảm chi phí quét rất nhiều | | | Partition projection bỏ được việc thêm phân vùng | |

⚠ Partition projection rất hợp với log:

TBLPROPERTIES (
  'projection.enabled'='true',
  'projection.ngay.type'='date',
  'projection.ngay.range'='2026/01/01,NOW',
  'projection.ngay.format'='yyyy/MM/dd')
Không cần chạy crawler hay
  ALTER TABLE ADD PARTITION
        ↓
    Athena tự suy ra phân vùng từ
      đường dẫn

Ba lưu ý về vòng đời log: | Tuổi | Lớp lưu trữ | |---|---| | 0-30 ngày | S3 Standard | | 30-90 ngày | Standard-IA | | trên 90 ngày | Glacier Instant Retrieval |

Ba lưu ý về log ứng dụng: | Lưu ý | Chi tiết | |---|---| | CloudWatch Agent đẩy log ra ngoài liên tục | | | Đừng để log chỉ nằm trên đĩa instance | | | Đặt log group retention để khỏi lưu vô hạn | |

⚠ Log group mặc định lưu VĨNH VIỄN:

aws logs put-retention-policy \
  --log-group-name /ung-dung/san-xuat --retention-in-days 90
Không đặt → trả tiền lưu trữ mãi

Ba lưu ý về bảo vệ log: | Lưu ý | Chi tiết | |---|---| | Bucket log ở tài khoản riêng | | | S3 Object Lock chống xoá | | | SCP cấm tắt ghi log | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gửi một yêu cầu và tìm nó trong log | | | Chấm dứt một instance, kiểm log vẫn còn | | | Chạy một truy vấn Athena mẫu | |

Và một lời khuyên: hãy đẩy cả log ứng dụng ra CloudWatch Logs song song với việc bật log của WAF. Log của WAF cho biết ai gửi yêu cầu gì tới, nhưng khi cần biết ứng dụng đã làm gì với yêu cầu đó, chỉ có log của chính ứng dụng mới trả lời được — và đó chính là thứ đã biến mất cùng với instance.

Câu 448 Accelerate Workload Migration and Modernization

A firm has created different AWS Virtual Private Cloud (VPCs) for each project belonging to a client. For inter-project functionality, the firm needs to connect to a load balancer in VPC V1 from the Amazon EC2 instance in VPC V2.

How will you set up the access to the internal load balancer for this use case in the most cost-effective manner?

  1. A

    Establish connectivity between VPC V1 and VPC V2 using VPC peering. Enable DNS resolution from the source VPC for VPC peering. Establish the necessary routes, security group rules, and network access control list (ACL) rules to allow traffic between the VPCs

  2. B

    Establish connectivity between VPC V1 and VPC V2 using VPC Interface endpoint. Enable DNS delegation from the source VPC for VPC peering. Establish the necessary routes, security group rules, and network access control list (ACL) rules to allow traffic between the VPCs

  3. C

    Establish connectivity between VPC V1 and VPC V2 using Transit Gateway. Update route tables inside the transit gateway, and change the VPC association to these route tables. Establish the necessary security group rules, and network access control list (ACL) rules to allow traffic between the VPCs

  4. D

    Establish connectivity between VPC V1 and VPC V2 using VPC Gateway endpoint. Enable DNS resolution from the source VPC for VPC peering. Establish the necessary routes, security group rules, and network access control list (ACL) rules to allow traffic between the VPCs

Xem giải thích

Đáp án

**A — Dựng VPC peering giữa hai VPC và bật phân giải DNS từ phía VPC nguồn, kèm cấu hình route table, security group và network ACL cho phù hợp.

Vì sao đúng

Đề yêu cầu tài nguyên ở VPC này gọi được tài nguyên ở VPC kia bằng tên DNS riêng tư. Có hai việc phải làm, và cả hai đều nằm trong đáp án: | Việc | Vì sao cần | |---|---| | VPC peering | tạo đường mạng giữa hai VPC | | Bật phân giải DNS | để tên DNS trả về IP RIÊNG TƯ |

⚠ Điểm mấu chốt: thiếu bước bật DNS thì tên vẫn phân giải — nhưng ra IP CÔNG KHAI:

VPC A hỏi tên DNS của endpoint ở
  VPC B
        ↓
    Không bật `AllowDnsResolutionFromRemoteVpc`
        ↓
    Trả về địa chỉ IP CÔNG KHAI
        ↓
    Lưu lượng đi ra Internet Gateway
    → không đi qua peering
Hậu quả:
    - trả tiền truyền dữ liệu ra
      Internet
    - lưu lượng ra khỏi mạng riêng
    - và nếu subnet không có đường ra
      Internet
    → kết nối HỎNG HẲN

Bật phân giải DNS qua peering:

aws ec2 modify-vpc-peering-connection-options \
  --vpc-peering-connection-id pcx-abc \
  --requester-peering-connection-options \
    AllowDnsResolutionFromRemoteVpc=true

aws ec2 modify-vpc-peering-connection-options \
  --vpc-peering-connection-id pcx-abc \
  --accepter-peering-connection-options \
    AllowDnsResolutionFromRemoteVpc=true

⚠ Và phải bật ở CẢ HAI phía nếu cần gọi hai chiều:

Chỉ bật ở phía requester
        ↓
    VPC A phân giải được tên của VPC B
        ↓
    Nhưng VPC B không phân giải được
      tên của VPC A
    → mỗi chiều cần một cờ riêng

⚠ Và VPC phải bật sẵn hai thuộc tính DNS:

aws ec2 modify-vpc-attribute --vpc-id vpc-abc \
  --enable-dns-support

aws ec2 modify-vpc-attribute --vpc-id vpc-abc \
  --enable-dns-hostnames
`enableDnsSupport`: dùng được Route 53
  Resolver ở địa chỉ .2
        ↓
    `enableDnsHostnames`: instance có
      tên DNS
        ↓
    Thiếu cái đầu → cờ peering không
      có tác dụng

Bốn bước dựng peering đầy đủ:

1. Tạo và chấp nhận peering
        ↓
2. Thêm route ở CẢ HAI route table
        ↓
3. Sửa security group cho phép CIDR
     hoặc security group bên kia
        ↓
4. Kiểm network ACL cho phép hai chiều
aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-a --peer-vpc-id vpc-b

aws ec2 accept-vpc-peering-connection \
  --vpc-peering-connection-id pcx-abc

aws ec2 create-route --route-table-id rtb-a \
  --destination-cidr-block 10.1.0.0/16 \
  --vpc-peering-connection-id pcx-abc

aws ec2 create-route --route-table-id rtb-b \
  --destination-cidr-block 10.0.0.0/16 \
  --vpc-peering-connection-id pcx-abc

⚠ Và quên route ở MỘT phía là lỗi hay gặp nhất:

Chỉ thêm route ở VPC A
        ↓
    Gói tin đi được sang VPC B
        ↓
    Nhưng phản hồi không biết đường về
        ↓
    Triệu chứng: kết nối treo, hết
      thời gian chờ

⚠ Và tham chiếu security group qua peering CHỈ hoạt động cùng Region:

Peering trong cùng Region
        ↓
    Tham chiếu security group bên kia
      được
        ↓
    Peering LIÊN REGION
        ↓
    Không tham chiếu được
    → phải khai dải CIDR

⚠ Và peering KHÔNG bắc cầu — ràng buộc quan trọng nhất:

A ↔ B và B ↔ C
        ↓
    A KHÔNG nói chuyện được với C
        ↓
    Phải tạo thêm peering A ↔ C
        ↓
    n VPC → n(n-1)/2 kết nối
    → 10 VPC = 45 kết nối
Đây là lý do Transit Gateway tồn tại:
        ↓
    Mô hình hub-and-spoke
        ↓
    Mỗi VPC chỉ gắn MỘT lần
    → 10 VPC = 10 attachment

Bảng so sánh: | | VPC Peering | Transit Gateway | |---|---|---| | Bắc cầu | không | có | | Số kết nối cho n VPC | n(n-1)/2 | n | | Chi phí | chỉ phí truyền dữ liệu | phí attachment theo giờ + truyền | | Độ trễ | thấp nhất | thêm một chặng | | Băng thông | không giới hạn | 50 Gbps mỗi attachment |

Hai VPC → peering rẻ hơn và đơn giản
  hơn
        ↓
    Nhiều VPC → Transit Gateway

⚠ Và CIDR không được chồng lấn:

VPC A: 10.0.0.0/16
VPC B: 10.0.0.0/16
        ↓
    Không tạo peering được
        ↓
    AWS từ chối ngay khi tạo
    → phải đánh số lại một VPC

⚠ Và phương án dùng PrivateLink cũng đáng cân nhắc:

aws ec2 create-vpc-endpoint-service-configuration \
  --network-load-balancer-arns <arn-nlb> \
  --acceptance-required

aws ec2 create-vpc-endpoint --vpc-id vpc-a \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.vpce.ap-southeast-1.vpce-svc-abc \
  --subnet-ids subnet-a1 subnet-a2 \
  --private-dns-enabled
PrivateLink chỉ lộ MỘT dịch vụ
        ↓
    Không nối cả hai mạng
        ↓
    Và CIDR chồng lấn cũng dùng được
    → chặt hơn peering về bảo mật

Bảng chọn: | Nhu cầu | Chọn | |---|---| | Hai VPC, cần nối toàn mạng | peering | | Nhiều VPC nối lưới | Transit Gateway | | Chỉ lộ một dịch vụ | PrivateLink | | CIDR chồng lấn | PrivateLink |

⚠ Và với tên DNS tuỳ chỉnh thì cần Route 53 private hosted zone:

aws route53 associate-vpc-with-hosted-zone \
  --hosted-zone-id Z123 \
  --vpc VPCRegion=ap-southeast-1,VPCId=vpc-a
Private hosted zone gắn được với
  nhiều VPC
        ↓
    Kể cả VPC ở tài khoản khác
        ↓
    Khi đó tên tuỳ chỉnh phân giải
      được ở cả hai bên

⚠ Và gắn hosted zone liên tài khoản phải làm bằng CLI:

# Tài khoản chứa hosted zone
aws route53 create-vpc-association-authorization \
  --hosted-zone-id Z123 \
  --vpc VPCRegion=ap-southeast-1,VPCId=vpc-b

# Tài khoản chứa VPC
aws route53 associate-vpc-with-hosted-zone \
  --hosted-zone-id Z123 \
  --vpc VPCRegion=ap-southeast-1,VPCId=vpc-b
Console không làm được việc này
        ↓
    Phải qua hai lệnh, ở hai tài khoản

Ba lợi ích của peering: | Lợi ích | Chi tiết | |---|---| | Lưu lượng đi trên mạng riêng của AWS | | | Không có điểm nghẽn băng thông | | | Không tính phí theo giờ | |

⚠ Và peering liên Region có tính phí truyền dữ liệu:

Cùng Region, khác AZ: 0,01 USD/GB
  mỗi chiều
        ↓
    Cùng Region, cùng AZ: miễn phí
      (từ 5/2021)
        ↓
    Liên Region: theo giá truyền dữ
      liệu giữa Region

⚠ Và chẩn đoán khi không kết nối được:

aws ec2 create-network-insights-path \
  --source i-may-a --destination i-may-b \
  --protocol tcp --destination-port 443

aws ec2 start-network-insights-analysis \
  --network-insights-path-id nip-abc
Reachability Analyzer chỉ ra chính
  xác thành phần đang chặn
        ↓
    Route thiếu, SG chặn, NACL chặn
    → nhanh hơn thử từng thứ

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

  • **Dựng VPC peering nhưng không bật phân giải DNS — đây là phương án gần nhất và đường mạng đã thông, nhưng tên DNS sẽ trả về IP công khai, khiến lưu lượng đi ra Internet thay vì qua peering, hoặc hỏng hẳn nếu subnet không có đường ra Internet.
  • **Dùng Transit Gateway — hoạt động được, nhưng với đúng hai VPC thì nó thêm phí attachment theo giờ và một chặng độ trễ mà không đổi lại lợi ích nào.
  • **Dùng VPN site-to-site giữa hai VPC — đi vòng qua đường hầm IPsec có giới hạn băng thông, trong khi hai VPC nằm sẵn trên cùng hạ tầng AWS.

Ghi nhớ

⚠ Bốn bước dựng peering — bảng phải thuộc: | Bước | Việc | |---|---| | 1. Tạo và chấp nhận | hai phía đều phải hành động | | 2. Route ở CẢ HAI route table | quên một bên là treo | | 3. Security group | CIDR hoặc SG (cùng Region) | | 4. Bật phân giải DNS | để ra IP riêng tư |

Từ khoá nhận diện:

"resolve to private IP over peering" → AllowDnsResolutionFromRemoteVpc "A talks to C through B" → peering KHÔNG bắc cầu "overlapping CIDR" → PrivateLink, không phải peering "many VPCs, full mesh" → Transit Gateway

Ba lưu ý về DNS trong VPC: | Thuộc tính | Việc | |---|---| | enableDnsSupport | dùng được Resolver ở .2 | | enableDnsHostnames | instance có tên DNS | | AllowDnsResolutionFromRemoteVpc | trả IP riêng tư qua peering |

Ba giới hạn của peering: | Giới hạn | Chi tiết | |---|---| | Không bắc cầu | | | CIDR không được chồng lấn | | | Không tham chiếu SG khi liên Region | |

Ba lưu ý về Transit Gateway: | Lưu ý | Chi tiết | |---|---| | Hub-and-spoke, bắc cầu được | | | Route table riêng để phân đoạn | | | Phí attachment theo giờ | |

Ba lưu ý về PrivateLink: | Lưu ý | Chi tiết | |---|---| | Lộ đúng một dịch vụ | | | Một chiều: consumer gọi provider | | | CIDR chồng lấn vẫn dùng được | |

Ba lưu ý về chi phí: | Trường hợp | Phí | |---|---| | Peering cùng AZ | miễn phí | | Peering khác AZ | 0,01 USD/GB mỗi chiều | | Transit Gateway | phí attachment + 0,02 USD/GB |

Ba lưu ý về Route 53 private hosted zone: | Lưu ý | Chi tiết | |---|---| | Gắn được với nhiều VPC | | | Liên tài khoản phải dùng CLI | | | Cần enableDnsSupport ở mọi VPC gắn vào | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | dig tên DNS — phải ra IP riêng tư | | | Chạy Reachability Analyzer | | | Kiểm route ở cả hai route table | |

Và một lời khuyên: hãy dig tên DNS từ phía bên kia sau khi dựng peering và xác nhận nó trả về địa chỉ riêng tư. Kết nối vẫn có thể chạy được khi tên phân giải ra IP công khai — chỉ là nó đi vòng ra Internet, tính phí truyền dữ liệu, và rời khỏi mạng riêng mà không có dấu hiệu nào cho thấy điều đó.

Câu 449 Continuous Improvement for Existing Solutions

An e-commerce business has recently moved to AWS serverless infrastructure with the help of Amazon API Gateway, AWS Lambda, and Amazon DynamoDB. The application performs as expected on a normal day. But, during peak periods, when thousands of concurrent requests are submitted, the user requests are initially failing before finally succeeding. The development team examined the logs for each component with a special focus on the Amazon CloudWatch Logs for Lambda. None of the components, services, or applications have logged any errors.

What could be the most probable reason for this failure?

  1. A

    DynamoDB is shutting down intermittently because of issues in Auto Scaling configuration

  2. B

    Lambda is configured to use NAT Gateway to connect to the internet and the NAT Gateway is timing out resulting in throttling of Lambda

  3. C

    The throttle limit set on API Gateway is very low. During peak hours, the additional requests are not making their way to Lambda

  4. D

    Lambda function might have been configured with memory requirements less than 128MB. This causes throttling of requests at Lambda, resulting in user request failures

Xem giải thích

Đáp án

**C — Giới hạn throttle đặt trên API Gateway quá thấp. Trong giờ cao điểm, các yêu cầu vượt quá không đi tới được Lambda.

Vì sao đúng

Manh mối quyết định nằm ở câu cuối của đề: không thành phần nào ghi lỗi nào cả. Điều đó loại gần hết các nguyên nhân.

⚠ Điểm mấu chốt: throttle ở API Gateway xảy ra TRƯỚC khi Lambda được gọi:

Yêu cầu tới API Gateway
        ↓
    Vượt giới hạn throttle
        ↓
    API Gateway trả `429 Too Many Requests`
        ↓
    Lambda KHÔNG BAO GIỜ được gọi
    → không có log Lambda nào cả

⚠ Và triệu chứng "hỏng rồi cuối cùng cũng thành công" khớp chính xác:

Client nhận 429
        ↓
    SDK của AWS tự thử lại với
      exponential backoff
        ↓
    Lần thử sau rơi vào cửa sổ khác
        ↓
    Thành công
    → người dùng thấy "chậm nhưng
      cuối cùng vẫn được"

Hai mức throttle của API Gateway: | Mức | Mặc định | |---|---| | Steady-state (mỗi Region, mỗi tài khoản) | 10.000 req/giây | | Burst | 5.000 req |

Nhưng đó là mức TÀI KHOẢN
        ↓
    Còn có throttle theo stage, theo
      method, theo usage plan
    → và những cái đó đặt thấp hơn
      rất nhiều

Xem cấu hình throttle hiện tại:

aws apigateway get-stage \
  --rest-api-id abc123 --stage-name prod \
  --query 'methodSettings'

Nâng giới hạn ở stage:

aws apigateway update-stage \
  --rest-api-id abc123 --stage-name prod \
  --patch-operations \
    op=replace,path=/*/*/throttling/rateLimit,value=5000 \
    op=replace,path=/*/*/throttling/burstLimit,value=10000

⚠ Và usage plan là chỗ hay bị quên nhất:

aws apigateway get-usage-plans \
  --query 'items[*].{ten:name,throttle:throttle,quota:quota}'
Usage plan gắn với API key
        ↓
    Đặt riêng rate, burst và quota
      theo ngày/tuần/tháng
        ↓
    Quota hết → 429 dù rate còn dư
    → và cũng không có log Lambda nào

⚠ Và vì sao phương án D sai về mặt sự thật:

D nói bộ nhớ Lambda dưới 128 MB
        ↓
    128 MB là mức TỐI THIỂU
        ↓
    Không cấu hình thấp hơn được
        ↓
    → tình huống này không tồn tại

⚠ Và bộ nhớ thấp không gây throttle:

Bộ nhớ ít → chạy chậm hơn
        ↓
    Hoặc hết bộ nhớ → lỗi và CÓ log
        ↓
    Throttle của Lambda là chuyện của
      SỐ LƯỢNG đồng thời
    → không liên quan tới bộ nhớ

⚠ Và vì sao phương án A sai:

A nói DynamoDB "tắt gián đoạn" vì
  cấu hình auto scaling
        ↓
    DynamoDB là dịch vụ được quản lý
        ↓
    Nó không "tắt"
        ↓
    Nếu thiếu công suất thì trả
      `ProvisionedThroughputExceededException`
    → và Lambda sẽ GHI LOG lỗi đó

⚠ Và vì sao phương án B sai:

B nói NAT Gateway hết thời gian chờ
        ↓
    Đề không nói Lambda nằm trong VPC
        ↓
    Và nếu Lambda gọi ra ngoài thất
      bại
    → nó sẽ ném ngoại lệ và GHI LOG

⚠ Và đây là nguyên tắc chẩn đoán quan trọng nhất của câu này:

"Không có log lỗi ở đâu cả"
        ↓
    → vấn đề nằm ở tầng TRƯỚC nơi
      sinh log
        ↓
    Không phải ở trong mã ứng dụng

Bảng nơi có thể chặn trước khi tới Lambda: | Chốt | Dấu hiệu | |---|---| | Throttle của API Gateway | 429, không có log Lambda | | Quota của usage plan | 429, Limit Exceeded | | WAF chặn | 403, có log WAF | | Giới hạn đồng thời của Lambda | 429, CÓ metric Throttles |

⚠ Và phải đọc metric chứ không chỉ đọc log:

aws cloudwatch get-metric-statistics \
  --namespace AWS/ApiGateway --metric-name 4XXError \
  --dimensions Name=ApiName,Value=api-ban-hang \
  --statistics Sum --period 300 \
  --start-time 2026-09-01T00:00:00Z \
  --end-time 2026-09-01T23:59:59Z
aws cloudwatch get-metric-statistics \
  --namespace AWS/Lambda --metric-name Throttles \
  --dimensions Name=FunctionName,Value=xu-ly-don \
  --statistics Sum --period 300 \
  --start-time 2026-09-01T00:00:00Z \
  --end-time 2026-09-01T23:59:59Z

⚠ Và Lambda cũng có giới hạn đồng thời riêng — cần loại trừ:

Mặc định 1.000 lượt gọi đồng thời
  mỗi Region
        ↓
    Chia chung cho MỌI hàm trong
      Region đó
        ↓
    Đặt reserved concurrency cho hàm
      quan trọng
    → nhưng khi throttle ở đây thì
      metric `Throttles` KHÁC 0
aws lambda put-function-concurrency \
  --function-name xu-ly-don \
  --reserved-concurrent-executions 200

Ba việc nên làm sau khi tìm ra nguyên nhân: | Việc | Chi tiết | |---|---| | Nâng throttle ở stage và usage plan | | | Bật access log của API Gateway | | | Đặt cảnh báo cho metric 4XXError | |

Bật access log:

aws apigateway update-stage \
  --rest-api-id abc123 --stage-name prod \
  --patch-operations \
    op=replace,path=/accessLogSettings/destinationArn,value=<arn-log-group> \
    op=replace,path=/accessLogSettings/format,value='{"requestId":"$context.requestId","status":"$context.status","error":"$context.error.message"}'
Không bật access log thì không thấy
  429 ở đâu cả
        ↓
    Đây chính là lý do đội phát triển
      "không tìm thấy lỗi nào"

⚠ Và nên bật provisioned concurrency nếu đỉnh tải dự đoán được:

aws lambda put-provisioned-concurrency-config \
  --function-name xu-ly-don --qualifier prod \
  --provisioned-concurrent-executions 100
Giữ sẵn môi trường chạy nóng
        ↓
    Không có cold start khi đỉnh tới
    → nhưng trả tiền cả lúc rảnh

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

  • **B. NAT Gateway hết thời gian chờ khiến Lambda bị throttle — đây là phương án gần nhất và NAT Gateway thật sự có giới hạn 55.000 kết nối đồng thời tới mỗi đích, nhưng đề không nói Lambda nằm trong VPC, và nếu gọi ra ngoài thất bại thì Lambda sẽ ném ngoại lệ và ghi log.
  • **A. DynamoDB tắt gián đoạn do cấu hình auto scaling — DynamoDB là dịch vụ được quản lý, không "tắt"; thiếu công suất thì trả ngoại lệ có ghi log.
  • **D. Lambda cấu hình dưới 128 MB bộ nhớ — 128 MB là mức tối thiểu, không đặt thấp hơn được; và bộ nhớ không gây throttle.

Ghi nhớ

⚠ Bốn chốt throttle trong kiến trúc serverless — bảng phải thuộc: | Chốt | Giới hạn mặc định | |---|---| | API Gateway tài khoản | 10.000 req/giây, burst 5.000 | | API Gateway stage/method | do bạn đặt | | Usage plan | rate, burst, quota | | Lambda đồng thời | 1.000 mỗi Region |

Từ khoá nhận diện:

"no errors logged anywhere" → chặn trước khi tới ứng dụng "fails then eventually succeeds" → throttle + retry của SDK "429 Too Many Requests" → throttle hoặc quota "Throttles metric > 0" → giới hạn đồng thời của Lambda

Ba lưu ý về API Gateway: | Lưu ý | Chi tiết | |---|---| | Throttle đặt được ở nhiều tầng | | | Usage plan có cả quota theo ngày | | | Phải bật access log mới thấy 429 | |

Ba lưu ý về Lambda: | Lưu ý | Chi tiết | |---|---| | Bộ nhớ tối thiểu 128 MB, tối đa 10 GB | | | CPU tỷ lệ thuận với bộ nhớ | | | Reserved concurrency vừa bảo đảm vừa giới hạn | |

⚠ Reserved concurrency là con dao hai lưỡi:

Đặt reserved = 200
        ↓
    Bảo đảm hàm này luôn có 200 lượt
        ↓
    Nhưng cũng CHẶN nó ở 200
        ↓
    Và trừ 200 khỏi hạn mức chung của
      Region

Ba lưu ý về chẩn đoán: | Lưu ý | Chi tiết | |---|---| | Đọc metric trước, đọc log sau | | | Không có log ≠ không có lỗi | | | Bật access log ở mọi tầng | |

Ba lưu ý về giới hạn đồng thời: | Lưu ý | Chi tiết | |---|---| | Chia chung cho mọi hàm trong Region | | | Nâng được bằng yêu cầu tăng hạn ngạch | | | Provisioned concurrency bỏ được cold start | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Xem metric 4XXError của API Gateway | | | Xem metric Throttles của Lambda | | | Chạy thử tải với đỉnh dự kiến | |

Và một lời khuyên: hãy bật access log của API Gateway ngay từ ngày đầu. Toàn bộ khó khăn trong câu này đến từ việc đội phát triển chỉ có log Lambda để đọc — mà lỗi lại xảy ra ở tầng trước đó, nơi không ghi gì cả trừ khi bạn chủ động bật.

Câu 450 Chọn nhiều đáp án Design for New Solutions

An e-commerce company has a three-tier web application with separate subnets for Web, Application and Database tiers. The CTO at the company wants to monitor any malicious activity targeting the web application running on EC2 instances. As a solutions architect, you have been tasked with developing a solution to notify the security team in case the network exposure of EC2 instances on specific ports violates the security policies of the company.

Which AWS Services would you use to build an automated notification system to meet these requirements with the least development effort? (Select two)

  1. A

    Amazon Inspector

  2. B

    Amazon SNS

  3. C

    VPC Flow Logs

  4. D

    Amazon CloudWatch

  5. E

    AWS Shield

Xem giải thích

Đáp án

**A và B — Amazon Inspector và Amazon SNS.

Vì sao đúng

Đề nêu hai vế, và mỗi dịch vụ lo một vế: | Vế | Dịch vụ | |---|---| | Phát hiện EC2 lộ cổng ra ngoài | Amazon Inspector | | Báo cho đội bảo mật | Amazon SNS |

⚠ Điểm mấu chốt: Inspector có luật chuyên về khả năng tiếp cận mạng:

Network Reachability
        ↓
    Phân tích cấu hình mạng thực tế:
      security group, NACL, route
      table, Internet Gateway, ELB
        ↓
    Kết luận: cổng nào của instance
      này TIẾP CẬN ĐƯỢC từ Internet

⚠ Và nó phân tích cấu hình chứ không quét gói tin:

Không gửi lưu lượng thử
        ↓
    Không cần agent để làm việc này
        ↓
    Dựng đồ thị đường đi từ mọi nguồn
    → biết được ngay cả cổng chưa ai
      chạm tới
Khác hẳn VPC Flow Logs:
        ↓
    Flow Logs chỉ thấy lưu lượng ĐÃ
      XẢY RA
        ↓
    Cổng mở nhưng chưa ai gọi
    → Flow Logs không có dòng nào
    → mà đó chính là rủi ro cần biết

⚠ Và đó là lý do phương án C không đủ:

C dùng VPC Flow Logs
        ↓
    Phải tự viết truy vấn tìm mẫu bất
      thường
        ↓
    Phải tự định nghĩa thế nào là "vi
      phạm chính sách"
        ↓
    Đề nói "công sức phát triển ÍT
      NHẤT"
    → Flow Logs là nguyên liệu thô

Bật Inspector:

aws inspector2 enable \
  --resource-types EC2 ECR LAMBDA \
  --account-ids 111122223333

⚠ Và Inspector thế hệ 2 chạy liên tục, không cần lên lịch:

Bản cũ (Inspector Classic): tạo
  assessment template rồi chạy theo
  lịch
        ↓
    Bản mới (Inspector2): tự quét khi
      có thay đổi
        ↓
    Cài agent hay đổi security group
    → quét lại ngay

⚠ Và Network Reachability không cần SSM Agent: | Loại quét | Cần agent | |---|---| | Network Reachability | không | | Quét lỗ hổng phần mềm | có (SSM Agent) |

Đưa phát hiện sang SNS:

aws events put-rule --name canh-bao-inspector \
  --event-pattern '{
    "source": ["aws.inspector2"],
    "detail-type": ["Inspector2 Finding"],
    "detail": {"severity": ["HIGH", "CRITICAL"]}}'

aws events put-targets --rule canh-bao-inspector \
  --targets Id=1,Arn=<arn-sns-topic>

⚠ Và lọc theo mức nghiêm trọng là bắt buộc:

Không lọc
        ↓
    Đội bảo mật nhận hàng trăm thư
      mỗi ngày
        ↓
    Họ ngừng đọc
    → cảnh báo mất tác dụng hoàn toàn

⚠ Và vì sao phương án D chưa đủ:

D chọn CloudWatch
        ↓
    CloudWatch là nơi chứa metric và
      log
        ↓
    Nó không tự biết "cổng này lộ ra
      Internet là vi phạm"
        ↓
    Phải có ai đó sinh ra phát hiện
      trước
    → và đó là việc của Inspector

⚠ Và vì sao phương án E sai hoàn toàn:

E chọn AWS Shield
        ↓
    Shield chống DDoS
        ↓
    Nó không phát hiện cấu hình sai
        ↓
    Không liên quan tới việc "cổng nào
      đang lộ ra"

Bảng phân biệt bốn dịch vụ hay lẫn: | Dịch vụ | Việc | |---|---| | Inspector | lỗ hổng phần mềm + khả năng tiếp cận mạng | | GuardDuty | phát hiện hành vi đe doạ đang diễn ra | | Macie | tìm dữ liệu nhạy cảm trong S3 | | Security Hub | gom phát hiện từ mọi nguồn |

⚠ Và Config cũng là lựa chọn hợp lý cho bài toán này:

aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "chan-ssh-tu-internet",
  "Source": {"Owner": "AWS",
    "SourceIdentifier": "INCOMING_SSH_DISABLED"}}'
Config kiểm cấu hình theo luật
        ↓
    Có luật dựng sẵn cho cổng mở
        ↓
    Nhưng nó kiểm TỪNG tài nguyên
      riêng lẻ
        ↓
    Inspector dựng cả ĐƯỜNG ĐI mạng
    → thấy được cả trường hợp qua ELB
      hay qua peering

⚠ Và đây là khác biệt đáng nhớ nhất:

Security group cho phép 0.0.0.0/0
  cổng 22
        ↓
    Config: BÁO VI PHẠM
        ↓
    Nhưng instance nằm trong subnet
      riêng tư, không có đường ra
        ↓
    Inspector: KHÔNG báo, vì thực tế
      không tiếp cận được
    → ít báo động giả hơn nhiều

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không phải viết logic phát hiện | | | Phân tích đường đi thật, ít báo giả | | | Quét lại tự động khi cấu hình đổi | |

⚠ Và nên gom qua Security Hub nếu có nhiều tài khoản:

aws securityhub enable-security-hub \
  --enable-default-standards

aws securityhub create-members \
  --account-details AccountId=222233334444
Phát hiện của Inspector, GuardDuty,
  Macie đều đổ về đây
        ↓
    Một chỗ để xem
    → và một chỗ để gắn SNS

⚠ Và SNS nên có bộ lọc thay vì tạo nhiều topic:

aws sns set-subscription-attributes \
  --subscription-arn <arn-sub> \
  --attribute-name FilterPolicy \
  --attribute-value '{"severity": ["CRITICAL"]}'

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

  • **C. VPC Flow Logs — đây là phương án gần nhất và thật sự chứa dữ liệu về lưu lượng tới các cổng, nhưng nó chỉ ghi lại lưu lượng đã xảy ra, không phát hiện được cổng đang mở mà chưa ai chạm tới, và đòi tự viết toàn bộ logic phân tích.
  • **D. Amazon CloudWatch — là nơi chứa metric và log, không tự sinh ra phát hiện về mức độ lộ mạng.
  • **E. AWS Shield — chống DDoS, không liên quan tới việc phát hiện cấu hình mạng sai.

Ghi nhớ

⚠ Bốn dịch vụ bảo mật và việc của chúng — bảng phải thuộc: | Dịch vụ | Phát hiện gì | |---|---| | Inspector | lỗ hổng + cổng tiếp cận được | | GuardDuty | hành vi bất thường, IP xấu | | Config | cấu hình lệch chuẩn | | Macie | dữ liệu nhạy cảm trong S3 |

Từ khoá nhận diện:

"network exposure on specific ports" → Inspector Network Reachability "unusual API calls, crypto mining" → GuardDuty "resource configuration compliance" → Config "notify the team" → SNS qua EventBridge

Ba lưu ý về Inspector: | Lưu ý | Chi tiết | |---|---| | Network Reachability không cần agent | | | Quét lỗ hổng thì cần SSM Agent | | | Chạy liên tục, quét lại khi có thay đổi | |

Ba lưu ý về EventBridge: | Lưu ý | Chi tiết | |---|---| | Lọc theo severity trong event-pattern | | | Một luật gửi được nhiều đích | | | Đích có thể là SNS, Lambda, Step Functions | |

Ba lưu ý về SNS: | Lưu ý | Chi tiết | |---|---| | Filter policy trên từng subscription | | | Hỗ trợ email, SMS, HTTPS, SQS, Lambda | | | Bật mã hoá bằng KMS cho nội dung nhạy cảm | |

Ba lưu ý về nhiều tài khoản: | Lưu ý | Chi tiết | |---|---| | Chỉ định delegated administrator | | | Security Hub gom mọi phát hiện | | | Bật tự động cho tài khoản mới | |

Ba lưu ý về chống mệt mỏi cảnh báo: | Lưu ý | Chi tiết | |---|---| | Chỉ gửi mức HIGH và CRITICAL | | | Chặn phát hiện đã chấp nhận rủi ro | | | Gom báo cáo định kỳ cho mức thấp | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Mở tạm một cổng, xem có phát hiện không | | | Kiểm thư có tới hộp của đội bảo mật | | | Xem list-findings của Inspector | |

Và một lời khuyên: hãy lọc cảnh báo theo mức nghiêm trọng ngay từ khi dựng. Một hệ thống thông báo mà đội bảo mật đã ngừng đọc thì tệ hơn không có gì — vì nó tạo cảm giác đang được bảo vệ trong khi thực tế không ai nhìn.