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

Tìm thấy 1221 câu.

Câu 411 Continuous Improvement for Existing Solutions

A solutions architect at a retail company has configured a private hosted zone using Route 53. The architect needs to configure health checks for record sets within the private hosted zone that are associated with EC2 instances.

How can the architect build a solution to address the given use case?

  1. A

    Configure a Route 53 health check to a private IP associated with the instances inside the VPC to be checked

  2. B

    Configure a Route 53 health check that monitors an SNS topic which in turn notifies a CloudWatch alarm when the EC2 StatusCheckFailed metric fails

  3. C

    Configure a CloudWatch metric that checks the status of the EC2 StatusCheckFailed metric, add an alarm to the metric, and then configure a health check that monitors the state of the alarm

  4. D

    Configure a CloudWatch metric that checks the status of the EC2 StatusCheckFailed metric and then configure a health check that monitors the status of the metric

Xem giải thích

Đáp án

**C — Cấu hình một CloudWatch metric theo dõi chỉ số StatusCheckFailed của EC2, thêm một alarm cho chỉ số đó, rồi cấu hình một health check theo dõi TRẠNG THÁI CỦA ALARM.

Vì sao đúng

Đề nêu một ràng buộc kỹ thuật cứng:

Private hosted zone
        ↓
    Bản ghi trỏ tới EC2 trong VPC
      riêng
        ↓
    Health checker của Route 53 nằm
      NGOÀI VPC, gọi từ Internet
        ↓
    Không tới được endpoint riêng

⚠ Điểm mấu chốt: Route 53 có ba loại health check, và chỉ một loại dùng được ở đây: | Loại | Cơ chế | Dùng cho private | |---|---|---| | Endpoint | gọi HTTP/HTTPS/TCP từ Internet | KHÔNG | | Calculated | gộp health check con | gián tiếp | | CloudWatch alarm | đọc trạng thái alarm | CÓ |

Alarm nằm TRONG tài khoản của bạn
        ↓
    Route 53 đọc trạng thái alarm
      qua API nội bộ
        ↓
    Không cần gọi tới endpoint nào
    → hoạt động với tài nguyên riêng

Tạo alarm:

aws cloudwatch put-metric-alarm \
  --alarm-name may-chu-ung-dung-hong \
  --namespace AWS/EC2 \
  --metric-name StatusCheckFailed \
  --dimensions Name=InstanceId,Value=i-0abc123 \
  --statistic Maximum --period 60 \
  --evaluation-periods 2 --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --treat-missing-data breaching

Tạo health check trỏ vào alarm:

aws route53 create-health-check \
  --caller-reference $(uuidgen) \
  --health-check-config '{
    "Type": "CLOUDWATCH_METRIC",
    "AlarmIdentifier": {
      "Region": "ap-southeast-1",
      "Name": "may-chu-ung-dung-hong"},
    "InsufficientDataHealthStatus": "LastKnownStatus"}'

⚠ Và InsufficientDataHealthStatus là chi tiết quan trọng: | Giá trị | Nghĩa khi alarm thiếu dữ liệu | |---|---| | Healthy | coi là khoẻ | | Unhealthy | coi là hỏng | | LastKnownStatus | giữ trạng thái cuối cùng biết được |

Instance vừa khởi động, chưa có
  dữ liệu chỉ số
        ↓
    `Unhealthy` → Route 53 loại nó ra
      ngay
        ↓
    `LastKnownStatus` → giữ nguyên
      trạng thái trước
    → thường là lựa chọn an toàn

⚠ Và trạng thái alarm ánh xạ NGƯỢC sang trạng thái health check:

Alarm ở trạng thái OK
        ↓
    → Health check KHOẺ
        ↓
    Alarm ở trạng thái ALARM
        ↓
    → Health check HỎNG

⚠ Đây là lý do phải đặt alarm theo hướng "có vấn đề thì ALARM":

`StatusCheckFailed >= 1` → ALARM
        ↓
    Nghĩa là instance có vấn đề
        ↓
    Health check báo hỏng
    → Route 53 ngừng trả về bản ghi đó

⚠ Và vì sao phương án A không hoạt động:

A cấu hình health check tới IP RIÊNG
  của instance
        ↓
    Health checker của Route 53 ở
      ngoài VPC
        ↓
    Không định tuyến tới IP riêng được
    → health check luôn báo hỏng

⚠ Và vì sao phương án D thiếu một bước:

D nói health check theo dõi "trạng
  thái của CHỈ SỐ"
        ↓
    Route 53 không đọc chỉ số trực
      tiếp
        ↓
    Nó chỉ đọc trạng thái ALARM
    → phải có alarm ở giữa

⚠ Đây là điểm phân biệt giữa C và D — một từ quyết định:

D: health check → metric
        ↓
    C: health check → ALARM → metric
        ↓
    Chỉ C mô tả đúng kiến trúc

⚠ Và vì sao phương án B đảo ngược luồng:

B nói health check theo dõi một SNS
  topic, topic đó thông báo cho
  CloudWatch alarm
        ↓
    Luồng thật là ngược lại: alarm
      gửi thông báo TỚI SNS
        ↓
    Và Route 53 không theo dõi SNS
      topic

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không cần IP công khai cho instance | | | Phản ánh trạng thái nội bộ chính xác | | | Gộp được nhiều điều kiện vào một alarm | |

⚠ Và có thể dùng chỉ số tuỳ chỉnh cho kiểm tra sâu hơn:

import boto3
cw = boto3.client('cloudwatch')

def bao_cao_suc_khoe():
    khoe = kiem_tra_csdl() and kiem_tra_cache()
    cw.put_metric_data(
        Namespace='UngDung',
        MetricData=[{'MetricName': 'SucKhoe',
                     'Value': 1 if khoe else 0,
                     'Unit': 'None'}])
`StatusCheckFailed` chỉ biết máy
  có chạy không
        ↓
    Chỉ số tuỳ chỉnh biết ứng dụng
      có khoẻ không
    → chính xác hơn nhiều

⚠ Và hai loại status check của EC2 — phải phân biệt: | Chỉ số | Hỏng nghĩa là | |---|---| | StatusCheckFailed_System | hạ tầng AWS có vấn đề | | StatusCheckFailed_Instance | hệ điều hành trong máy có vấn đề | | StatusCheckFailed | một trong hai cái trên |

⚠ Và calculated health check gộp nhiều điều kiện:

aws route53 create-health-check \
  --caller-reference $(uuidgen) \
  --health-check-config '{
    "Type": "CALCULATED",
    "ChildHealthChecks": ["hc-may-1", "hc-may-2", "hc-may-3"],
    "HealthThreshold": 2}'
Khoẻ khi ít nhất 2 trong 3 máy khoẻ
        ↓
    Diễn đạt được logic nhóm
    → thay vì chỉ một máy

⚠ Và có thể đảo ngược health check để rút endpoint có kiểm soát:

{"Inverted": true}
Đặt alarm ở ALARM có chủ đích
        ↓
    Health check inverted → báo khoẻ
        ↓
    Hoặc ngược lại để rút endpoint
      khi bảo trì

⚠ Và alarm phải nằm cùng Region với khai báo trong health check:

"AlarmIdentifier": {"Region": "ap-southeast-1", ...}
Khai sai Region → Route 53 không
  tìm thấy alarm
        ↓
    Health check ở trạng thái
      Insufficient Data mãi mãi

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

  • **D. Cấu hình CloudWatch metric theo dõi StatusCheckFailed rồi cấu hình health check theo dõi trạng thái của CHỈ SỐ — đây là phương án gần nhất và chỉ khác đáp án đúng ở việc thiếu một bước, nhưng Route 53 không đọc chỉ số trực tiếp; nó chỉ đọc trạng thái của một CloudWatch alarm.
  • **A. Cấu hình health check tới IP riêng của instance trong VPC — health checker của Route 53 nằm ngoài VPC nên không tới được địa chỉ riêng.
  • **B. Health check theo dõi một SNS topic mà topic đó thông báo cho alarm — luồng bị đảo ngược, và Route 53 không theo dõi SNS topic.

Ghi nhớ

⚠ Ba loại health check của Route 53 — bảng phải thuộc: | Loại | Kiểm gì | Private endpoint | |---|---|---| | Endpoint | gọi HTTP/HTTPS/TCP | KHÔNG dùng được | | Calculated | gộp health check con | gián tiếp | | CloudWatch alarm | trạng thái alarm | CÓ |

Từ khoá nhận diện:

"health check for private hosted zone" → CloudWatch alarm health check "health check for public endpoint" → endpoint health check "combine multiple checks" → calculated health check "remove Region for maintenance" → inverted health check

Ba lưu ý về CloudWatch alarm health check: | Lưu ý | Chi tiết | |---|---| | Alarm phải cùng tài khoản | | | Khai đúng Region của alarm | | | InsufficientDataHealthStatus quyết định khi thiếu dữ liệu | |

⚠ Ánh xạ trạng thái:

Alarm OK → health check KHOẺ
Alarm ALARM → health check HỎNG
Alarm INSUFFICIENT_DATA
  → theo cấu hình

Ba lưu ý về treat-missing-data: | Giá trị | Nghĩa | |---|---| | missing | giữ trạng thái hiện tại | | notBreaching | coi là bình thường | | breaching | coi là vượt ngưỡng | | ignore | giữ nguyên trạng thái |

Ba lưu ý về private hosted zone: | Lưu ý | Chi tiết | |---|---| | Cần bật enableDnsSupport và enableDnsHostnames | | | Gắn được với nhiều VPC | | | Chỉ phân giải được từ VPC đã gắn | |

Ba lưu ý về failover routing: | Lưu ý | Chi tiết | |---|---| | PRIMARY và SECONDARY | | | Cả hai nên có health check | | | Bản ghi không có health check luôn coi là khoẻ | |

⚠ Và nếu MỌI bản ghi đều hỏng:

Route 53 coi TẤT CẢ đều khoẻ
        ↓
    Và trả về bình thường
        ↓
    "Fail open" thay vì trả về rỗng

Ba lưu ý về chỉ số tuỳ chỉnh: | Lưu ý | Chi tiết | |---|---| | Ứng dụng tự đẩy chỉ số lên CloudWatch | | | Kiểm được cả phụ thuộc bên trong | | | Chính xác hơn StatusCheckFailed | |

Ba lưu ý về alias record: | Lưu ý | Chi tiết | |---|---| | EvaluateTargetHealth tự đọc trạng thái ALB, NLB | | | Không cần health check riêng | | | Hoạt động cả trong private hosted zone | |

⚠ Với ALB nội bộ thì alias là cách đơn giản nhất:

Bản ghi alias trỏ tới ALB nội bộ
        ↓
    `EvaluateTargetHealth: true`
        ↓
    Route 53 đọc trạng thái target
      group
    → không cần alarm nào

Ba lưu ý về chi phí: | Loại health check | Giá xấp xỉ | |---|---| | Endpoint trong AWS | 0,50 USD/tháng | | Endpoint ngoài AWS | 0,75 USD/tháng | | CloudWatch alarm | 0,50 USD/tháng |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đặt alarm vào trạng thái ALARM thủ công | | | Xem health check chuyển sang hỏng | | | Kiểm Route 53 ngừng trả về bản ghi đó | |

Và một lời khuyên: hãy dùng chỉ số tuỳ chỉnh phản ánh sức khoẻ ứng dụng thay vì chỉ dựa vào StatusCheckFailed. Status check chỉ biết máy có chạy hay không — còn một ứng dụng mất kết nối tới cơ sở dữ liệu vẫn để máy chạy hoàn toàn bình thường, và đó chính là lúc bạn cần failover nhất.

Câu 412 Design Solutions for Organizational Complexity

A company has its web application hosted on Amazon EC2 instances that are deployed in a single AWS Region. The company has now expanded its operations into new geographies and the company wants to offer low-latency access for the application to its customers. To comply with different financial regulations of each geography, the application needs to operate in silos and the underlying instances in one region should not interact with instances running in other regions.

Which of the following represents the most optimal solution to automate the application deployment to different AWS regions?

  1. A

    Create a shell script that uses the AWS CLI to query the current state in one region and output an AWS CloudFormation template. Create a CloudFormation stack from the template by using the AWS CLI, specifying the --region parameter to deploy the application to other regions

  2. B

    Create a CloudFormation template describing the application infrastructure in the Resources section. Use CloudFormation stack set from an administrator account to launch stack instances that deploy the application to various other regions

  3. C

    Create a CloudFormation template describing the application infrastructure in the Resources section. Use CloudFormation change set from an administrator account to launch stack instances that deploy the application to various other regions

  4. D

    Create a CloudFormation template describing the application infrastructure in the Resources section. Create a CloudFormation stack from the template by using the AWS CLI, specify multiple regions using the --regions parameter to deploy the application

Xem giải thích

Đáp án

**B — Tạo một CloudFormation template mô tả hạ tầng ứng dụng trong phần Resources, rồi dùng CloudFormation StackSet từ tài khoản quản trị để khởi chạy các stack instance triển khai ứng dụng sang nhiều Region khác.

Vì sao đúng

Đề nêu hai yêu cầu, và StackSets đáp ứng cả hai: | Yêu cầu | Cách đáp ứng | |---|---| | Tự động triển khai sang nhiều Region | StackSets phân phối một template ra nhiều Region | | Các Region hoạt động độc lập, không tương tác | mỗi Region một stack riêng, tài nguyên riêng |

⚠ Điểm mấu chốt: --region chỉ nhận MỘT giá trị, không có --regions:

aws cloudformation create-stack \
  --stack-name ung-dung --region ap-southeast-1
Một lệnh = một Region
        ↓
    Không có tham số `--regions`
      dạng số nhiều
        ↓
    Phương án D mô tả một tham số
      không tồn tại

⚠ Và vì sao phương án A là cách làm thủ công:

A viết shell script truy vấn trạng
  thái hiện tại rồi SINH RA template
        ↓
    Đây là kỹ thuật "reverse
      engineering" hạ tầng
        ↓
    Script tự viết phải bảo trì
        ↓
    Và vẫn phải gọi lệnh cho từng
      Region

⚠ Và có công cụ chính thức cho việc sinh template:

aws cloudformation create-generated-template \
  --generated-template-name tu-tai-nguyen-hien-co \
  --resources file://danh-sach-tai-nguyen.json
IaC generator sinh template từ tài
  nguyên đã có
        ↓
    Nhưng đó là bước MỘT LẦN để bắt
      đầu
    → không phải cơ chế triển khai

Tạo StackSet:

aws cloudformation create-stack-set \
  --stack-set-name ung-dung-toan-cau \
  --template-body file://mau.yaml \
  --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
  --capabilities CAPABILITY_NAMED_IAM

Triển khai sang nhiều Region:

aws cloudformation create-stack-instances \
  --stack-set-name ung-dung-toan-cau \
  --regions ap-southeast-1 eu-west-1 us-east-1 sa-east-1 \
  --deployment-targets OrganizationalUnitIds=ou-abc123 \
  --operation-preferences \
    RegionConcurrencyType=PARALLEL,\
MaxConcurrentPercentage=50,\
FailureTolerancePercentage=0

⚠ --regions (số nhiều) tồn tại ở lệnh của StackSets — không phải ở create-stack:

`create-stack --region` : một Region
        ↓
    `create-stack-instances --regions`
      : nhiều Region
        ↓
    Đây chính là khác biệt giữa
      phương án B và D

⚠ Và operation-preferences kiểm soát cách triển khai: | Tham số | Tác dụng | |---|---| | RegionConcurrencyType | SEQUENTIAL hoặc PARALLEL | | MaxConcurrentPercentage | bao nhiêu tài khoản cùng lúc | | FailureTolerancePercentage | dừng khi bao nhiêu phần trăm lỗi |

`FailureTolerancePercentage: 0`
        ↓
    Một Region lỗi → dừng toàn bộ
        ↓
    Tránh lan lỗi ra mọi Region

⚠ Và triển khai tuần tự theo Region an toàn hơn:

`RegionConcurrencyType: SEQUENTIAL`
        ↓
    Triển khai xong Region này mới
      sang Region kia
        ↓
    Phát hiện lỗi sớm
    → chậm hơn nhưng an toàn hơn

⚠ Và vì sao phương án C sai — change set không triển khai sang Region khác:

Change set là bản XEM TRƯỚC thay đổi
  của MỘT stack
        ↓
    Nó cho biết tài nguyên nào sẽ
      tạo, sửa, xoá
        ↓
    Không phải cơ chế phân phối

⚠ Và change set vẫn rất hữu ích — chỉ khác mục đích:

aws cloudformation create-change-set \
  --stack-name ung-dung \
  --change-set-name xem-truoc \
  --template-body file://mau-moi.yaml

aws cloudformation describe-change-set \
  --change-set-name xem-truoc --stack-name ung-dung
Xem trước thay đổi trước khi áp
        ↓
    Phát hiện việc THAY THẾ tài
      nguyên (Replacement: True)
    → tránh xoá nhầm cơ sở dữ liệu

⚠ Và hai mô hình quyền của StackSets: | Mô hình | Đặc điểm | |---|---| | SELF_MANAGED | tự tạo vai trò AWSCloudFormationStackSetAdministrationRole và ExecutionRole | | SERVICE_MANAGED | dùng AWS Organizations, tự động cho tài khoản mới |

`SERVICE_MANAGED` với
  `AutoDeployment`
        ↓
    Tài khoản mới vào OU → tự nhận
      stack
        ↓
    Không phải làm gì thêm

⚠ Và yêu cầu "các Region không tương tác với nhau" được đáp ứng tự nhiên:

Mỗi Region một stack độc lập
        ↓
    Tài nguyên riêng, VPC riêng
        ↓
    Không có peering, không có
      replication
    → đúng yêu cầu cách ly theo quy
      định tài chính

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Một template, nhiều Region | | | Cập nhật đồng loạt bằng một lệnh | | | Kiểm soát được tốc độ và ngưỡng lỗi | |

⚠ Và cập nhật StackSet áp cho mọi instance:

aws cloudformation update-stack-set \
  --stack-set-name ung-dung-toan-cau \
  --template-body file://mau-v2.yaml \
  --operation-preferences \
    RegionConcurrencyType=SEQUENTIAL,\
FailureTolerancePercentage=0

⚠ Và tham số khác nhau theo Region dùng override:

aws cloudformation create-stack-instances \
  --stack-set-name ung-dung-toan-cau \
  --regions eu-west-1 \
  --accounts 111122223333 \
  --parameter-overrides \
    ParameterKey=CidrVpc,ParameterValue=10.2.0.0/16
Mỗi Region cần dải CIDR riêng
        ↓
    Hoặc cấu hình tuân thủ khác nhau
        ↓
    Override cho từng instance

⚠ Và có mapping trong template để tự chọn giá trị theo Region:

Mappings:
  CauHinhTheoRegion:
    ap-southeast-1:
      AMI: ami-0abc123
      Cidr: 10.1.0.0/16
    eu-west-1:
      AMI: ami-0def456
      Cidr: 10.2.0.0/16

Resources:
  MayChu:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [CauHinhTheoRegion, !Ref "AWS::Region", AMI]

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

  • **D. Tạo CloudFormation template và tạo stack bằng AWS CLI, khai nhiều Region qua tham số --regions — đây là phương án gần nhất và dùng đúng template, nhưng lệnh create-stack chỉ có tham số --region số ít; tham số --regions chỉ tồn tại ở lệnh của StackSets.
  • **A. Viết shell script truy vấn trạng thái và sinh ra template, rồi tạo stack cho từng Region — cách làm thủ công phải tự bảo trì, và vẫn phải gọi lệnh cho từng Region.
  • **C. Dùng change set để khởi chạy stack instance sang các Region — change set là bản xem trước thay đổi của một stack, không phải cơ chế phân phối.

Ghi nhớ

⚠ Ba khái niệm của CloudFormation dễ nhầm — bảng phải thuộc: | Khái niệm | Việc | |---|---| | Stack | một tập tài nguyên trong một tài khoản, một Region | | StackSet | phân phối stack ra nhiều tài khoản, nhiều Region | | Change set | xem trước thay đổi của một stack |

Từ khoá nhận diện:

"deploy to multiple Regions/accounts" → StackSets "preview changes before applying" → change set "new accounts automatically get the stack" → SERVICE_MANAGED + AutoDeployment "different values per Region" → parameter override hoặc Mappings

Ba lưu ý về StackSets: | Lưu ý | Chi tiết | |---|---| | Hai mô hình quyền: self-managed và service-managed | | | FailureTolerance chặn lan lỗi | | | Triển khai tuần tự hoặc song song theo Region | |

⚠ Self-managed cần hai vai trò:

Tài khoản quản trị:
  AWSCloudFormationStackSetAdministrationRole
        ↓
    Tài khoản đích:
  AWSCloudFormationStackSetExecutionRole
        ↓
    Vai trò thứ hai tin cậy vai trò
      thứ nhất

Ba lưu ý về change set: | Lưu ý | Chi tiết | |---|---| | Cho biết tài nguyên nào bị THAY THẾ | | | Không tính phí | | | Nên xem trước mọi lần cập nhật sản xuất | |

⚠ Cột Replacement là thứ phải đọc kỹ:

`Replacement: True`
        ↓
    Tài nguyên sẽ bị XOÁ và tạo lại
        ↓
    Với RDS hoặc EBS → mất dữ liệu
    → dừng lại và xem xét

Ba lưu ý về bảo vệ tài nguyên: | Cơ chế | Tác dụng | |---|---| | DeletionPolicy: Retain | giữ tài nguyên khi xoá stack | | UpdateReplacePolicy: Retain | giữ khi bị thay thế | | Stack policy | chặn cập nhật tài nguyên cụ thể |

Ba lưu ý về nested stack: | Lưu ý | Chi tiết | |---|---| | Chia template lớn thành nhiều phần | | | Dùng lại được giữa các dự án | | | Cập nhật stack cha cập nhật cả con | |

Ba lưu ý về drift: | Lưu ý | Chi tiết | |---|---| | Sửa tay qua console gây drift | | | detect-stack-drift phát hiện | | | StackSets cũng có drift detection | |

Ba lưu ý về CDK: | Lưu ý | Chi tiết | |---|---| | Viết bằng TypeScript, Python... | | | Sinh ra CloudFormation ở phía dưới | | | CDK Pipelines triển khai nhiều Region | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | describe-stack-set-operation xem tiến độ | | | Kiểm stack tồn tại ở mọi Region đích | | | Chạy drift detection định kỳ | |

Và một lời khuyên: hãy đặt FailureTolerancePercentage: 0 cho lần triển khai đầu tiên. StackSets sẽ dừng ngay khi Region đầu tiên gặp lỗi thay vì tiếp tục và để lại một tập hạ tầng nửa vời rải rác khắp thế giới — mà việc dọn dẹp thứ đó tốn nhiều thời gian hơn cả việc triển khai lại từ đầu.

Câu 413 Accelerate Workload Migration and Modernization

An e-commerce company traditionally hosted its application APIs on Amazon EC2 instances. Recently, the company has started migrating to a serverless architecture that is built using Amazon API Gateway, AWS Lambda functions, and Amazon DynamoDB. The Lambda functions and EC2 instances share the same Virtual Private Cloud (VPC). The Lambda functions hold the logic to fetch data from a third-party service provider.

After moving a portion of functionality to the serverless model, users have started complaining of API Gateway 5XX errors. The third-party service provider is unable to see any requests from the serverless architecture. Upon inspection, the development team can see that the Lambda functions have created some entries in the generated logs.

Which solution would you recommend to troubleshoot this issue?

  1. A

    API Gateway does not have the necessary permissions to invoke Lambda

  2. B

    Increase the concurrency limit for Lambda function to cater to the high user traffic

  3. C

    Create a request limit increase for API Gateway

  4. D

    NAT Gateway has to be configured to give internet access to the Amazon VPC connected Lambda function

Xem giải thích

Đáp án

**D — Phải cấu hình NAT gateway để hàm Lambda đã gắn vào VPC có đường ra Internet.

Vì sao đúng

Đề cho ba manh mối, ghép lại chỉ ra đúng một nguyên nhân:

Lambda có tạo được log
        ↓
    → hàm ĐÃ CHẠY, không phải bị
      chặn hay thiếu quyền
        ↓
    Bên thứ ba KHÔNG thấy yêu cầu nào
        ↓
    → lời gọi ra ngoài không tới nơi
        ↓
    Lambda chung VPC với EC2
    → hàm đã được gắn vào VPC

⚠ Điểm mấu chốt: gắn Lambda vào VPC là MẤT đường ra Internet:

Mặc định: Lambda chạy trong VPC do
  AWS quản
        ↓
    Có đường ra Internet sẵn
        ↓
    Gắn vào VPC của bạn
    → ENI nằm trong subnet của bạn
    → và ENI đó KHÔNG có IP công khai

⚠ Và đây là điều nhiều người không lường trước:

Gắn Lambda vào VPC để truy cập RDS
        ↓
    Bỗng nhiên nó không gọi được API
      bên ngoài nữa
        ↓
    Không có lỗi rõ ràng
    → chỉ là timeout sau vài chục giây

⚠ Và đặt Lambda vào subnet CÔNG KHAI cũng không giúp:

Lambda ENI không nhận IP công khai
        ↓
    Dù subnet có route tới internet
      gateway
        ↓
    Internet gateway cần IP công khai
      để NAT
    → không có thì không đi ra được
        ↓
    Phải đặt Lambda ở subnet RIÊNG
      và đi qua NAT gateway

Kiến trúc đúng:

Lambda ENI ở private subnet
        ↓
    Route mặc định → NAT gateway
        ↓
    NAT gateway ở public subnet
        ↓
    Route → internet gateway
        ↓
    Ra Internet

Tạo NAT gateway và route:

aws ec2 allocate-address --domain vpc

aws ec2 create-nat-gateway \
  --subnet-id subnet-cong-khai-1a \
  --allocation-id eipalloc-abc123

aws ec2 create-route --route-table-id rtb-rieng \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id nat-abc123

⚠ Và mã lỗi 5XX của API Gateway khớp với chẩn đoán:

Lambda timeout khi gọi bên thứ ba
        ↓
    Hàm chạy hết thời gian
        ↓
    API Gateway trả 502 hoặc 504
        ↓
    Nhưng log Lambda VẪN CÓ
    → vì hàm đã bắt đầu chạy

⚠ Và vì sao phương án A sai — quyền thì log đã không có:

API Gateway thiếu quyền gọi Lambda
        ↓
    Lambda KHÔNG BAO GIỜ chạy
        ↓
    Không có log nào
        ↓
    Đề nói có log
    → quyền không phải vấn đề

Kiểm quyền gọi Lambda:

aws lambda get-policy --function-name ham-api \
  --query 'Policy' --output text | python3 -m json.tool

⚠ Và vì sao phương án B sai — bị chặn thì cũng không có log:

Lambda bị chặn (throttled)
        ↓
    Hàm không được gọi
        ↓
    Chỉ số `Throttles` tăng
    → nhưng không có log thực thi
        ↓
    Và bên thứ ba cũng không thấy gì
    → nhưng nguyên nhân khác hẳn

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

API Gateway bị chặn tần suất
        ↓
    Trả về 429 Too Many Requests
        ↓
    Không phải 5XX
        ↓
    Đề nói rõ lỗi 5XX

⚠ Và ba mã lỗi của API Gateway — phải phân biệt: | Mã | Nghĩa | |---|---| | 429 | vượt hạn mức tần suất | | 502 Bad Gateway | Lambda trả định dạng sai hoặc lỗi | | 504 Gateway Timeout | tích hợp quá 29 giây |

Ba lợi ích của việc dựng NAT gateway: | Lợi ích | Chi tiết | |---|---| | Lambda gọi được API bên ngoài | | | Vẫn truy cập được tài nguyên trong VPC | | | Địa chỉ đi ra cố định, thêm vào allowlist được | |

⚠ Và địa chỉ cố định là lợi ích phụ quan trọng:

Bên thứ ba yêu cầu khai IP nguồn
        ↓
    Lambda ngoài VPC: IP thay đổi
      liên tục
        ↓
    Qua NAT gateway: một Elastic IP
      cố định
    → khai vào allowlist được

⚠ Nhưng NAT gateway tốn tiền — cần tính:

~0,045 USD/giờ + 0,045 USD/GB xử lý
        ↓
    Chạy 24/7 ≈ 32 USD/tháng mỗi cái
        ↓
    Ba AZ → ba NAT gateway
        ↓
    Cân nhắc một NAT nếu chấp nhận
      rủi ro AZ

⚠ Và VPC endpoint bỏ được NAT cho dịch vụ AWS:

aws ec2 create-vpc-endpoint --vpc-id vpc-abc \
  --service-name com.amazonaws.ap-southeast-1.dynamodb \
  --vpc-endpoint-type Gateway \
  --route-table-ids rtb-rieng
Gateway endpoint cho S3 và DynamoDB
  MIỄN PHÍ
        ↓
    Lưu lượng không qua NAT
    → giảm mạnh phí xử lý GB
        ↓
    Nhưng API bên thứ ba vẫn cần NAT

⚠ Và câu hỏi cần đặt trước: Lambda có THẬT SỰ cần ở trong VPC không?

Lambda gọi DynamoDB và API bên
  thứ ba
        ↓
    Cả hai đều là endpoint công khai
        ↓
    Không cần vào VPC chút nào
    → gỡ khỏi VPC là giải pháp rẻ
      nhất
Chỉ gắn vào VPC khi cần truy cập:
    - RDS trong private subnet
    - ElastiCache
    - EC2 nội bộ
    - endpoint chỉ có trong VPC

⚠ Và Lambda trong VPC nay không còn chậm như trước:

Trước 2019: mỗi môi trường thực thi
  tạo một ENI
        ↓
    Khởi động nguội tới 10 giây
        ↓
    Nay: Hyperplane ENI dùng chung
    → khởi động nguội gần như không
      khác gì ngoài VPC

⚠ Và cần đủ IP trong subnet cho Lambda:

Lambda dùng ENI trong subnet
        ↓
    Đồng thời cao → cần nhiều IP
        ↓
    Subnet /28 chỉ có 11 IP dùng được
    → hết IP thì hàm không chạy được
        ↓
    Dùng subnet đủ lớn

Chẩn đoán bằng cách thử từ trong hàm:

import urllib.request

def xu_ly(event, context):
    try:
        r = urllib.request.urlopen(
            'https://api.doi-tac.com/kiem-tra', timeout=5)
        return {'ma': r.status}
    except Exception as e:
        print(f'Loi ket noi: {e}')
        raise

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

  • **B. Tăng giới hạn đồng thời cho Lambda để chịu lưu lượng cao — đây là phương án gần nhất và thật sự gây ra lỗi 5XX ở API Gateway, nhưng khi bị chặn thì hàm không chạy nên không có log; đề nói rõ Lambda đã tạo được log.
  • **A. API Gateway thiếu quyền gọi Lambda — nếu vậy thì hàm không bao giờ chạy và không có log nào.
  • **C. Xin tăng hạn mức yêu cầu cho API Gateway — vượt hạn mức trả về 429 chứ không phải 5XX.

Ghi nhớ

⚠ Bốn hệ quả khi gắn Lambda vào VPC — bảng phải thuộc: | Hệ quả | Chi tiết | |---|---| | Mất đường ra Internet | cần NAT gateway | | Cần đủ IP trong subnet | mỗi ENI một IP | | Truy cập được tài nguyên trong VPC | RDS, ElastiCache | | Vẫn gọi được dịch vụ AWS | qua NAT hoặc VPC endpoint |

Từ khoá nhận diện:

"Lambda logs exist but external call fails" → thiếu NAT gateway "no Lambda logs at all" → quyền hoặc throttle "429 Too Many Requests" → hạn mức API Gateway "504 Gateway Timeout" → tích hợp quá 29 giây

Ba lưu ý về Lambda trong VPC: | Lưu ý | Chi tiết | |---|---| | Đặt ở private subnet, không phải public | | | Cần NAT gateway để ra Internet | | | VPC endpoint cho dịch vụ AWS thì rẻ hơn | |

⚠ Ba VPC endpoint hay dùng cho Lambda:

com.amazonaws.<region>.s3 (gateway, miễn phí)
com.amazonaws.<region>.dynamodb (gateway, miễn phí)
com.amazonaws.<region>.secretsmanager (interface)

Ba lưu ý về NAT gateway: | Lưu ý | Chi tiết | |---|---| | Đặt trong PUBLIC subnet | | | Chỉ cho lưu lượng đi ra | | | Một NAT mỗi AZ để chịu lỗi | |

Ba lưu ý về chẩn đoán Lambda: | Việc | Cách | |---|---| | Xem log trong CloudWatch Logs | có log = hàm đã chạy | | Xem chỉ số Throttles | có = bị chặn | | Bật X-Ray | thấy lời gọi nào chậm hoặc lỗi |

⚠ X-Ray chỉ ra ngay đoạn nào treo:

from aws_xray_sdk.core import patch_all
patch_all()
Tự đo mọi lời gọi HTTP và SDK
        ↓
    Thấy lời gọi tới bên thứ ba
      treo 30 giây
    → chẩn đoán trong vài giây

Ba lưu ý về timeout: | Thành phần | Timeout | |---|---| | API Gateway | 29 giây (cứng) | | Lambda | tối đa 15 phút | | Lời gọi HTTP trong hàm | tự đặt, nên ngắn |

⚠ Đặt timeout ngắn cho lời gọi bên ngoài:

Không đặt timeout
        ↓
    Lời gọi treo tới khi Lambda hết
      giờ
        ↓
    Tốn tiền và không có thông tin
    → đặt 5-10 giây và bắt lỗi

Ba lưu ý về chi phí: | Khoản | Giá xấp xỉ | |---|---| | NAT gateway | 0,045 USD/giờ + 0,045 USD/GB | | Interface endpoint | 0,01 USD/giờ mỗi AZ + 0,01 USD/GB | | Gateway endpoint | miễn phí |

Ba lưu ý về thiết kế: | Lưu ý | Chi tiết | |---|---| | Chỉ gắn Lambda vào VPC khi thật sự cần | | | Dùng subnet đủ lớn cho đồng thời cao | | | RDS Proxy nếu Lambda gọi cơ sở dữ liệu | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gọi thử một URL công khai từ trong hàm | | | Kiểm route table của subnet chứa Lambda | | | Chạy Reachability Analyzer từ ENI của Lambda | |

Và một lời khuyên: hãy hỏi lại xem hàm Lambda có thật sự cần nằm trong VPC hay không. Rất nhiều hàm được gắn vào VPC chỉ vì "cho đồng bộ với phần còn lại", và cái giá phải trả là một NAT gateway chạy 24/7 cùng với chính lớp lỗi mà bạn vừa mất thời gian chẩn đoán.

Câu 414 Design for New Solutions

A data analytics company leverages Amazon QuickSight (Enterprise Edition) for creating and publishing interactive BI dashboards that can be accessed from any device. For a new requirement, the company must create a private connection from Amazon QuickSight to an Amazon RDS DB instance that's in a private subnet to fetch data for analysis.

Which is the BEST solution for configuring a private connection between QuickSight and Amazon RDS DB instance?

  1. A

    Create a new private subnet in the same VPC as the Amazon RDS DB instance. Create a new network Access Control List (ACL) with necessary inbound rules for QuickSight in the same VPC. Connect from QuickSight using a VPC connector

  2. B

    Create a new private subnet in the same VPC as the Amazon RDS DB instance. Create a new security group with necessary inbound rules for QuickSight in the same VPC. Sign in to QuickSight as a QuickSight admin and create a new QuickSight VPC connection. Create a new dataset from the RDS DB instance

  3. C

    Amazon QuickSight Enterprise edition is fully integrated with the Amazon VPC service. Create an ENI in QuickSight that points to the VPC that hosts the RDS DB instance. However, the subnet has to be a private subnet and not a public subnet

  4. D

    Create a Private Virtual Interface between VPC that hosts Amazon RDS DB instance and QuickSight. Use this connection to privately access necessary data from RDS DB

Xem giải thích

Đáp án

**B — Tạo một private subnet mới trong cùng VPC với RDS DB instance; tạo một security group có quy tắc vào cần thiết cho QuickSight trong cùng VPC đó; đăng nhập QuickSight bằng tài khoản quản trị và tạo một QuickSight VPC connection mới; rồi tạo dataset từ RDS DB instance.

Vì sao đúng

Đề nêu một bài toán rất cụ thể:

QuickSight là dịch vụ chạy TRONG
  tài khoản AWS do AWS quản
        ↓
    RDS nằm trong private subnet
        ↓
    QuickSight không tới được bằng
      đường công khai
        ↓
    → cần một cơ chế kết nối riêng

⚠ Điểm mấu chốt: QuickSight VPC connection tạo một ENI trong VPC của bạn:

Tạo VPC connection
        ↓
    QuickSight dựng một elastic
      network interface trong subnet
      bạn khai
        ↓
    Từ ENI đó, QuickSight kết nối
      tới RDS bằng IP riêng

Tạo VPC connection:

aws quicksight create-vpc-connection \
  --aws-account-id 111122223333 \
  --vpc-connection-id ket-noi-rds \
  --name "Ket noi toi RDS" \
  --subnet-ids subnet-1a subnet-1b \
  --security-group-ids sg-quicksight \
  --role-arn arn:aws:iam::111122223333:role/QuickSightVPCRole

⚠ Và cần tối thiểu HAI subnet ở HAI AZ:

QuickSight yêu cầu ít nhất 2 subnet
        ↓
    Ở hai Availability Zone khác nhau
        ↓
    Để bảo đảm tính sẵn sàng
    → một AZ hỏng vẫn kết nối được

⚠ Và security group phải cấu hình theo hai chiều:

aws ec2 authorize-security-group-egress \
  --group-id sg-quicksight \
  --protocol tcp --port 3306 --source-group sg-rds

aws ec2 authorize-security-group-ingress \
  --group-id sg-rds \
  --protocol tcp --port 3306 --source-group sg-quicksight
Security group của QuickSight: cho
  phép ĐI RA tới RDS
        ↓
    Security group của RDS: cho phép
      ĐI VÀO từ QuickSight
        ↓
    Thiếu một chiều → kết nối treo

⚠ Và đây là lý do phương án A sai — NACL không thay được security group:

A nói tạo NETWORK ACL với quy tắc
  vào cho QuickSight
        ↓
    NACL áp ở tầng SUBNET
        ↓
    Nhưng QuickSight VPC connection
      cần một SECURITY GROUP gắn vào
      ENI của nó
        ↓
    Không khai được NACL thay

⚠ Và NACL còn là stateless — dễ cấu hình thiếu:

NACL phải mở cả chiều vào lẫn chiều
  ra
        ↓
    Kể cả dải cổng tạm 1024-65535
        ↓
    Security group stateful nên đơn
      giản hơn nhiều

⚠ Và vì sao phương án C sai — không tự tạo ENI trong QuickSight được:

C nói "tạo một ENI trong QuickSight
  trỏ tới VPC"
        ↓
    Không có thao tác nào như vậy
        ↓
    Bạn tạo VPC CONNECTION, và
      QuickSight tự dựng ENI
        ↓
    Chiều ngược lại

⚠ Và vì sao phương án D sai — private VIF thuộc Direct Connect:

Private virtual interface là khái
  niệm của Direct Connect
        ↓
    Nó nối trung tâm dữ liệu tại chỗ
      với VPC
        ↓
    QuickSight là dịch vụ AWS
    → không có customer gateway nào
      để nối

⚠ Và IAM role cho VPC connection cần quyền quản ENI:

{"Effect": "Allow",
 "Action": ["ec2:CreateNetworkInterface",
            "ec2:ModifyNetworkInterfaceAttribute",
            "ec2:DeleteNetworkInterface",
            "ec2:DescribeSubnets",
            "ec2:DescribeSecurityGroups"],
 "Resource": "*"}

Tạo dataset từ RDS:

aws quicksight create-data-source \
  --aws-account-id 111122223333 \
  --data-source-id nguon-rds \
  --name "CSDL nghiep vu" \
  --type MYSQL \
  --data-source-parameters '{"RdsParameters": {
    "InstanceId": "csdl-nghiep-vu",
    "Database": "phan_tich"}}' \
  --vpc-connection-properties '{
    "VpcConnectionArn": "<arn-ket-noi>"}' \
  --credentials '{"CredentialPair": {
    "Username": "quicksight_ro", "Password": "..."}}'

⚠ Và VPC connection chỉ có ở Enterprise Edition: | Tính năng | Standard | Enterprise | |---|---|---| | VPC connection | KHÔNG | CÓ | | Row-level security | không | CÓ | | Nhúng bảng điều khiển | không | CÓ | | Tích hợp Active Directory | không | CÓ |

Đề nói rõ Enterprise Edition
    → VPC connection dùng được

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | RDS vẫn nằm trong private subnet | | | Không phải mở cổng ra Internet | | | Security group kiểm soát chính xác | |

⚠ Và nên tạo một người dùng CSDL chỉ đọc cho QuickSight:

CREATE USER 'quicksight_ro'@'%' IDENTIFIED BY '...';
GRANT SELECT ON phan_tich.* TO 'quicksight_ro'@'%';
QuickSight chỉ cần đọc
        ↓
    Cấp quyền tối thiểu
    → tránh rủi ro nếu credential lộ

⚠ Và SPICE giảm tải cho cơ sở dữ liệu:

Direct query: mỗi lần mở bảng điều
  khiển là một truy vấn tới RDS
        ↓
    Nhiều người xem → tải lớn
        ↓
    SPICE: nạp dữ liệu vào bộ nhớ
      của QuickSight
    → làm mới theo lịch
    → bảng phản hồi tức thì
aws quicksight create-ingestion \
  --aws-account-id 111122223333 \
  --data-set-id bo-du-lieu-ban-hang \
  --ingestion-id lam-moi-$(date +%s)

⚠ Và làm mới SPICE theo lịch:

aws quicksight create-refresh-schedule \
  --aws-account-id 111122223333 \
  --data-set-id bo-du-lieu-ban-hang \
  --schedule '{
    "ScheduleId": "hang-ngay",
    "ScheduleFrequency": {"Interval": "DAILY",
      "TimeOfTheDay": "02:00"},
    "RefreshType": "FULL_REFRESH"}'

⚠ Và cần đủ IP trong subnet cho ENI:

Mỗi VPC connection dùng một ENI
  mỗi subnet
        ↓
    Subnet nhỏ đã gần hết IP
    → tạo connection thất bại
        ↓
    Đây là lý do đề nói tạo subnet MỚI

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

  • **A. Tạo private subnet mới và một network ACL có quy tắc vào cho QuickSight, rồi kết nối bằng VPC connector — đây là phương án gần nhất và cấu trúc mạng hoàn toàn đúng, nhưng QuickSight VPC connection yêu cầu một security group gắn vào ENI của nó, không phải NACL.
  • **C. Tạo một ENI trong QuickSight trỏ tới VPC — không có thao tác đó; bạn tạo VPC connection và QuickSight tự dựng ENI.
  • **D. Tạo một Private Virtual Interface giữa VPC và QuickSight — private VIF là khái niệm của Direct Connect, dùng để nối trung tâm dữ liệu tại chỗ với VPC.

Ghi nhớ

⚠ Bốn cách QuickSight kết nối tới nguồn dữ liệu — bảng phải thuộc: | Nguồn | Cách kết nối | |---|---| | RDS trong private subnet | VPC connection | | Redshift công khai | trực tiếp, mở SG cho dải IP QuickSight | | S3, Athena | trực tiếp qua IAM | | CSDL tại chỗ | VPC connection + Direct Connect/VPN |

Từ khoá nhận diện:

"QuickSight to private RDS" → VPC connection + security group "row-level security" → Enterprise Edition "embed dashboard in app" → Enterprise Edition "fast dashboards, reduce DB load" → SPICE

Ba lưu ý về VPC connection: | Lưu ý | Chi tiết | |---|---| | Cần tối thiểu 2 subnet ở 2 AZ | | | Cần IAM role quản ENI | | | Chỉ có ở Enterprise Edition | |

Ba lưu ý về security group: | Lưu ý | Chi tiết | |---|---| | SG của QuickSight cho phép đi RA tới CSDL | | | SG của CSDL cho phép đi VÀO từ QuickSight | | | Tham chiếu SG thay vì CIDR | |

⚠ Nếu không dùng VPC connection thì phải mở theo dải IP:

QuickSight có dải IP công khai riêng
  cho mỗi Region
        ↓
    Mở security group của RDS cho dải
      đó
        ↓
    Nhưng RDS phải công khai
    → kém an toàn hơn nhiều

Ba lưu ý về SPICE: | Lưu ý | Chi tiết | |---|---| | Dung lượng tính theo GB, mua thêm được | | | Làm mới theo lịch hoặc theo API | | | Incremental refresh cho dữ liệu lớn | |

⚠ Incremental refresh chỉ nạp phần mới:

{"RefreshType": "INCREMENTAL_REFRESH",
 "LookbackWindow": {"ColumnName": "ngay_cap_nhat",
                    "Size": 7, "SizeUnit": "DAY"}}
Chỉ nạp 7 ngày gần nhất
        ↓
    Nhanh hơn nhiều so với nạp lại
      toàn bộ

Ba lưu ý về bảo mật: | Lưu ý | Chi tiết | |---|---| | Người dùng CSDL chỉ đọc | | | Row-level security theo người xem | | | Credential lưu trong Secrets Manager | |

Ba lưu ý về chi phí: | Khoản | Ghi chú | |---|---| | Author | theo người dùng mỗi tháng | | Reader | theo phiên hoặc gói cố định | | SPICE | theo GB dung lượng |

⚠ Reader tính theo phiên rất tiết kiệm:

0,30 USD mỗi phiên 30 phút
        ↓
    Trần 5 USD mỗi người mỗi tháng
        ↓
    Người xem thỉnh thoảng → rẻ hơn
      gói cố định nhiều

Ba lưu ý về nhúng bảng điều khiển: | Lưu ý | Chi tiết | |---|---| | Enterprise Edition mới nhúng được | | | Sinh URL nhúng qua API | | | Kiểm soát quyền theo người dùng | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tạo dataset và xem có kết nối được không | | | Kiểm ENI đã xuất hiện trong subnet | | | Xem VPC Flow Log xác nhận lưu lượng tới RDS | |

Và một lời khuyên: hãy cấu hình cả hai chiều của security group ngay từ đầu. QuickSight VPC connection cần quy tắc đi ra ở phía nó và quy tắc đi vào ở phía cơ sở dữ liệu — thiếu một chiều cho ra đúng một triệu chứng là kết nối treo tới khi hết thời gian chờ, không kèm bất kỳ thông báo nào cho biết bên nào chặn.

Câu 415 Design for New Solutions

The development team at a company has noticed issues with the Quality of Service (QoS) in the traffic to the EC2 instances hosting a VOIP program. The team needs to inspect the network packets to determine if it is a programming error or a networking error.

As an AWS Certified Solutions Architect Professional, which of the following options would you suggest for the given use case?

  1. A

    Use CloudWatch to inspect the network packets

  2. B

    Use VPC Flow Logs to inspect the network packets

  3. C

    Provision another EC2 instance with an ENI added to act as a monitoring interface. Configure the port to promiscuous mode and sniff the traffic to analyze the packets. Direct the output of this single stream to an S3 bucket for further analysis

  4. D

    Configure traffic mirroring on the source EC2 instances hosting the VOIP program, set up a network monitoring program on a target EC2 instance and stream the logs to an S3 bucket for further analysis

Xem giải thích

Đáp án

**D — Cấu hình traffic mirroring trên các EC2 instance nguồn đang chạy chương trình VOIP, dựng một chương trình giám sát mạng trên một EC2 đích, và đẩy log sang bucket S3 để phân tích.

Vì sao đúng

Đề nêu một yêu cầu rất cụ thể:

Cần KIỂM TRA GÓI TIN mạng
        ↓
    Để phân biệt lỗi lập trình với
      lỗi mạng
        ↓
    Vấn đề là Quality of Service của
      VOIP
        ↓
    → cần thấy NỘI DUNG gói tin, không
      chỉ siêu dữ liệu

⚠ Điểm mấu chốt: chỉ VPC Traffic Mirroring cho phép xem nội dung gói tin: | Công cụ | Thấy gì | |---|---| | VPC Flow Log | IP, cổng, byte, ACCEPT/REJECT | | CloudWatch | chỉ số tổng hợp | | Traffic Mirroring | TOÀN BỘ gói tin, cả header lẫn payload |

Chẩn đoán jitter và mất gói của
  VOIP
        ↓
    Cần xem dấu thời gian, số thứ tự
      RTP, jitter thật
        ↓
    Flow log không có những thứ đó

⚠ Và đây là lý do phương án B không đủ:

VPC Flow Log ghi mỗi luồng một dòng
        ↓
    Không có nội dung, không có từng
      gói
        ↓
    Biết được "có lưu lượng" và
      "bị chặn hay không"
    → không biết chất lượng ra sao

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

CloudWatch thu thập CHỈ SỐ và LOG
        ↓
    Không phải công cụ bắt gói tin
        ↓
    Nó không có khái niệm packet
      capture

Cấu hình traffic mirroring:

aws ec2 create-traffic-mirror-target \
  --network-interface-id eni-giam-sat \
  --description "May giam sat VOIP"

aws ec2 create-traffic-mirror-filter \
  --description "Loc luu luong VOIP"

aws ec2 create-traffic-mirror-filter-rule \
  --traffic-mirror-filter-id tmf-abc \
  --traffic-direction ingress --rule-number 100 \
  --rule-action accept --protocol 17 \
  --destination-port-range FromPort=10000,ToPort=20000

aws ec2 create-traffic-mirror-session \
  --network-interface-id eni-nguon \
  --traffic-mirror-target-id tmt-abc \
  --traffic-mirror-filter-id tmf-abc \
  --session-number 1 \
  --packet-length 1500

⚠ Và packet-length quyết định bắt bao nhiêu byte mỗi gói:

Không khai → bắt TOÀN BỘ gói
        ↓
    Lưu lượng nhân đôi
        ↓
    Khai 128 byte → chỉ bắt header
    → đủ để phân tích luồng, ít tốn
      băng thông hơn nhiều

⚠ Và bộ lọc là thứ giữ chi phí trong tầm kiểm soát:

Mirror toàn bộ lưu lượng
        ↓
    Nhân đôi băng thông của instance
        ↓
    Lọc theo cổng RTP (10000-20000)
    → chỉ bắt đúng lưu lượng VOIP

⚠ Và vì sao phương án C không hoạt động trên AWS:

C nói đặt cổng ở chế độ "promiscuous
  mode" để nghe lưu lượng
        ↓
    Mạng ảo của AWS KHÔNG cho phép
      chế độ đó
        ↓
    Một ENI chỉ nhận gói tin gửi tới
      chính nó
        ↓
    Đây là ràng buộc cứng của hạ tầng

⚠ Đây là khác biệt lớn giữa mạng vật lý và mạng ảo AWS:

Trung tâm dữ liệu truyền thống:
  cắm máy vào switch port mirroring
        ↓
    AWS: không có switch để cấu hình
        ↓
    Traffic Mirroring là cách AWS
      cung cấp chức năng tương đương

⚠ Và Traffic Mirroring có ràng buộc về kiểu instance:

Nguồn phải là instance dùng
  Nitro System
        ↓
    Hầu hết kiểu instance thế hệ mới
      đều được
        ↓
    Kiểu cũ (m4, c4...) không hỗ trợ

⚠ Và đích có thể là ENI, NLB, hoặc Gateway Load Balancer: | Đích | Dùng khi | |---|---| | ENI | một máy giám sát duy nhất | | NLB | đội máy giám sát, cần cân bằng tải | | Gateway Load Balancer | thiết bị an ninh bên thứ ba |

Bắt gói trên máy giám sát:

sudo tcpdump -i eth0 -w /var/log/voip-$(date +%s).pcap \
  'udp portrange 10000-20000'

aws s3 cp /var/log/voip-*.pcap s3://phan-tich-mang/ --recursive

⚠ Và phân tích RTP cho biết chính xác vấn đề:

Wireshark đọc tệp pcap
        ↓
    Telephony → RTP → Stream Analysis
        ↓
    Thấy: jitter, mất gói, số thứ tự
      bị đảo
        ↓
    Jitter cao → vấn đề mạng
    → gói đến đủ nhưng ứng dụng xử lý
      sai → vấn đề lập trình

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Thấy được nội dung gói tin thật | | | Không cài gì lên máy nguồn | | | Lọc được đúng lưu lượng cần | |

⚠ Và "không cài agent lên máy nguồn" là ưu điểm quan trọng:

tcpdump chạy trên chính máy VOIP
        ↓
    Tốn CPU của máy đó
        ↓
    Và có thể làm vấn đề hiệu năng
      tệ hơn
        ↓
    Traffic Mirroring: sao chép ở
      tầng hạ tầng
    → máy nguồn không biết gì

⚠ Nhưng mirroring vẫn tốn băng thông của instance nguồn:

Lưu lượng mirror đi qua ENI của
  instance nguồn
        ↓
    Tính vào hạn ngạch băng thông
      của nó
        ↓
    Instance đang nghẽn → mirror làm
      tệ hơn
    → dùng bộ lọc và giới hạn
      packet-length

⚠ Và cần lưu ý về quyền riêng tư:

Traffic mirroring bắt TOÀN BỘ nội
  dung
        ↓
    Bao gồm cả dữ liệu nhạy cảm nếu
      không mã hoá
        ↓
    Hạn chế quyền tạo mirror session
        ↓
    Và mã hoá tệp pcap khi lưu

⚠ Và VPC Flow Log vẫn hữu ích ở tầng khác:

Flow log: bức tranh tổng thể, rẻ,
  chạy liên tục
        ↓
    Traffic mirroring: chi tiết, đắt,
      bật khi cần điều tra
        ↓
    Dùng flow log để phát hiện
    → mirroring để chẩn đoán sâu

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

  • **C. Dựng một EC2 với ENI làm giao diện giám sát, đặt cổng ở chế độ promiscuous và nghe lưu lượng — đây là phương án gần nhất và đúng cách làm trong trung tâm dữ liệu truyền thống, nhưng mạng ảo của AWS không cho phép chế độ promiscuous; một ENI chỉ nhận được gói tin gửi tới chính nó.
  • **B. Dùng VPC Flow Log để kiểm tra gói tin — flow log ghi siêu dữ liệu của luồng chứ không ghi nội dung gói tin.
  • **A. Dùng CloudWatch để kiểm tra gói tin — CloudWatch thu thập chỉ số và log, không có chức năng bắt gói.

Ghi nhớ

⚠ Ba mức chi tiết khi giám sát mạng — bảng phải thuộc: | Công cụ | Chi tiết | |---|---| | CloudWatch metric | số liệu tổng hợp | | VPC Flow Log | siêu dữ liệu từng luồng | | Traffic Mirroring | toàn bộ gói tin |

Từ khoá nhận diện:

"inspect network packets" → Traffic Mirroring "who talked to whom" → VPC Flow Log "promiscuous mode" → KHÔNG hoạt động trên AWS "third-party security appliance" → Gateway Load Balancer

Ba lưu ý về Traffic Mirroring: | Lưu ý | Chi tiết | |---|---| | Nguồn phải là instance Nitro | | | Đích: ENI, NLB, hoặc GWLB | | | Nguồn và đích phải cùng VPC hoặc peered | |

⚠ Mirror liên tài khoản cũng làm được:

Chia sẻ traffic mirror target qua
  RAM
        ↓
    Tài khoản khác tạo session trỏ
      tới đó
        ↓
    Hữu ích khi có đội an ninh tập
      trung

Ba lưu ý về bộ lọc: | Lưu ý | Chi tiết | |---|---| | Lọc theo giao thức, cổng, CIDR | | | Có chiều ingress và egress riêng | | | Quy tắc xét theo số thứ tự | |

⚠ Số hiệu giao thức phải nhớ: | Số | Giao thức | |---|---| | 6 | TCP | | 17 | UDP | | 1 | ICMP | | -1 hoặc bỏ trống | tất cả |

Ba lưu ý về đóng gói: | Lưu ý | Chi tiết | |---|---| | Gói được bọc trong VXLAN | | | Đích nghe trên cổng UDP 4789 | | | Công cụ phân tích phải hiểu VXLAN | |

⚠ VXLAN là chi tiết dễ vấp:

tcpdump trên máy đích thấy gói VXLAN
        ↓
    Phải bóc lớp đó ra mới thấy gói
      gốc
        ↓
    Wireshark tự hiểu VXLAN
    → nhưng công cụ tự viết thì không

Ba lưu ý về chi phí: | Khoản | Ghi chú | |---|---| | Traffic mirroring | theo giờ mỗi ENI nguồn | | Truyền dữ liệu | theo GB, tính cả liên AZ | | Máy giám sát | chi phí EC2 và lưu trữ |

Ba lưu ý về giới hạn: | Giới hạn | Giá trị | |---|---| | Session mỗi ENI nguồn | 3 | | Session mỗi ENI đích | 10.000 | | Filter rule mỗi filter | 100 |

Ba lưu ý về giải pháp thay thế: | Cách | Đặc điểm | |---|---| | tcpdump trên chính máy | đơn giản, tốn CPU máy đó | | Gateway Load Balancer | cho thiết bị IDS/IPS bên thứ ba | | Network Access Analyzer | phân tích đường đi theo cấu hình |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Kiểm tệp pcap có gói tin thật | | | Phân tích luồng RTP trong Wireshark | | | So chỉ số jitter với ngưỡng chấp nhận được | |

Và một lời khuyên: hãy dùng bộ lọc và giới hạn packet-length ngay khi bật mirroring. Sao chép toàn bộ lưu lượng của một máy đang gặp vấn đề hiệu năng sẽ làm chính vấn đề đó tệ hơn — và với chẩn đoán chất lượng VOIP thì header của gói RTP đã chứa gần như mọi thông tin bạn cần.

Câu 416 Continuous Improvement for Existing Solutions

A web application is running on a fleet of Amazon EC2 instances that are configured to operate in an Auto Scaling group (ASG). The instances are fronted by an Elastic Load Balancer (ELB). To enhance the system performance, a new Amazon Machine Image (AMI) was created and the ASG was configured to use the new AMI. However, after the production deployment, users complained of aberrations in the expected application functionality. A cross-check on the ELB has confirmed that all the instances are healthy and running as expected.

As a solutions architect, which option would you suggest to rectify these issues and guarantee that later deployments are successful?

  1. A

    Configure the ASG to use multiple Availability Zones. When an instance becomes unhealthy, the ASG maintains the desired capacity by distributing instances across these Availability Zones. This configuration helps in better application availability and reduces errors cropping from network connectivity issues

  2. B

    Configure the ASG to a maximum capacity of 3 times the actual needed size. With this configuration, the ASG will terminate unhealthy instances and launch new ones quickly to maintain an optimum number of instances to meet user requirements

  3. C

    Configure the ASG to use Elastic Load Balancing (ELB) health checks in place of EC2 status checks

  4. D

    Create a new ASG launch configuration that uses the newly created AMI. Double the size of the ASG and allow the new instances to become healthy and then reduce the ASG back to the original size. If the new instances do not work as expected, associate the ASG with the old launch configuration

Xem giải thích

Đáp án

**D — Tạo một launch configuration mới dùng AMI mới; nhân đôi kích thước của Auto Scaling group và chờ các instance mới trở nên khoẻ mạnh, rồi thu về kích thước ban đầu; nếu instance mới không hoạt động như mong đợi thì gắn lại ASG với launch configuration cũ.

Vì sao đúng

Đề mô tả hai vấn đề khác nhau, và đáp án giải quyết cả hai: | Vấn đề | Cách giải quyết | |---|---| | AMI mới gây lỗi chức năng | quay lui bằng launch configuration cũ | | Lần triển khai sau phải an toàn | nhân đôi rồi thu về — mẫu blue/green |

⚠ Điểm mấu chốt: ELB health check báo khoẻ nhưng ứng dụng vẫn sai:

Health check gọi `/health` → 200
        ↓
    ASG và ELB coi instance khoẻ
        ↓
    Nhưng chức năng nghiệp vụ sai
        ↓
    → health check KHÔNG phát hiện
      được lỗi logic

⚠ Và đây là lý do phương án C không giải quyết được:

C đổi từ EC2 status check sang ELB
  health check
        ↓
    Đề nói ELB ĐÃ xác nhận mọi
      instance khoẻ
        ↓
    Nghĩa là health check kiểu ELB
      đã dùng rồi
    → và nó vẫn không bắt được lỗi

⚠ Và mẫu "nhân đôi rồi thu về" chính là blue/green trong một ASG:

ASG đang có 4 instance với AMI cũ
        ↓
    Đổi launch configuration sang
      AMI mới
        ↓
    Đặt desired = 8
    → 4 instance MỚI khởi động
        ↓
    Cả 8 cùng phục vụ, kiểm thử
        ↓
    Đặt desired = 4
    → chính sách chấm dứt mặc định
      bỏ instance CŨ trước

⚠ Và chính sách chấm dứt mặc định làm việc đó tự động:

Default termination policy:
    1. AZ nhiều instance nhất
    2. Instance dùng launch
       configuration CŨ NHẤT
    3. Gần giờ tính phí tiếp theo nhất
        ↓
    Bước 2 chính là thứ ta cần
    → instance AMI cũ bị bỏ trước

Quy trình đầy đủ:

aws autoscaling create-launch-configuration \
  --launch-configuration-name cau-hinh-v2 \
  --image-id ami-moi123 --instance-type m6i.large

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name doi-ung-dung \
  --launch-configuration-name cau-hinh-v2 \
  --desired-capacity 8 --max-size 12

# chờ instance mới InService, kiểm thử

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name doi-ung-dung \
  --desired-capacity 4

Quay lui:

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name doi-ung-dung \
  --launch-configuration-name cau-hinh-v1 \
  --desired-capacity 8

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name doi-ung-dung \
  --desired-capacity 4

⚠ Và vì sao phương án B không giải quyết vấn đề:

B đặt max size gấp 3 lần
        ↓
    Để ASG "chấm dứt instance không
      khoẻ và tạo mới nhanh hơn"
        ↓
    Nhưng instance đang KHOẺ theo
      health check
    → ASG không thay thế chúng
        ↓
    Sai chẩn đoán

⚠ Và vì sao phương án A không liên quan:

A cấu hình ASG dùng nhiều AZ
        ↓
    Đó là biện pháp SẴN SÀNG CAO
        ↓
    Vấn đề ở đây là AMI mới có lỗi
    → không phải vấn đề AZ

⚠ Và vấn đề gốc là AMI mới chưa được kiểm thử:

"Tạo AMI mới, cấu hình ASG dùng nó"
        ↓
    Rồi triển khai thẳng vào sản xuất
        ↓
    Không có bước kiểm thử nào ở giữa
        ↓
    Đây mới là lỗi quy trình thật

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không giảm công suất trong lúc triển khai | | | Cả hai phiên bản cùng chạy để so sánh | | | Quay lui bằng một lệnh | |

⚠ Và cần theo dõi chỉ số tách theo phiên bản:

Cả 8 instance cùng target group
        ↓
    Chỉ số gộp lại
        ↓
    Lỗi của 4 máy mới bị pha loãng
      một nửa
        ↓
    Dùng hai target group riêng
      để thấy rõ hơn

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

⚠ Launch configuration đã ngừng nhận tạo mới từ tháng 12/2023.

Tiêu chí Launch configuration Launch template
Tạo mới KHÔNG còn được CÓ
Phiên bản không có CÓ, quay lui được
Mixed instance policy không CÓ
Spot + On-Demand trộn không CÓ
T2/T3 unlimited không CÓ

Launch template với phiên bản:

aws ec2 create-launch-template-version \
  --launch-template-name mau-ung-dung \
  --source-version 1 \
  --launch-template-data '{"ImageId": "ami-moi123"}'

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name doi-ung-dung \
  --launch-template LaunchTemplateName=mau-ung-dung,Version=2

⚠ Và AWS đã có tính năng chuyên cho việc này: Instance Refresh.

aws autoscaling start-instance-refresh \
  --auto-scaling-group-name doi-ung-dung \
  --preferences '{
    "MinHealthyPercentage": 90,
    "InstanceWarmup": 300,
    "CheckpointPercentages": [20, 50, 100],
    "CheckpointDelay": 600,
    "AutoRollback": true}'
Thay thế instance theo lô
        ↓
    Checkpoint dừng lại để kiểm tra
        ↓
    `AutoRollback: true` tự quay lui
      khi alarm kích hoạt
        ↓
    Đây là cách hiện đại, không phải
      nhân đôi thủ công

Với kiến thức hiện tại, quy trình đúng là: dùng launch template có phiên bản + instance refresh với checkpoint và auto rollback, hoặc CodeDeploy blue/green với hai target group.

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

  • **C. Cấu hình ASG dùng ELB health check thay cho EC2 status check — đây là phương án gần nhất và là thực hành đúng trong hầu hết trường hợp, nhưng đề nói rõ ELB đã xác nhận mọi instance khoẻ mạnh, nghĩa là health check kiểu ELB đã được dùng và vẫn không bắt được lỗi chức năng.
  • **B. Đặt max capacity gấp 3 lần để ASG thay thế instance hỏng nhanh hơn — instance đang khoẻ theo health check nên ASG không thay thế chúng.
  • **A. Cấu hình ASG dùng nhiều Availability Zone — biện pháp sẵn sàng cao, không liên quan tới lỗi trong AMI mới.

Ghi nhớ

⚠ Bốn cách triển khai an toàn với ASG — bảng phải thuộc: | Cách | Đặc điểm | |---|---| | Instance refresh | thay theo lô, có checkpoint và auto rollback | | Nhân đôi rồi thu về | thủ công, không giảm công suất | | CodeDeploy blue/green | hai ASG, chuyển lưu lượng ở ALB | | Weighted target group | canary theo tỷ lệ |

Từ khoá nhận diện:

"new AMI causes issues, rollback" → launch template version cũ "replace instances gradually" → instance refresh "health check passes but app is wrong" → health check chưa đủ sâu "launch configuration" → đã ngừng tạo mới, dùng launch template

Ba lưu ý về instance refresh: | Tham số | Tác dụng | |---|---| | MinHealthyPercentage | giữ công suất tối thiểu | | InstanceWarmup | chờ instance sẵn sàng trước khi tính | | CheckpointPercentages | dừng lại kiểm tra ở các mốc | | AutoRollback | tự quay lui khi alarm kích hoạt |

⚠ AutoRollback cần alarm để hoạt động:

--preferences '{"AutoRollback": true,
                "AlarmSpecification": {
                  "Alarms": ["alarm-loi-5xx"]}}'

Ba lưu ý về health check: | Kiểu | Kiểm gì | |---|---| | EC2 | status check của hạ tầng | | ELB | kết quả health check của target group | | Custom | do bạn đặt qua API |

⚠ Health check phải chạm logic nghiệp vụ:

`/health` trả 200 cố định
        ↓
    Không bắt được lỗi chức năng
        ↓
    Cho nó kiểm cả kết nối CSDL,
      cache, và một truy vấn thật

Ba lưu ý về chính sách chấm dứt: | Chính sách | Chọn instance nào | |---|---| | Default | AZ nhiều nhất → launch config cũ nhất | | OldestInstance | chạy lâu nhất | | NewestInstance | mới nhất |

Ba lưu ý về launch template: | Lưu ý | Chi tiết | |---|---| | Có phiên bản, quay lui bằng một lệnh | | | $Latest và $Default là bí danh | | | Mixed instance policy trộn Spot và On-Demand | |

⚠ Đừng trỏ ASG vào $Latest cho sản xuất:

Tạo phiên bản mới → ASG dùng ngay
        ↓
    Không có chỗ để kiểm thử
        ↓
    Trỏ vào số phiên bản cụ thể
    → hoặc `$Default` và chủ động
      đặt default

Ba lưu ý về kiểm thử AMI: | Lưu ý | Chi tiết | |---|---| | EC2 Image Builder có bước kiểm thử tự động | | | Triển khai vào môi trường thử trước | | | Chạy kiểm thử tích hợp trên instance mới | |

Ba lưu ý về warm pool: | Lưu ý | Chi tiết | |---|---| | Giữ sẵn instance đã cài đặt xong | | | Trạng thái Stopped hoặc Hibernated | | | Rút ngắn thời gian co giãn | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | So chỉ số lỗi giữa hai phiên bản | | | Chạy kiểm thử chức năng trên instance mới | | | Thử quay lui trên môi trường thử | |

Và một lời khuyên: hãy cho health check kiểm tra logic nghiệp vụ thật chứ đừng chỉ trả về 200. Cả sự cố trong đề bắt nguồn từ việc ELB báo mọi instance khoẻ mạnh trong khi ứng dụng hoạt động sai — một endpoint chỉ cần gọi thử một truy vấn thật đã đủ để bắt được điều đó.

Câu 417 Design for New Solutions

A global multi-player gaming application runs on UDP protocol and it needs to add functionality where you can assign multiple players to a single session on a game server based on factors such as geographic location, player skill, and a few more configurable parameters. The application is accessed by players spread out across different regions of the world.

What is the BEST way to configure this requirement?

  1. A

    Use custom routing accelerator of Global Accelerator to deterministically route one or more users to a specific instance using VPC subnet endpoints

  2. B

    Use custom routing accelerator of Global Accelerator in front of Network Load Balancer (NLB) to route traffic that can maintain session data

  3. C

    Use Application Load Balancer (ALB) with sticky sessions enabled to maintain player session data. Configure Global Accelerator to front the ALB for cross-region elasticity

  4. D

    Use custom routing accelerator of Global Accelerator to deterministically route one or more users to a specific instance using VPC sharing

Xem giải thích

Đáp án

**A — Dùng custom routing accelerator của Global Accelerator để định tuyến tất định một hoặc nhiều người dùng tới một instance cụ thể, thông qua VPC subnet endpoint.

Vì sao đúng

Đề mô tả một yêu cầu rất đặc thù của game nhiều người chơi:

Gán nhiều người chơi vào MỘT PHIÊN
  trên MỘT máy chủ game
        ↓
    Dựa trên vị trí địa lý, trình độ,
      và tham số khác
        ↓
    → hệ thống ghép cặp quyết định
      ai vào máy nào
        ↓
    Mạng phải TUÂN THEO quyết định đó

⚠ Điểm mấu chốt: "tất định" nghĩa là ứng dụng chọn máy, không phải load balancer:

Load balancer thông thường: TỰ chọn
  target
        ↓
    Round robin, least outstanding,
      flow hash
        ↓
    Nhưng game cần: người chơi A, B,
      C phải vào ĐÚNG máy chủ số 7
        ↓
    → custom routing accelerator

⚠ Và cơ chế của custom routing rất khác accelerator thường: | Loại | Cách định tuyến | |---|---| | Standard accelerator | tới endpoint gần nhất, tự cân bằng | | Custom routing accelerator | ánh xạ CỔNG → đúng một IP riêng trong subnet |

Custom routing ánh xạ:
    cổng 10000 → 10.0.1.5:7777
    cổng 10001 → 10.0.1.6:7777
        ↓
    Hệ thống ghép cặp bảo client
      dùng cổng nào
    → client tới đúng máy chủ đó

Tạo custom routing accelerator:

aws globalaccelerator create-custom-routing-accelerator \
  --name dinh-tuyen-game --ip-address-type IPV4

aws globalaccelerator create-custom-routing-listener \
  --accelerator-arn <arn> \
  --port-ranges FromPort=10000,ToPort=19999

aws globalaccelerator create-custom-routing-endpoint-group \
  --listener-arn <arn-listener> \
  --endpoint-group-region ap-southeast-1 \
  --destination-configurations \
    FromPort=7777,ToPort=7777,Protocols=UDP

Thêm subnet làm endpoint:

aws globalaccelerator add-custom-routing-endpoints \
  --endpoint-group-arn <arn-nhom> \
  --endpoint-configurations EndpointId=subnet-1a

⚠ Và endpoint là SUBNET, không phải instance — đây là điểm cốt lõi:

Khai một subnet
        ↓
    Global Accelerator ánh xạ dải cổng
      tới mọi IP trong subnet đó
        ↓
    Instance mới khởi động trong subnet
    → tự có ánh xạ, không phải đăng ký

Tra ánh xạ cổng cho một instance:

import boto3
ga = boto3.client('globalaccelerator', region_name='us-west-2')

kq = ga.list_custom_routing_port_mappings_by_destination(
    EndpointId='i-0abc123',
    DestinationAddress='10.0.1.5')
for m in kq['DestinationPortMappings']:
    print(m['AcceleratorSocketAddresses'])
Hệ thống ghép cặp gọi API này
        ↓
    Nhận địa chỉ IP tĩnh + cổng
        ↓
    Gửi cho từng người chơi trong
      phiên
    → tất cả vào đúng một máy chủ

⚠ Và vì sao phương án D sai — "VPC sharing" không liên quan:

D nói định tuyến "thông qua VPC
  SHARING"
        ↓
    VPC sharing là cơ chế chia sẻ
      subnet cho tài khoản khác
        ↓
    Không phải cơ chế endpoint của
      Global Accelerator
        ↓
    Custom routing dùng SUBNET
      ENDPOINT

⚠ Đây là loại câu chỉ khác nhau một cụm từ:

A: "VPC subnet endpoints" — đúng
        ↓
    D: "VPC sharing" — sai
        ↓
    Phần còn lại của hai phương án
      giống hệt nhau

⚠ Và vì sao phương án B sai — custom routing KHÔNG đặt trước NLB:

B nói đặt custom routing accelerator
  trước Network Load Balancer
        ↓
    Custom routing trỏ THẲNG tới
      subnet và IP riêng
        ↓
    Không có load balancer nào ở giữa
        ↓
    Vì mục đích là BỎ QUA việc cân
      bằng tải

⚠ Và standard accelerator mới đặt trước NLB được: | Loại accelerator | Endpoint hợp lệ | |---|---| | Standard | ALB, NLB, EC2, Elastic IP | | Custom routing | CHỈ subnet của VPC |

⚠ Và vì sao phương án C sai — sticky session không phải ghép cặp:

C dùng ALB với sticky session
        ↓
    Sticky giữ MỘT người dùng ở
      MỘT máy
        ↓
    Nhưng không gán NHIỀU người chơi
      vào CÙNG một máy
        ↓
    Và ALB là tầng 7 HTTP
    → game chạy UDP

⚠ Và đây là hai khái niệm hoàn toàn khác nhau:

Sticky session: cùng client → cùng
  server (theo cookie hoặc IP)
        ↓
    Deterministic routing: ỨNG DỤNG
      quyết định client nào tới
      server nào
        ↓
    Cái sau mạnh hơn và là thứ game
      cần

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Hệ thống ghép cặp kiểm soát hoàn toàn | | | IP tĩnh anycast, độ trễ thấp toàn cầu | | | Hỗ trợ UDP | |

⚠ Và một custom routing accelerator hỗ trợ rất nhiều instance:

Một accelerator ánh xạ tới hàng
  triệu đích
        ↓
    Đủ cho đội máy chủ game rất lớn
        ↓
    Và mở rộng bằng cách thêm subnet

⚠ Và mặc định mọi lưu lượng bị TỪ CHỐI:

Custom routing: deny by default
        ↓
    Phải cho phép từng đích tường minh
aws globalaccelerator allow-custom-routing-traffic \
  --endpoint-group-arn <arn-nhom> \
  --endpoint-id subnet-1a \
  --destination-addresses 10.0.1.5 \
  --destination-ports 7777
Hoặc cho phép toàn bộ:
    --allow-all-traffic-to-endpoint

⚠ Và đây là điểm khác biệt về an ninh so với standard:

Standard accelerator: chuyển mọi
  lưu lượng tới endpoint
        ↓
    Custom routing: chỉ chuyển tới
      đích đã được phép
        ↓
    Kiểm soát chi tiết hơn nhiều

⚠ Và GameLift là lựa chọn trọn gói cho bài toán này:

GameLift FlexMatch: ghép cặp theo
  trình độ, độ trễ, tham số tuỳ ý
        ↓
    GameLift quản đội máy chủ game
      và phiên
        ↓
    Tự đặt người chơi vào đúng phiên
        ↓
    Đề hỏi cách cấu hình mạng
    → nhưng GameLift đáng cân nhắc
      cho toàn bộ bài toán

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

  • **D. Dùng custom routing accelerator để định tuyến tất định tới một instance thông qua VPC sharing — đây là phương án gần nhất và chọn đúng loại accelerator, nhưng endpoint của custom routing là VPC subnet chứ không phải VPC sharing; VPC sharing là cơ chế chia sẻ subnet cho tài khoản khác.
  • **B. Dùng custom routing accelerator đứng trước Network Load Balancer — custom routing trỏ thẳng tới IP riêng trong subnet, không đặt trước load balancer; đó là việc của standard accelerator.
  • **C. Dùng ALB với sticky session kèm Global Accelerator — ALB là tầng 7 HTTP trong khi game chạy UDP, và sticky session chỉ giữ một client ở một máy chứ không gán nhiều người chơi vào cùng một phiên.

Ghi nhớ

⚠ Hai loại Global Accelerator — bảng phải thuộc: | Tiêu chí | Standard | Custom routing | |---|---|---| | Endpoint | ALB, NLB, EC2, EIP | VPC subnet | | Định tuyến | tự chọn endpoint gần nhất | ánh xạ cổng → IP cụ thể | | Health check | CÓ | không | | Mặc định | cho phép | TỪ CHỐI | | Dùng cho | web, API, ứng dụng thường | game, VoIP cần gán phiên |

Từ khoá nhận diện:

"deterministically route users to a specific instance" → custom routing accelerator "lowest latency, automatic failover" → standard accelerator "matchmaking players into sessions" → GameLift FlexMatch "sticky sessions" → ALB, không giải quyết bài toán ghép cặp

Ba lưu ý về custom routing: | Lưu ý | Chi tiết | |---|---| | Endpoint là subnet, không phải instance | | | Mặc định từ chối mọi lưu lượng | | | Không có health check | |

⚠ Không có health check nghĩa là ứng dụng phải tự lo:

Máy chủ game hỏng
        ↓
    Global Accelerator vẫn gửi lưu
      lượng tới
        ↓
    Hệ thống ghép cặp phải tự biết
      máy nào còn sống
    → và không đặt người chơi mới
      vào đó

Ba lưu ý về ánh xạ cổng: | Lưu ý | Chi tiết | |---|---| | Tra bằng list-custom-routing-port-mappings | | | Ánh xạ cố định, không đổi | | | Một IP riêng có thể có nhiều cổng ánh xạ | |

Ba lưu ý về standard accelerator: | Lưu ý | Chi tiết | |---|---| | Hai IP tĩnh anycast | | | Traffic dial điều khiển tỷ lệ theo nhóm | | | Client affinity theo IP nguồn | |

Ba lưu ý về GameLift: | Thành phần | Việc | |---|---| | FlexMatch | ghép cặp theo quy tắc tuỳ chỉnh | | Fleet | quản đội máy chủ game | | Queue | đặt phiên vào Region phù hợp |

⚠ FlexMatch khai quy tắc bằng JSON:

{"name": "ghep-cap-theo-trinh-do",
 "ruleLanguageVersion": "1.0",
 "teams": [{"name": "doi", "maxPlayers": 10, "minPlayers": 8}],
 "rules": [{
   "name": "chenh-lech-trinh-do",
   "type": "distance",
   "measurements": ["teams[doi].players.attributes[trinhDo]"],
   "referenceValue": "avg(teams[doi].players.attributes[trinhDo])",
   "maxDistance": 10}]}

Ba lưu ý về UDP trên AWS: | Dịch vụ | Hỗ trợ UDP | |---|---| | NLB | CÓ | | Global Accelerator | CÓ | | ALB | KHÔNG | | CloudFront | KHÔNG (trừ HTTP/3 ở biên) |

Ba lưu ý về chi phí: | Khoản | Ghi chú | |---|---| | Phí cố định mỗi accelerator | ~0,025 USD/giờ | | Phí truyền dữ liệu premium | theo Region | | Custom routing | giá tương tự standard |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gọi API tra ánh xạ cổng của một instance | | | Kết nối tới cổng đó và xác nhận tới đúng máy | | | Kiểm lưu lượng bị từ chối khi chưa cho phép đích | |

Và một lời khuyên: hãy nhớ rằng custom routing accelerator từ chối mọi lưu lượng theo mặc định. Cấu hình xong mọi thứ mà quên gọi allow-custom-routing-traffic sẽ cho ra một hệ thống trông hoàn toàn đúng nhưng không người chơi nào kết nối được — và không có thông báo lỗi nào chỉ ra nguyên nhân.

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

A data analytics company runs a real-time data processing application that uses Kinesis Client Library (KCL) to help consume and process data from the real-time data streams. The development team has raised a query on the viability of using the same DynamoDB table for different KCL applications.

Which of the following are correct statements for KCL while consuming Kinesis Data Streams? (Select two)

  1. A

    Each KCL application must use its own DynamoDB table

  2. B

    Multiple KCL applications can share a DynamoDB table if Amazon Amazon Simple Storage Service (Amazon S3) is configured to save transit data and metadata

  3. C

    You can only use DynamoDB for checkpointing KCL

  4. D

    Multiple KCL applications can share a DynamoDB table

  5. E

    Amazon Relational Database Service (Amazon RDS) can also be used for checkpointing KCL

Xem giải thích

Đáp án

**A và C — Mỗi ứng dụng KCL phải dùng bảng DynamoDB riêng của nó, và chỉ dùng được DynamoDB để lưu checkpoint của KCL.

Vì sao đúng

Câu này kiểm tra hai ràng buộc cứng của Kinesis Client Library.

⚠ Ràng buộc thứ nhất: KCL dùng tên ứng dụng làm TÊN BẢNG:

KCL tự tạo một bảng DynamoDB
        ↓
    Tên bảng = tên ứng dụng KCL
        ↓
    Hai ứng dụng cùng tên
    → dùng chung bảng
    → checkpoint đè lên nhau

⚠ Và đây là lý do phải mỗi ứng dụng một bảng:

Ứng dụng A đọc tới bản ghi #1000
        ↓
    Ứng dụng B đọc tới bản ghi #500
        ↓
    Dùng chung bảng → một cái ghi đè
      checkpoint của cái kia
        ↓
    Cả hai đều xử lý sai vị trí

Cấu trúc bảng lease của KCL:

leaseKey (partition key)  = shardId-000000000000
leaseOwner                = worker-abc-123
leaseCounter              = 42
checkpoint                = 49590338271490256608559692538361571095921575989136588898
checkpointSubSequenceNumber = 0
ownerSwitchesSinceCheckpoint = 3

⚠ Và bảng đó làm ba việc cùng lúc: | Việc | Cột | |---|---| | Lưu vị trí đọc | checkpoint | | Phân chia shard cho worker | leaseOwner, leaseCounter | | Phát hiện worker chết | leaseCounter không tăng |

⚠ Ràng buộc thứ hai: KCL chỉ hỗ trợ DynamoDB, không có lựa chọn khác:

KCL cài cứng DynamoDB làm nơi lưu
  lease và checkpoint
        ↓
    Không cấu hình sang RDS, S3 hay
      nơi khác được
        ↓
    Đây là ràng buộc thiết kế của
      thư viện

Đây là lý do mệnh đề E sai.

⚠ Và vì sao mệnh đề D sai:

D nói nhiều ứng dụng KCL DÙNG CHUNG
  một bảng DynamoDB
        ↓
    Ngược với ràng buộc trên
        ↓
    Trực tiếp mâu thuẫn với mệnh
      đề A

⚠ Và vì sao mệnh đề B sai:

B nói dùng chung bảng được NẾU cấu
  hình S3 lưu dữ liệu trung gian
        ↓
    KCL không có tuỳ chọn đó
        ↓
    S3 không tham gia vào cơ chế
      lease của KCL

Khai tên ứng dụng khi khởi tạo:

ConfigsBuilder configsBuilder = new ConfigsBuilder(
    "luong-clickstream",
    "ung-dung-phan-tich",
    kinesisClient, dynamoClient, cloudWatchClient,
    UUID.randomUUID().toString(),
    new XuLyBanGhiFactory());
Tham số thứ hai là tên ứng dụng
        ↓
    Cũng chính là tên bảng DynamoDB
        ↓
    Hai đội dùng cùng tên → xung đột

⚠ Và phải cấp thông lượng cho bảng đó:

Bảng lease bị đọc và ghi liên tục
        ↓
    Mỗi worker cập nhật `leaseCounter`
      vài giây một lần
        ↓
    Nhiều shard + nhiều worker → tải
      cao
        ↓
    Bảng bị chặn → KCL không lấy
      được lease
    → xử lý dừng lại
aws dynamodb update-table --table-name ung-dung-phan-tich \
  --billing-mode PAY_PER_REQUEST
On-demand tránh được việc phải đoán
  công suất
        ↓
    Và tự chịu đỉnh khi resharding

⚠ Và resharding làm tải bảng tăng vọt:

Chia shard hoặc gộp shard
        ↓
    Mọi worker phải lấy lại lease
        ↓
    Bảng nhận rất nhiều ghi trong
      thời gian ngắn
    → đây là lúc hay bị chặn nhất

Ba lợi ích khi hiểu đúng cơ chế: | Lợi ích | Chi tiết | |---|---| | Nhiều ứng dụng đọc cùng luồng độc lập | | | Mỗi ứng dụng có vị trí đọc riêng | | | Worker chết thì shard được giao lại | |

⚠ Và đây chính là cách nhiều consumer đọc cùng một luồng:

Ba đội cùng đọc luồng clickstream
        ↓
    Ba ứng dụng KCL, ba tên khác nhau
        ↓
    Ba bảng DynamoDB riêng
        ↓
    Mỗi đội có con trỏ đọc riêng
    → không ảnh hưởng nhau

⚠ Và cơ chế lease xử lý việc worker vào và ra:

Worker mới khởi động
        ↓
    Nó "đánh cắp" lease từ worker
      đang giữ nhiều shard nhất
        ↓
    Worker chết → `leaseCounter`
      ngừng tăng
        ↓
    Worker khác phát hiện và tiếp quản

⚠ Và KCL 3.x có thêm cân bằng theo tải:

KCL 2.x: chia đều SỐ SHARD cho worker
        ↓
    Shard có lưu lượng khác nhau
    → worker không cân bằng thật
        ↓
    KCL 3.x: cân bằng theo mức dùng
      CPU của worker

⚠ Và Lambda là lựa chọn thay thế bỏ được toàn bộ việc này:

Lambda với Kinesis event source
  mapping
        ↓
    AWS lo checkpoint và phân chia
      shard
        ↓
    Không có bảng DynamoDB nào để
      quản
        ↓
    Nhưng ít kiểm soát hơn KCL

⚠ Và cần dọn bảng khi ngừng một ứng dụng:

Ứng dụng KCL không dùng nữa
        ↓
    Bảng DynamoDB vẫn còn
        ↓
    Vẫn tính tiền
    → nhớ xoá

⚠ Và bảng lease cũng cần theo dõi:

aws cloudwatch put-metric-alarm \
  --alarm-name bang-lease-bi-chan \
  --namespace AWS/DynamoDB \
  --metric-name ThrottledRequests \
  --dimensions Name=TableName,Value=ung-dung-phan-tich \
  --statistic Sum --period 60 \
  --evaluation-periods 1 --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold

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

  • **D. Nhiều ứng dụng KCL dùng chung một bảng DynamoDB — đây là phương án gần nhất và nghe hợp lý nếu nghĩ bảng chỉ lưu vị trí đọc, nhưng KCL dùng tên ứng dụng làm tên bảng và các checkpoint sẽ đè lên nhau.
  • **B. Dùng chung bảng được nếu cấu hình S3 lưu dữ liệu trung gian — KCL không có tuỳ chọn nào như vậy.
  • **E. Amazon RDS cũng dùng được để lưu checkpoint — KCL chỉ hỗ trợ DynamoDB.

Ghi nhớ

⚠ Bốn điều phải thuộc về KCL: | Điều | Nội dung | |---|---| | 1 | Mỗi ứng dụng một bảng DynamoDB riêng | | 2 | Tên bảng = tên ứng dụng KCL | | 3 | Chỉ dùng DynamoDB cho checkpoint | | 4 | Bảng lease cần đủ thông lượng |

Từ khoá nhận diện:

"KCL checkpointing" → DynamoDB, mỗi ứng dụng một bảng "multiple consumers of same stream" → nhiều ứng dụng KCL tên khác nhau "no checkpoint management" → Lambda event source mapping "dedicated throughput per consumer" → Enhanced Fan-Out

Ba lưu ý về bảng lease: | Lưu ý | Chi tiết | |---|---| | KCL tự tạo nếu chưa có | | | Partition key là leaseKey (shard ID) | | | Nên dùng on-demand để tránh bị chặn | |

⚠ Cần quyền IAM để KCL tạo và dùng bảng:

{"Effect": "Allow",
 "Action": ["dynamodb:CreateTable", "dynamodb:DescribeTable",
            "dynamodb:GetItem", "dynamodb:PutItem",
            "dynamodb:UpdateItem", "dynamodb:DeleteItem",
            "dynamodb:Scan", "dynamodb:Query"],
 "Resource": "arn:aws:dynamodb:*:*:table/ung-dung-phan-tich"}

Ba lưu ý về cơ chế lease: | Cơ chế | Chi tiết | |---|---| | leaseCounter tăng đều | chứng tỏ worker còn sống | | Lease stealing | worker mới lấy bớt shard | | failoverTimeMillis | bao lâu thì coi worker đã chết |

Ba lưu ý về checkpoint: | Lưu ý | Chi tiết | |---|---| | Checkpoint quá thường xuyên → tốn ghi DynamoDB | | | Checkpoint quá thưa → xử lý lại nhiều khi khởi động lại | | | Thường checkpoint mỗi lô | |

Ba lưu ý về ba phiên bản KCL: | Phiên bản | Đặc điểm | |---|---| | 1.x | cũ, dùng GetRecords | | 2.x | hỗ trợ Enhanced Fan-Out | | 3.x | cân bằng tải theo CPU của worker |

Ba lưu ý về Enhanced Fan-Out: | Lưu ý | Chi tiết | |---|---| | Mỗi consumer 2 MB/s riêng mỗi shard | | | Độ trễ khoảng 70 ms thay vì 200 ms | | | Tối đa 20 consumer đăng ký mỗi luồng | |

Ba chỉ số cần theo dõi: | Chỉ số | Ý nghĩa | |---|---| | MillisBehindLatest | consumer tụt lại bao xa | | ThrottledRequests của bảng lease | bảng bị chặn | | RecordsProcessed | thông lượng thật |

Ba lưu ý về vận hành: | Lưu ý | Chi tiết | |---|---| | Xoá bảng khi ngừng ứng dụng | | | Đặt on-demand để chịu resharding | | | Đặt cảnh báo trên MillisBehindLatest | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Xem bảng DynamoDB do KCL tạo | | | Đếm số dòng = số shard | | | Kiểm hai ứng dụng có hai bảng khác nhau | |

Và một lời khuyên: hãy chuyển bảng lease sang chế độ on-demand ngay khi triển khai. Nó bị đọc và ghi liên tục bởi mọi worker, và đúng lúc bạn resharding để tăng công suất là lúc nó nhận nhiều ghi nhất — nếu bị chặn ở đó thì toàn bộ việc xử lý dừng lại đúng lúc tải cao nhất.

Câu 419 Chọn nhiều đáp án Design Solutions for Organizational Complexity

An e-commerce business has several AWS accounts. For implementing a new feature, the development team has used AWS Lambda functions which will be managed in a centralized AWS account. The team needs the required permissions to allow the Lambda functions to access resources in each of the company's AWS accounts with the least privilege(s) possible.

How will you configure this requirement? (Select two)

  1. A

    In the other AWS accounts, configure an IAM role that has permissions to assume the role of the centralized account. Add the Lambda service as a trusted entity

  2. B

    In the centralized account, configure an IAM role that has roles of the other accounts as trusted entities. Provide least possible privileges to this role

  3. C

    In the centralized account, configure an IAM role that has the Lambda service as a trusted entity. Add an inline policy to assume the roles of the other AWS accounts

  4. D

    In the other AWS accounts, configure an IAM role that has minimal permissions. Add the Lambda execution role of the centralized account as a trusted entity

  5. E

    In the other AWS accounts, configure a service-linked role for the Lambda function of the centralized account. Provide least possible privileges to this role

Xem giải thích

Đáp án

**C và D — Ở tài khoản trung tâm, tạo một IAM role có dịch vụ Lambda làm trusted entity và thêm một inline policy cho phép giả nhận vai trò của các tài khoản khác; ở các tài khoản khác, tạo một IAM role có quyền tối thiểu và thêm execution role của Lambda ở tài khoản trung tâm làm trusted entity.

Vì sao đúng

Truy cập liên tài khoản bằng Lambda cần hai vai trò, và mỗi đáp án lo một cái: | Vai trò | Ở đâu | Việc | |---|---|---| | Execution role | tài khoản trung tâm | Lambda chạy bằng nó, và giả nhận vai trò khác | | Cross-account role | các tài khoản khác | chứa quyền thật để chạm tài nguyên |

⚠ Điểm mấu chốt: chiều giả nhận vai trò rất dễ nhớ ngược:

Lambda Ở TÀI KHOẢN TRUNG TÂM
        ↓
    Muốn chạm tài nguyên Ở TÀI KHOẢN
      KHÁC
        ↓
    → Vai trò được giả nhận nằm ở
      TÀI KHOẢN KHÁC
    → Quyền `sts:AssumeRole` nằm ở
      TRUNG TÂM

Execution role ở tài khoản trung tâm:

{"Version": "2012-10-17", "Statement": [{
  "Effect": "Allow",
  "Principal": {"Service": "lambda.amazonaws.com"},
  "Action": "sts:AssumeRole"}]}

Inline policy cho phép giả nhận vai trò xa:

{"Version": "2012-10-17", "Statement": [{
  "Effect": "Allow",
  "Action": "sts:AssumeRole",
  "Resource": [
    "arn:aws:iam::222222222222:role/VaiTroChoLambda",
    "arn:aws:iam::333333333333:role/VaiTroChoLambda"]}]}

⚠ Liệt kê ARN cụ thể thay vì * là thực hành đúng:

`"Resource": "*"`
        ↓
    Lambda giả nhận được BẤT KỲ vai
      trò nào cho phép nó
        ↓
    Liệt kê tường minh
    → quyền tối thiểu thật

Cross-account role ở tài khoản đích:

{"Version": "2012-10-17", "Statement": [{
  "Effect": "Allow",
  "Principal": {"AWS":
    "arn:aws:iam::111111111111:role/LambdaExecutionRole"},
  "Action": "sts:AssumeRole",
  "Condition": {"StringEquals": {
    "sts:ExternalId": "chuoi-bi-mat"}}}]}

⚠ Trust policy trỏ tới ARN của EXECUTION ROLE, không phải tài khoản:

`"AWS": "arn:aws:iam::111111111111:root"`
        ↓
    Cho phép MỌI danh tính trong tài
      khoản đó giả nhận
        ↓
    Trỏ thẳng ARN của execution role
    → chỉ đúng hàm Lambda đó
    → quyền tối thiểu

Mã trong Lambda:

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

def truy_cap_tai_khoan(ma_tai_khoan):
    cred = sts.assume_role(
        RoleArn=f'arn:aws:iam::{ma_tai_khoan}:role/VaiTroChoLambda',
        RoleSessionName=f'lambda-{ma_tai_khoan}')['Credentials']
    return boto3.client('s3',
        aws_access_key_id=cred['AccessKeyId'],
        aws_secret_access_key=cred['SecretAccessKey'],
        aws_session_token=cred['SessionToken'])

⚠ Và vì sao phương án A đảo ngược chiều:

A nói ở CÁC TÀI KHOẢN KHÁC tạo vai
  trò "có quyền giả nhận vai trò
  của tài khoản trung tâm"
        ↓
    Chiều bị đảo
        ↓
    Và "thêm dịch vụ Lambda làm
      trusted entity" ở tài khoản
      khác cũng sai
    → Lambda chạy ở trung tâm, không
      chạy ở đó

⚠ Và vì sao phương án B đảo ngược trust policy:

B nói ở TÀI KHOẢN TRUNG TÂM tạo vai
  trò "có các vai trò của tài khoản
  khác làm trusted entity"
        ↓
    Nghĩa là tài khoản khác giả nhận
      vai trò ở trung tâm
        ↓
    Ngược với việc Lambda ở trung tâm
      chạm tài nguyên ở nơi khác

⚠ Và vì sao phương án E sai — service-linked role không dùng như vậy:

Service-linked role do CHÍNH DỊCH VỤ
  AWS tạo và quản
        ↓
    Ví dụ `AWSServiceRoleForAutoScaling`
        ↓
    Bạn không tạo service-linked role
      cho một hàm Lambda của tài
      khoản khác
    → khái niệm không tồn tại

⚠ Và external ID chống confused deputy — đáng thêm dù cùng tổ chức:

Không có external ID
        ↓
    Nếu execution role đó cũng phục
      vụ mục đích khác
        ↓
    Có thể bị lợi dụng
        ↓
    Với tài khoản nội bộ thì rủi ro
      thấp
    → nhưng thêm vẫn tốt

⚠ Và quyền tối thiểu ở vai trò đích là chỗ quan trọng nhất:

{"Effect": "Allow",
 "Action": ["s3:GetObject", "s3:ListBucket"],
 "Resource": ["arn:aws:s3:::bao-cao-*",
              "arn:aws:s3:::bao-cao-*/*"]}
Đề nói rõ "least privilege possible"
        ↓
    Vai trò đích chỉ có đúng quyền
      hàm cần
        ↓
    Không phải `PowerUserAccess`

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Một hàm phục vụ mọi tài khoản | | | Credential tạm, tự hết hạn | | | Mỗi tài khoản kiểm soát quyền của mình | |

⚠ Và điểm cuối là lợi ích quản trị quan trọng:

Chủ tài khoản đích quyết định vai
  trò đó làm được gì
        ↓
    Đội trung tâm không tự cấp quyền
      cho mình được
        ↓
    Phân quyền hai chiều

⚠ Và nên đặt tên vai trò GIỐNG NHAU ở mọi tài khoản:

`VaiTroChoLambda` ở mọi tài khoản
        ↓
    Mã Lambda chỉ cần thay account ID
        ↓
    Không phải duy trì bảng ánh xạ
      tên vai trò

⚠ Và StackSets triển khai vai trò đó ra mọi tài khoản:

aws cloudformation create-stack-set \
  --stack-set-name vai-tro-cho-lambda \
  --template-body file://vai-tro.yaml \
  --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true \
  --capabilities CAPABILITY_NAMED_IAM
Tài khoản mới vào tổ chức
        ↓
    Tự có vai trò
    → không phải làm thủ công

⚠ Và credential tạm nên được cache trong hàm:

import time
_bo_nho = {}

def lay_client(ma_tai_khoan):
    muc = _bo_nho.get(ma_tai_khoan)
    if muc and muc['het_han'] > time.time() + 300:
        return muc['client']
    cred = sts.assume_role(...)['Credentials']
    _bo_nho[ma_tai_khoan] = {
        'client': boto3.client('s3', ...),
        'het_han': cred['Expiration'].timestamp()}
    return _bo_nho[ma_tai_khoan]['client']
Biến toàn cục sống qua nhiều lời
  gọi trong cùng môi trường
        ↓
    Giảm số lời gọi `AssumeRole`
    → nhanh hơn và tránh chạm hạn
      ngạch STS

⚠ Và RoleSessionName giúp truy vết trong CloudTrail:

CloudTrail ở tài khoản đích ghi:
    "assumed-role/VaiTroChoLambda/
     lambda-222222222222"
        ↓
    Biết ngay hàm nào, cho tài khoản
      nào

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

  • **B. Ở tài khoản trung tâm tạo vai trò có các vai trò của tài khoản khác làm trusted entity — đây là phương án gần nhất và cấu trúc trust policy hoàn toàn hợp lệ, nhưng nó cho phép tài khoản khác giả nhận vai trò ở trung tâm, ngược với việc Lambda ở trung tâm chạm tài nguyên ở nơi khác.
  • **A. Ở các tài khoản khác tạo vai trò có quyền giả nhận vai trò của tài khoản trung tâm và thêm Lambda làm trusted entity — chiều bị đảo, và Lambda không chạy ở những tài khoản đó.
  • **E. Ở các tài khoản khác tạo service-linked role cho hàm Lambda của tài khoản trung tâm — service-linked role do chính dịch vụ AWS tạo và quản, không tạo được cho hàm của tài khoản khác.

Ghi nhớ

⚠ Hai vai trò trong mẫu Lambda liên tài khoản — bảng phải thuộc: | Vai trò | Ở đâu | Trust policy trỏ tới | |---|---|---| | Execution role | tài khoản có Lambda | lambda.amazonaws.com | | Cross-account role | tài khoản đích | ARN của execution role |

Từ khoá nhận diện:

"centralized Lambda accessing other accounts" → assume role sang tài khoản đích "role to assume" → luôn ở tài khoản ĐÍCH "permission to assume" → luôn ở tài khoản NGUỒN "third-party service provider" → thêm external ID

Ba lưu ý về trust policy: | Lưu ý | Chi tiết | |---|---| | Trỏ ARN cụ thể chặt hơn :root | | | Thêm sts:ExternalId khi bên thứ ba | | | MaxSessionDuration giới hạn thời hạn phiên | |

⚠ Trỏ tới :root là cho cả tài khoản:

`"AWS": "arn:aws:iam::111111111111:root"`
        ↓
    Bất kỳ danh tính nào trong tài
      khoản đó (nếu IAM policy cho)
        ↓
    Trỏ ARN vai trò cụ thể
    → chặt hơn nhiều

Ba lưu ý về sts:AssumeRole: | Lưu ý | Chi tiết | |---|---| | Credential mặc định 1 giờ, tối đa 12 giờ | | | Hạn ngạch lời gọi STS theo Region | | | Cache credential trong hàm để giảm lời gọi | |

Ba lưu ý về quyền tối thiểu: | Lưu ý | Chi tiết | |---|---| | Liệt kê ARN vai trò cụ thể trong Resource | | | Vai trò đích chỉ có quyền thật sự cần | | | Dùng permissions boundary để chặn leo thang | |

Ba lưu ý về triển khai: | Cách | Đặc điểm | |---|---| | StackSets | phân phối vai trò ra mọi tài khoản | | Đặt tên vai trò giống nhau | mã đơn giản hơn | | Auto deployment | tài khoản mới tự có |

Ba lưu ý về giám sát: | Lưu ý | Chi tiết | |---|---| | CloudTrail ghi mọi AssumeRole | | | RoleSessionName truy về nguồn gốc | | | Đặt cảnh báo khi giả nhận thất bại | |

Ba lưu ý về thay thế: | Cách | Khi nào | |---|---| | Resource-based policy | S3, SQS, SNS cho phép trực tiếp tài khoản khác | | RAM | chia sẻ tài nguyên như subnet, TGW | | Assume role | khi cần quyền chung cho nhiều dịch vụ |

⚠ Resource-based policy đơn giản hơn cho một dịch vụ:

Chỉ cần đọc một bucket S3
        ↓
    Bucket policy cho phép execution
      role đó
        ↓
    Không cần assume role
    → ít một bước

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Gọi hàm và xem log có giả nhận được không | | | Đọc CloudTrail ở tài khoản đích | | | Thử một hành động ngoài quyền — phải bị từ chối | |

Và một lời khuyên: hãy trỏ trust policy tới ARN của execution role thay vì tới :root của tài khoản. Trỏ tới :root mở cửa cho mọi danh tính trong tài khoản trung tâm — kể cả những vai trò được tạo sau này cho mục đích hoàn toàn khác.

Câu 420 Continuous Improvement for Existing Solutions

A company has hired you as an AWS Certified Solutions Architect Professional to develop a deployment plan for its flagship application deployed on EC2 instances across multiple Availability Zones in the us-east-1 Region. Your solution must meet these constraints:

1) A 300 GB static dataset must be available to the application before it can be started

2) The application layer must scale on-demand with the least amount of starting time possible

3) The development team must be able to change the code multiple times in a day

4) Any patches for critical operating systems (OS) must be applied within 24 hours of release

Which of the following represents the best solution for this requirement?

  1. A

    Leverage AWS Systems Manager to create and maintain a new AMI with the OS patches updated on an ongoing basis. Configure the Auto Scaling group to use the patched AMI and replace existing unpatched instances. Use AWS CodeDeploy to push the application code to the instances. Store and access the static dataset using Amazon EFS

  2. B

    Leverage AWS Systems Manager to create and maintain a new AMI with the OS patches updated on an ongoing basis. Configure the Auto Scaling group to use the patched AMI and replace existing unpatched instances. Use AWS CodeDeploy to push the application code to the instances. Configure an Amazon EC2 user data script to download the static dataset from Amazon S3

  3. C

    Leverage AWS Systems Manager to create and maintain a new AMI with the OS patches updated on an ongoing basis. Configure the Auto Scaling group to use the patched AMI and replace existing unpatched instances. Use AWS CodeDeploy to push the application code to the instances. Store and access the static dataset using Amazon EBS

  4. D

    Leverage an Amazon-provided AMI for the OS and set up an Auto Scaling group to scale with traffic. Replace existing instances after each updated Amazon-provided AMI release. Use AWS CodeDeploy to push the application code to the instances. Configure an Amazon EC2 user data script to download the static dataset from Amazon S3

Xem giải thích

Đáp án

**A — Dùng AWS Systems Manager tạo và duy trì AMI mới có bản vá cập nhật liên tục; cấu hình Auto Scaling group dùng AMI đã vá và thay thế instance chưa vá; dùng AWS CodeDeploy đẩy mã ứng dụng lên instance; và lưu, truy cập tập dữ liệu tĩnh bằng Amazon EFS.

Vì sao đúng

Đề nêu bốn ràng buộc, và phương án này khớp cả bốn: | Ràng buộc | Cách đáp ứng | |---|---| | 300 GB dữ liệu tĩnh phải có TRƯỚC khi khởi động | EFS mount là có ngay | | Co giãn với thời gian khởi động ngắn nhất | không phải chép 300 GB | | Đội phát triển đổi mã nhiều lần mỗi ngày | CodeDeploy đẩy mã, không dựng AMI mới | | Vá hệ điều hành trong 24 giờ | SSM dựng AMI vá, ASG thay instance |

⚠ Điểm mấu chốt: 300 GB dữ liệu tĩnh quyết định giữa EFS và các phương án chép:

Chép 300 GB từ S3 lúc khởi động
        ↓
    Ở 500 MB/s: 10 phút
        ↓
    Nhân với mỗi lần co giãn ra
        ↓
    Vi phạm "thời gian khởi động
      ngắn nhất có thể"

Đây là lý do phương án B và D thua — cả hai chép dữ liệu từ S3 qua user data.

⚠ Và EFS mount gần như tức thì:

sudo mount -t efs -o tls fs-0abc123:/ /du-lieu
Vài giây
        ↓
    Dữ liệu có ngay, không phải chép
        ↓
    Và mọi instance thấy cùng một bản
    → cập nhật dữ liệu một chỗ

⚠ Và vì sao phương án C sai — EBS không chia sẻ được:

C dùng EBS cho tập dữ liệu tĩnh
        ↓
    EBS gắn vào MỘT instance
        ↓
    Auto Scaling tạo instance mới
    → phải tạo volume mới từ snapshot
        ↓
    Khôi phục 300 GB từ snapshot mất
      thời gian

⚠ Và EBS khôi phục từ snapshot có hiện tượng "lazy loading":

Volume dựng từ snapshot sẵn sàng
  ngay
        ↓
    Nhưng dữ liệu tải dần từ S3 khi
      đọc lần đầu
        ↓
    Lần đọc đầu rất chậm
        ↓
    Fast Snapshot Restore khắc phục
    → nhưng tính phí theo giờ và
      phải bật trước

⚠ Và vì sao phương án D không đáp ứng yêu cầu vá:

D dùng AMI của Amazon và "thay
  instance sau mỗi bản AMI mới"
        ↓
    Amazon phát hành AMI theo lịch
      riêng
        ↓
    Không bảo đảm trong 24 giờ sau
      khi bản vá ra
        ↓
    Đề yêu cầu 24 giờ

⚠ Và SSM Automation dựng AMI vá tự động:

aws ssm start-automation-execution \
  --document-name AWS-UpdateLinuxAmi \
  --parameters '{
    "SourceAmiId": ["ami-goc123"],
    "IamInstanceProfileName": ["VaiTroSSM"],
    "AutomationAssumeRole":
      ["arn:aws:iam::111122223333:role/SSMAutomation"]}'
Khởi động instance từ AMI gốc
        ↓
    Cài bản vá
        ↓
    Tạo AMI mới
        ↓
    Chấm dứt instance tạm
    → toàn bộ tự động

⚠ Và EC2 Image Builder là công cụ chuyên hơn cho việc này:

aws imagebuilder create-image-pipeline \
  --name pipeline-ami-va \
  --image-recipe-arn <arn-cong-thuc> \
  --infrastructure-configuration-arn <arn-ha-tang> \
  --schedule '{
    "scheduleExpression": "cron(0 2 * * ? *)",
    "pipelineExecutionStartCondition":
      "EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE"}'
`EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`
        ↓
    Chỉ dựng AMI mới khi CÓ bản vá mới
        ↓
    Không dựng thừa mỗi đêm

⚠ Và tách mã ứng dụng khỏi AMI là nguyên tắc quan trọng:

Đội phát triển đổi mã nhiều lần
  mỗi ngày
        ↓
    Dựng AMI mới cho mỗi lần đổi
    → mất 10-20 phút mỗi lần
        ↓
    CodeDeploy đẩy mã lên instance
      đang chạy
    → vài giây

⚠ Và đây là ranh giới thiết kế đáng nhớ: | Thay đổi | Cơ chế | |---|---| | Hệ điều hành, bản vá, runtime | AMI mới + thay instance | | Mã ứng dụng | CodeDeploy | | Cấu hình | Parameter Store, App Config | | Dữ liệu | EFS, S3 |

Cấu hình CodeDeploy với ASG:

aws deploy create-deployment-group \
  --application-name ung-dung \
  --deployment-group-name san-xuat \
  --auto-scaling-groups doi-ung-dung \
  --deployment-config-name CodeDeployDefault.OneAtATime \
  --service-role-arn <arn-role>
CodeDeploy tự nhận instance mới
  của ASG
        ↓
    Và đẩy phiên bản mã hiện tại
      lên đó
    → instance mới luôn có mã mới nhất

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Khởi động nhanh vì không chép dữ liệu | | | Mã và hệ điều hành cập nhật độc lập | | | Dữ liệu chia sẻ, cập nhật một chỗ | |

⚠ Nhưng EFS cần chú ý chế độ thông lượng:

300 GB ở chế độ Bursting
        ↓
    Thông lượng nền = 50 KB/s mỗi GB
    → 15 MB/s
        ↓
    Nhiều instance cùng đọc
    → cạn tín dụng bùng nổ
        ↓
    Dùng chế độ Elastic
aws efs update-file-system --file-system-id fs-0abc123 \
  --throughput-mode elastic

⚠ Và EFS đắt hơn EBS và S3 đáng kể: | Kho | Giá xấp xỉ | |---|---| | S3 Standard | 0,023 USD/GB | | EBS gp3 | 0,08 USD/GB | | EFS Standard | 0,30 USD/GB |

300 GB trên EFS ≈ 90 USD/tháng
        ↓
    Đắt nhưng đổi lấy khởi động nhanh
      và chia sẻ được
        ↓
    Bật lifecycle sang IA nếu phần
      lớn ít đọc

⚠ Và có lựa chọn thứ tư: nhúng dữ liệu vào AMI:

Đưa 300 GB vào chính AMI
        ↓
    Instance khởi động là có sẵn
        ↓
    Nhưng AMI 300 GB dựng rất lâu
        ↓
    Và cập nhật dữ liệu phải dựng
      lại AMI
    → không hợp với dữ liệu hay đổi

⚠ Và Mountpoint for S3 là lựa chọn mới đáng biết:

Mount bucket S3 như hệ tệp
        ↓
    Chi phí lưu trữ như S3
        ↓
    Nhưng không phải hệ tệp POSIX
      đầy đủ
    → chỉ hợp với đọc tuần tự

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

  • **B. Như A nhưng dùng user data script tải tập dữ liệu từ S3 — đây là phương án gần nhất và ba vế đầu hoàn toàn đúng, nhưng chép 300 GB từ S3 mỗi lần khởi động làm thời gian co giãn dài ra rất nhiều, vi phạm yêu cầu khởi động nhanh nhất có thể.
  • **C. Như A nhưng lưu tập dữ liệu trên Amazon EBS — EBS gắn vào một instance nên mỗi instance mới phải dựng volume từ snapshot, và lazy loading làm lần đọc đầu rất chậm.
  • **D. Dùng AMI của Amazon và thay instance sau mỗi bản phát hành, kèm user data tải dữ liệu từ S3 — lịch phát hành AMI của Amazon không bảo đảm vá trong 24 giờ, và vẫn phải chép 300 GB.

Ghi nhớ

⚠ Bốn tầng thay đổi và cơ chế tương ứng — bảng phải thuộc: | Tầng | Cơ chế | Tần suất | |---|---|---| | Hệ điều hành | AMI mới + thay instance | hằng tháng hoặc khi có CVE | | Runtime, thư viện | AMI hoặc container image | hằng tuần | | Mã ứng dụng | CodeDeploy | nhiều lần mỗi ngày | | Cấu hình | Parameter Store, AppConfig | bất cứ lúc nào |

Từ khoá nhận diện:

"large static dataset before app starts" → EFS, không chép từ S3 "code changes multiple times a day" → CodeDeploy, không dựng AMI "patch within 24 hours" → pipeline dựng AMI tự động "fastest possible start time" → tránh mọi việc chép dữ liệu lớn

Ba lưu ý về EFS: | Lưu ý | Chi tiết | |---|---| | Chế độ Elastic tự co giãn thông lượng | | | Bursting cạn tín dụng với dữ liệu nhỏ | | | Lifecycle sang IA giảm chi phí nhiều | |

⚠ EFS access point cô lập theo ứng dụng:

aws efs create-access-point --file-system-id fs-0abc123 \
  --posix-user Uid=1001,Gid=1001 \
  --root-directory 'Path=/du-lieu-ung-dung'

Ba lưu ý về EC2 Image Builder: | Lưu ý | Chi tiết | |---|---| | Pipeline có bước build, test, phân phối | | | Chạy khi có bản vá mới | | | Tự chia sẻ AMI sang Region và tài khoản khác | |

Ba lưu ý về CodeDeploy: | Lưu ý | Chi tiết | |---|---| | Tích hợp với ASG, instance mới tự nhận mã | | | AppSpec định nghĩa các hook vòng đời | | | Blue/green với hai ASG | |

⚠ Hook BeforeAllowTraffic để kiểm thử:

hooks:
  BeforeAllowTraffic:
    - location: scripts/kiem-tra.sh
      timeout: 300

Ba lưu ý về warm pool: | Lưu ý | Chi tiết | |---|---| | Giữ instance đã cài đặt xong ở trạng thái Stopped | | | Rút ngắn thời gian co giãn rất nhiều | | | Chỉ trả phí EBS, không trả phí instance | |

⚠ Warm pool là giải pháp cho việc khởi động chậm:

aws autoscaling put-warm-pool \
  --auto-scaling-group-name doi-ung-dung \
  --min-size 4 --pool-state Stopped
Nếu buộc phải chép dữ liệu lúc
  khởi động
        ↓
    Warm pool làm việc đó TRƯỚC
        ↓
    Khi cần chỉ việc bật máy

Ba lưu ý về Patch Manager: | Lưu ý | Chi tiết | |---|---| | AWS-RunPatchBaseline cho cả Linux và Windows | | | Vá tại chỗ hoặc dựng AMI mới | | | Báo cáo tuân thủ cho kiểm toán | |

Ba lưu ý về hạ tầng bất biến: | Lưu ý | Chi tiết | |---|---| | Dựng AMI mới thay vì vá máy đang chạy | | | Không có configuration drift | | | Cần ứng dụng không giữ trạng thái | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Đo thời gian từ khởi động tới InService | | | Kiểm instance mới có mã mới nhất | | | Xem báo cáo tuân thủ vá của SSM | |

Và một lời khuyên: hãy cân nhắc warm pool nếu vẫn còn bất kỳ việc chuẩn bị nào tốn thời gian lúc khởi động. EFS bỏ được việc chép 300 GB, nhưng nếu ứng dụng còn phải nạp cache hay khởi tạo gì nữa thì warm pool là cách duy nhất để việc đó xảy ra trước khi bạn cần công suất.