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

Tìm thấy 1221 câu.

Câu 291 Domain - Design for New Solutions

A company has several applications written in TypeScript and Python hosted on the AWS cloud. The company uses an automated deployment solution for its applications using AWS CloudFormation templates and AWS CodePipeline. The company recently acquired a new business unit that uses Python scripts to deploy applications on AWS. The developers from the new business are having difficulty migrating their deployments to AWS CloudFormation because they need to learn a new domain-specific language and their old Python scripts require programming loops, which are not supported in CloudFormation.

Which of the following is the recommended solution to address the developers’ concerns and help them update their deployment procedures?

  1. A

    Ask the developers to continue using Python scripts for deploying new resources. Once the resources are created, import them into a new CloudFormation stack.

  2. B

    Write TypeScript or Python code that will define AWS resources. Convert these codes to AWS CloudFormation templates by using AWS Cloud Development Kit (AWS CDK). Create CloudFormation stacks using AWS CDK. Create an AWS CodeBuild job that includes AWS CDK and add this stage to AWS CodePipeline.

  3. C

    Create a standard deployment process for the company and the new business unit by leveraging a third-party resource provisioning engine on AWS CodeBuild. Add a stage on AWS CodePipeline to integrate AWS CodeBuild on the application deployment.

  4. D

    Write new CloudFormation templates for the deployments of the new business unit. Extract parts of the Python scripts to be added as EC2 user data. Deploy the CloudFormation templates using the AWS Cloud Development Kit (AWS CDK). Add a stage on AWS CodePipeline to integrate AWS CDK using the templates for the application deployment.

Xem giải thích

Đáp án

**B — Viết mã TypeScript hoặc Python để định nghĩa tài nguyên AWS, dùng AWS Cloud Development Kit (CDK) chuyển mã đó thành template CloudFormation và tạo stack; rồi thêm một job CodeBuild có CDK vào CodePipeline.

Vì sao đúng

Đề nêu hai lời phàn nàn rất cụ thể, và CDK giải quyết đúng cả hai: | Phàn nàn | CDK giải quyết thế nào | |---|---| | Phải học một ngôn ngữ chuyên biệt mới | viết bằng TypeScript/Python — ngôn ngữ họ đã biết | | Cần vòng lặp, CloudFormation không có | for của ngôn ngữ lập trình thật |

⚠ Điểm mấu chốt: CDK không thay thế CloudFormation, nó SINH RA CloudFormation:

Viết mã Python/TypeScript
        ↓
    `cdk synth` biên dịch thành
      template CloudFormation
        ↓
    CloudFormation triển khai
    → vẫn có drift detection, rollback,
      change set như cũ

Đây là lý do đáp án này giữ được toàn bộ quy trình hiện có của công ty.

Vòng lặp thật trong CDK:

from aws_cdk import Stack, aws_s3 as s3
from constructs import Construct

class StackKho(Stack):
    def __init__(self, scope: Construct, id: str, **kw):
        super().__init__(scope, id, **kw)
        for moi_truong in ['phat-trien', 'thu-nghiem', 'san-xuat']:
            s3.Bucket(self, f'kho-{moi_truong}',
                      bucket_name=f'du-lieu-{moi_truong}',
                      versioned=(moi_truong == 'san-xuat'),
                      encryption=s3.BucketEncryption.S3_MANAGED)

⚠ Trong CloudFormation thuần, việc này phải viết ba khối riêng:

Resources:
  KhoPhatTrien: {Type: AWS::S3::Bucket, Properties: {...}}
  KhoThuNghiem: {Type: AWS::S3::Bucket, Properties: {...}}
  KhoSanXuat:   {Type: AWS::S3::Bucket, Properties: {...}}
Ba khối gần giống nhau
    → sửa một thứ phải sửa ba chỗ
        ↓
    CloudFormation có `Fn::ForEach`
      (từ 2023) nhưng cú pháp rất
      rườm rà

Thêm CDK vào pipeline:

version: 0.2
phases:
  install:
    runtime-versions: {nodejs: 20, python: 3.12}
    commands:
      - npm install -g aws-cdk
      - pip install -r requirements.txt
  build:
    commands:
      - cdk synth
      - cdk deploy --require-approval never

⚠ Và CDK có construct cấp cao giảm rất nhiều mã:

from aws_cdk import aws_ec2 as ec2
vpc = ec2.Vpc(self, 'MangChinh', max_azs=3, nat_gateways=1)
Một dòng này sinh ra: VPC, 6 subnet,
  internet gateway, NAT gateway,
  3 bảng định tuyến, các liên kết
        ↓
    Trong CloudFormation thuần:
      hàng trăm dòng YAML

⚠ Ba cấp construct — phải phân biệt: | Cấp | Tên | Đặc điểm | |---|---|---| | L1 | CfnBucket | ánh xạ 1-1 với CloudFormation | | L2 | Bucket | có mặc định hợp lý, phương thức tiện lợi | | L3 | pattern | ghép nhiều dịch vụ thành kiến trúc sẵn |

# L3: một dòng ra cả kiến trúc
from aws_cdk import aws_ecs_patterns as patterns
patterns.ApplicationLoadBalancedFargateService(
    self, 'DichVu', cpu=512, memory_limit_mib=1024,
    task_image_options={'image': ecs.ContainerImage.from_registry('nginx')})

⚠ Và grant là thứ tiện nhất của CDK:

kho = s3.Bucket(self, 'Kho')
ham = lambda_.Function(self, 'Ham', ...)
kho.grant_read_write(ham)
Một dòng này sinh ra chính sách
  IAM với đúng hành động, đúng ARN
        ↓
    Không phải tự viết JSON
    → và không phải đoán tên hành
      động nào cần thiết

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

A: cứ dùng script Python, rồi
  import tài nguyên vào stack
        ↓
    Không giải quyết vấn đề nào cả
    → vẫn hai quy trình khác nhau
        ↓
    Và import tài nguyên là thao
      tác thủ công, dễ sai

⚠ Và vì sao phương án D lộn xộn:

D: viết template CloudFormation MỚI,
  trích script Python thành EC2
  user data
        ↓
    Vẫn phải học CloudFormation
    → đúng thứ đề nói họ không
      muốn
        ↓
    Và user data là script chạy
      TRONG máy, không phải cách
      cấp phát hạ tầng

⚠ Và phương án C dùng công cụ bên thứ ba:

"Third-party resource provisioning
  engine" (Terraform, Pulumi...)
        ↓
    Là lựa chọn hợp lệ trong thực tế
    → nhưng công ty đã đầu tư vào
      CloudFormation và CodePipeline
        ↓
    CDK giữ được toàn bộ, và vẫn
      cho viết bằng Python

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Dùng ngôn ngữ và IDE quen thuộc | | | Có vòng lặp, hàm, lớp, kiểm thử đơn vị | | | Vẫn triển khai bằng CloudFormation | |

⚠ Và kiểm thử đơn vị cho hạ tầng là điều CloudFormation không có:

from aws_cdk.assertions import Template

def test_kho_co_ma_hoa():
    template = Template.from_stack(StackKho(App(), 'Thu'))
    template.has_resource_properties('AWS::S3::Bucket', {
        'BucketEncryption': Match.any_value()})

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

  • **D. Viết template CloudFormation mới cho đơn vị mới, trích script Python thành EC2 user data, rồi triển khai bằng CDK — đây là phương án gần nhất và có nhắc tới CDK, nhưng nó vẫn bắt lập trình viên viết CloudFormation, và user data là script chạy trong máy chứ không phải cách cấp phát hạ tầng.
  • **A. Tiếp tục dùng script Python rồi import tài nguyên vào stack CloudFormation — không hợp nhất được quy trình, và import là thao tác thủ công dễ sai.
  • **C. Dùng công cụ cấp phát bên thứ ba trên CodeBuild — bỏ đi khoản đầu tư vào CloudFormation mà không cần thiết; CDK đã giải quyết đúng vấn đề.

Ghi nhớ

⚠ Bốn công cụ hạ tầng dạng mã trên AWS — bảng phải thuộc: | Công cụ | Ngôn ngữ | Nền dưới | |---|---|---| | CloudFormation | YAML/JSON | chính nó | | CDK | TypeScript, Python, Java, Go, C# | CloudFormation | | SAM | YAML rút gọn | CloudFormation | | Terraform | HCL | API AWS trực tiếp |

Từ khoá nhận diện:

"developers don't want to learn DSL" → CDK "need loops and conditionals" → CDK "serverless application" → SAM hoặc CDK "multi-cloud" → Terraform "deploy same stack to many accounts" → StackSets

Ba lưu ý về CDK: | Lưu ý | Chi tiết | |---|---| | cdk bootstrap một lần mỗi tài khoản/Region | | | cdk diff xem thay đổi trước khi triển khai | | | cdk synth xuất ra template để kiểm tra | |

⚠ Bootstrap là bước hay bị quên:

CDK cần một bucket S3 và vài
  vai trò IAM để hoạt động
        ↓
    `cdk bootstrap aws://111122223333/ap-southeast-1`
        ↓
    Quên: lỗi "This stack uses
      assets, please run cdk bootstrap"

Ba lưu ý về CDK Pipelines: | Lưu ý | Chi tiết | |---|---| | Pipeline tự cập nhật chính nó | | | Triển khai được nhiều tài khoản, nhiều Region | | | Có bước phê duyệt thủ công | |

Ba lưu ý về quản lý trạng thái: | Công cụ | Trạng thái ở đâu | |---|---| | CloudFormation/CDK | AWS quản lý | | Terraform | tệp state, phải tự lưu và khoá |

⚠ Đây là ưu thế lớn của CloudFormation:

Terraform: state file mất là
  mất dấu vết tài nguyên
        ↓
    Phải dựng S3 backend + DynamoDB
      lock
        ↓
    CloudFormation: trạng thái nằm
      trong dịch vụ, không mất được

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 | | | Cấm sửa tay bằng SCP hoặc stack policy | |

Ba lưu ý về CI/CD: | Bước | Việc | |---|---| | Source | CodeCommit, GitHub, S3 | | Build | CodeBuild chạy cdk synth | | Deploy | CloudFormation hoặc cdk deploy |

Ba lưu ý về an toàn khi triển khai: | Lưu ý | Chi tiết | |---|---| | Change set xem trước thay đổi | | | Stack policy chặn xoá tài nguyên quan trọng | | | Rollback tự động khi lỗi | |

⚠ Stack policy bảo vệ CSDL khỏi bị xoá nhầm:

{"Statement": [{
  "Effect": "Deny",
  "Action": ["Update:Replace", "Update:Delete"],
  "Principal": "*",
  "Resource": "LogicalResourceId/CoSoDuLieuChinh"}]}

Ba việc kiểm chứng: | Việc | Cách | |---|---| | cdk diff trước mỗi lần triển khai | | | Chạy cdk synth xem template sinh ra | | | Triển khai vào tài khoản thử trước | |

Và một lời khuyên: hãy luôn đọc kết quả cdk diff trước khi triển khai vào sản xuất. CDK sinh ra template thay bạn, và một thay đổi trông vô hại trong mã Python có thể dịch thành việc thay thế cả một cơ sở dữ liệu — diff là chỗ duy nhất bạn thấy được điều đó trước khi nó xảy ra.

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

A multinational consumer goods company is currently using a VMWare vCenter Server to manage their virtual machines, multiple ESXi hosts, and all dependent components from a single centralized location. To save costs and to avail the benefits of cloud computing, the company decided to move its virtual machines to AWS. The Solutions Architect is required to generate new AMIs of the existing virtual machines which can then be launched as an EC2 instance in the company VPC.

Which combination of steps should the Solutions Architect do to properly execute the cloud migration? (Select TWO.)

  1. A

    Use the AWS Application Migration Service to migrate your on-premises workloads to the AWS cloud.

  2. B

    Create an AWS CloudFormation template that mirrors the on-premises virtualized environment. Deploy the stack to the AWS cloud.

  3. C

    Establish a Direct Connect connection between your data center and your VPC. Use AWS Service Catalog to centrally manage all your IT services and to quickly migrate virtual machines to your virtual private cloud.

  4. D

    Use Serverless Application Model (SAM) to migrate the virtual machines (VMs) to AWS and automatically launch an Amazon ECS Cluster to host the VMs.

  5. E

    Install the AWS Replication Agent in your on-premises virtualization environment.

Xem giải thích

Đáp án

**A và E — Dùng AWS Application Migration Service (MGN) để di trú khối lượng công việc tại chỗ lên AWS, và cài AWS Replication Agent vào môi trường ảo hoá tại chỗ.

Vì sao đúng

Đề mô tả một môi trường VMware vCenter cần chuyển sang EC2, và hai đáp án là hai vế của cùng một quy trình: | Vế | Việc | |---|---| | MGN | dịch vụ điều phối toàn bộ việc di trú | | Replication Agent | thành phần cài trên máy nguồn để sao chép đĩa |

⚠ Không có agent thì MGN không có gì để sao chép:

MGN là dịch vụ phía AWS
        ↓
    Nó cần một tác nhân trong máy
      nguồn đọc từng khối đĩa
        ↓
    Agent gửi dữ liệu liên tục
      sang AWS
    → không có agent, không có
      dữ liệu

Luồng di trú:

Cài Replication Agent lên từng VM
        ↓
    Agent sao chép TOÀN BỘ đĩa
      (block-level) sang staging
      area trong AWS
        ↓
    Sao chép LIÊN TỤC, máy nguồn
      vẫn chạy
        ↓
    Chạy "test instance" để kiểm thử
        ↓
    Cutover: dừng nguồn, khởi động
      instance thật

⚠ Điểm mấu chốt: sao chép liên tục nghĩa là ngừng dịch vụ rất ngắn:

Sao chép một lần rồi chuyển
    → dữ liệu thay đổi trong lúc
      chép bị mất
        ↓
    MGN sao chép liên tục
    → tới lúc cutover chỉ còn
      độ trễ vài phút

Cài agent:

wget -O aws-replication-installer-init.py \
  https://aws-application-migration-service-ap-southeast-1.s3.\
ap-southeast-1.amazonaws.com/latest/linux/aws-replication-installer-init.py
sudo python3 aws-replication-installer-init.py \
  --region ap-southeast-1 \
  --aws-access-key-id AKIA... --aws-secret-access-key ...

⚠ Và MGN tự tạo AMI — đúng thứ đề yêu cầu:

Đề nói: "tạo AMI mới từ các máy
  ảo hiện có"
        ↓
    MGN dựng volume EBS từ dữ liệu
      sao chép
    → và sinh AMI cho việc khởi động
        ↓
    Không phải xuất OVA rồi nhập
      thủ công

⚠ Và "test instance" là tính năng đáng giá nhất:

Khởi động bản sao trong VPC tách
  biệt
        ↓
    Kiểm thử toàn bộ ứng dụng
    → máy nguồn VẪN CHẠY sản xuất
        ↓
    Hỏng thì xoá đi thử lại
    → không rủi ro gì

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

B: viết template CloudFormation
  "phản chiếu" môi trường ảo tại chỗ
        ↓
    CloudFormation tạo tài nguyên
      MỚI, TRỐNG
        ↓
    Không mang theo hệ điều hành,
      ứng dụng, dữ liệu, cấu hình
    → đó là dựng lại từ đầu, không
      phải di trú

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

C: Direct Connect + Service Catalog
        ↓
    Direct Connect là ĐƯỜNG TRUYỀN
    → hữu ích nhưng không di trú gì
        ↓
    Service Catalog là danh mục
      sản phẩm chuẩn hoá cho người
      dùng nội bộ
    → không liên quan tới di trú VM

⚠ Và phương án D sai hoàn toàn về mục đích công cụ:

SAM = Serverless Application Model
    → framework cho Lambda,
      API Gateway, DynamoDB
        ↓
    Không di trú máy ảo
    → và "khởi động cụm ECS để
      chứa VM" là chuyện không tồn
      tại: container không chạy
      được máy ảo

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Ngừng dịch vụ chỉ vài phút | | | Kiểm thử trước khi chuyển thật | | | Miễn phí trong 90 ngày mỗi máy chủ | |

⚠ Và điểm cuối là chi tiết ít người biết:

MGN miễn phí 90 ngày cho mỗi
  máy chủ nguồn
        ↓
    Chỉ trả tiền cho tài nguyên
      staging (EBS, EC2 nhỏ)
        ↓
    Đủ thời gian cho một dự án
      di trú bình thường

⚠ Và MGN thay thế cả SMS lẫn CloudEndure: | Công cụ | Trạng thái | |---|---| | AWS Server Migration Service (SMS) | ngừng, thay bằng MGN | | CloudEndure Migration | ngừng, thay bằng MGN | | VM Import/Export | còn, nhưng thủ công và phải dừng máy | | MGN | hiện hành, khuyến nghị |

⚠ Và có công cụ khảo sát trước khi di trú:

AWS Application Discovery Service
    → thu thập cấu hình, hiệu năng,
      phụ thuộc mạng
        ↓
    Migration Hub gom kết quả và
      theo dõi tiến độ
        ↓
    Nên chạy TRƯỚC khi cài agent
      sao chép

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

  • **C. Dựng Direct Connect giữa trung tâm dữ liệu và VPC, dùng Service Catalog để quản lý và di trú máy ảo — đây là phương án gần nhất và Direct Connect thật sự hữu ích cho việc di trú lượng lớn dữ liệu, nhưng nó chỉ là đường truyền; Service Catalog là danh mục sản phẩm chuẩn hoá, không di trú máy ảo.
  • **B. Viết CloudFormation phản chiếu môi trường tại chỗ — tạo hạ tầng mới rỗng, không mang theo hệ điều hành, ứng dụng hay dữ liệu.
  • **D. Dùng SAM để di trú VM và khởi động cụm ECS để chứa chúng — SAM là framework serverless; container không chạy được máy ảo.

Ghi nhớ

⚠ Năm dịch vụ di trú của AWS — bảng phải thuộc: | Dịch vụ | Di trú gì | |---|---| | MGN | máy chủ (block-level), lift-and-shift | | DMS | cơ sở dữ liệu, có CDC | | DataSync | tệp: NFS, SMB, S3, EFS, FSx | | Transfer Family | SFTP/FTPS vào S3, EFS | | Snow Family | dữ liệu lớn qua thiết bị vật lý |

Từ khoá nhận diện:

"migrate VMs to EC2, minimal downtime" → MGN + Replication Agent "migrate database with minimal downtime" → DMS full load + CDC "discover dependencies before migrating" → Application Discovery Service "track migration progress" → Migration Hub "replatform to containers" → App2Container

⚠ App2Container là công cụ ít biết nhưng hữu ích:

Ứng dụng Java hoặc .NET đang chạy
    → A2C phân tích và đóng gói
      thành container
        ↓
    Sinh sẵn task definition ECS
      hoặc manifest EKS
    → hiện đại hoá thay vì chỉ
      lift-and-shift

Sáu chiến lược di trú (6 R): | Chiến lược | Nghĩa | |---|---| | Rehost | lift-and-shift, MGN | | Replatform | đổi nhẹ, ví dụ sang RDS | | Repurchase | mua SaaS thay thế | | Refactor | viết lại theo kiến trúc đám mây | | Retire | bỏ đi, không dùng nữa | | Retain | giữ tại chỗ |

⚠ Retire thường tiết kiệm nhiều nhất:

Khảo sát thường phát hiện 10-20%
  máy chủ không ai dùng
        ↓
    Di trú chúng là trả tiền cho
      thứ vô dụng
    → khảo sát trước khi di trú

Ba lưu ý về MGN: | Lưu ý | Chi tiết | |---|---| | Miễn phí 90 ngày mỗi máy chủ nguồn | | | Cần cổng TCP 443 và 1500 ra AWS | | | Staging area dùng instance nhỏ và EBS rẻ | |

⚠ Cổng 1500 hay bị tường lửa chặn:

Agent gửi dữ liệu sao chép qua
  cổng 1500 tới replication server
        ↓
    Tường lửa chặn → agent cài xong
      mà không sao chép được
        ↓
    Kiểm tra trước khi cài hàng loạt

Ba lưu ý về launch template: | Lưu ý | Chi tiết | |---|---| | Đặt kiểu instance, subnet, security group trước | | | Cấu hình được cho từng máy nguồn | | | Kiểm tra kỹ trước khi cutover | |

Ba lưu ý về kiểm thử: | Lưu ý | Chi tiết | |---|---| | Khởi động test instance nhiều lần được | | | Test trong VPC tách biệt | | | Kiểm cả ứng dụng lẫn kết nối tới hệ thống khác | |

Ba lưu ý về cutover: | Bước | Việc | |---|---| | Dừng ứng dụng ở nguồn | | | Chờ sao chép về độ trễ 0 | | | Khởi động instance cutover, đổi DNS | |

Ba lưu ý sau di trú: | Lưu ý | Chi tiết | |---|---| | Gỡ agent khỏi máy nguồn | | | Đánh dấu "finalize cutover" trong MGN | | | Dọn tài nguyên staging | |

⚠ Quên finalize là vẫn bị tính phí:

Staging area giữ nguyên
    → EBS và instance sao chép
      vẫn chạy
        ↓
    Finalize xong mới dọn

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy test instance và kiểm thử toàn diện | | | So hiệu năng với máy cũ | | | Kiểm độ trễ sao chép trước khi cutover | |

Và một lời khuyên: hãy chạy Application Discovery Service trước khi cài agent lên bất cứ máy nào. Danh sách máy chủ trong tài liệu bao giờ cũng lệch so với thực tế, và những phụ thuộc mạng không ai nhớ ra chính là thứ làm hỏng đêm cutover.

Câu 293 Domain - Continuous Improvement for Existing Solutions

A technology company is developing an educational mobile app for students, with an exam feature that also allows them to submit their answers. The developers used React Native so the app can be deployed on both iOS and Android devices. They used AWS Lambda and Amazon API Gateway for the backend services and a DynamoDB table as the database service. After a month, the released app has been downloaded over 3 million times. However, there are a lot of users who complain about the slow processing of the app especially when they are submitting their answers in the multiple-choice exams. The diagrams and images on the exam also take a lot of time to load, which is not a good user experience.

Which of the following options provides the most cost-effective and scalable architecture for the application?

  1. A

    Increase the write capacity in DynamoDB to 10,000 WCU. Use a web distribution in CloudFront with associated CloudFront Functions to host the diagrams, images and other static assets of the mobile app in real-time

  2. B

    Instead of DynamoDB, use RDS Multi-AZ configuration with Read Replicas. Use a web distribution in CloudFront and Amazon S3 to host the diagrams, images, and other static assets of the mobile app.

  3. C Enable Auto Scaling in DynamoDB with a Target Utilization of 100% and a maximum provisioned capacity of 1000 units. Use an S3 bucket to host the diagrams, images, and other static assets of the mobile app.
  4. D

    Launch an SQS queue and develop a custom service which integrates with SQS to buffer the incoming requests. Use a web distribution in CloudFront and Amazon S3 to host the diagrams, images, and other static assets of the mobile app.

Xem giải thích

Đáp án

**D — Dựng một hàng đợi SQS và một dịch vụ đọc từ hàng đợi để đệm các yêu cầu nộp bài; đồng thời dùng CloudFront với origin là S3 để phục vụ sơ đồ, hình ảnh và tài nguyên tĩnh.

Vì sao đúng

Đề mô tả hai triệu chứng khác nhau, cần hai cách chữa khác nhau: | Triệu chứng | Nguyên nhân | Cách chữa | |---|---|---| | Nộp bài chậm | đỉnh ghi vượt công suất DynamoDB | SQS đệm lại | | Sơ đồ và ảnh tải chậm | phục vụ từ xa, không cache | S3 + CloudFront |

⚠ Điểm mấu chốt: nộp bài thi tạo đỉnh ghi rất nhọn:

Hàng nghìn học sinh bấm "Nộp bài"
  gần như cùng lúc
        ↓
    DynamoDB bị chặn (throttle)
    → ứng dụng nhận lỗi hoặc chờ
        ↓
    Người dùng thấy "chậm"

⚠ SQS làm phẳng đỉnh — đây là mẫu kinh điển:

Đỉnh 10.000 yêu cầu/giây trong
  30 giây
        ↓
    SQS nhận hết ngay, trả về cho
      client tức thì
        ↓
    Consumer đọc và ghi vào DynamoDB
      với tốc độ ổn định
        ↓
    Người dùng: "đã nộp" ngay
    → xử lý xong sau vài giây

Gửi vào hàng đợi thay vì ghi thẳng:

import boto3, json, uuid
sqs = boto3.client('sqs')

def xu_ly(event, context):
    sqs.send_message(
        QueueUrl=URL_HANG_DOI,
        MessageBody=json.dumps({
            'ma_bai_lam': str(uuid.uuid4()),
            'ma_hoc_sinh': event['ma_hoc_sinh'],
            'dap_an': event['dap_an']}))
    return {'statusCode': 202,
            'body': json.dumps({'trang_thai': 'da-nhan'})}

⚠ Mã 202 Accepted là đúng ngữ nghĩa ở đây:

200 OK: đã xử lý xong
        ↓
    202 Accepted: đã nhận, sẽ xử lý
    → phản ánh đúng mô hình bất
      đồng bộ

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

A: nâng WCU lên 10.000 cố định
        ↓
    Trả tiền cho 10.000 WCU suốt
      24 giờ
    → trong khi chỉ cần lúc thi
        ↓
    Đề hỏi "hiệu quả chi phí nhất"
    → đây là phương án đắt nhất

⚠ Và CloudFront Functions trong phương án A dùng sai việc:

A nói dùng CloudFront Functions
  để "host" ảnh và sơ đồ
        ↓
    Functions là mã chạy ở biên
      để sửa request/response
    → không lưu trữ tệp
        ↓
    Lưu trữ là việc của S3

⚠ Và vì sao phương án C sai — Target Utilization 100%:

Auto scaling nhắm 100% mức dùng
        ↓
    Nghĩa là không chừa biên nào
    → mọi đỉnh nhỏ đều gây throttle
        ↓
    AWS khuyến nghị 70%
Và trần 1.000 đơn vị
    → với 3 triệu lượt tải,
      hoàn toàn không đủ

⚠ Và auto scaling của DynamoDB phản ứng CHẬM:

Phát hiện qua CloudWatch → mất
  vài phút
        ↓
    Đỉnh nộp bài kéo dài 30 giây
    → scaling xong thì đỉnh đã qua
        ↓
    Đây là lý do đệm bằng SQS hơn
      hẳn scaling

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

B: bỏ DynamoDB, chuyển sang RDS
  Multi-AZ + read replica
        ↓
    Vấn đề là đỉnh GHI
    → read replica không giúp
      gì cho ghi
        ↓
    Và RDS chịu đỉnh ghi kém hơn
      DynamoDB

Phục vụ tài nguyên tĩnh:

aws s3 sync ./tai-nguyen s3://tai-nguyen-app/ \
  --cache-control "public, max-age=31536000, immutable"

⚠ max-age dài kết hợp tên tệp có mã băm:

so-do-a3f9c2.png
        ↓
    Cache một năm ở trình duyệt
      và ở biên
        ↓
    Đổi nội dung → đổi tên
    → không cần invalidate gì

⚠ Và với ứng dụng di động, CloudFront giảm độ trễ rất rõ:

Ảnh phục vụ từ một Region
    → học sinh ở xa: hàng trăm
      mili giây mỗi ảnh
        ↓
    CloudFront: phục vụ từ điểm
      biên gần nhất
    → và một trang thi có nhiều ảnh

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Đỉnh ghi không làm chậm người dùng | | | Trả tiền theo lượt dùng thật | | | Ảnh phục vụ từ điểm biên | |

⚠ Nhưng bất đồng bộ đổi trải nghiệm người dùng:

Người dùng không biết bài đã
  được chấm chưa
        ↓
    Phải có cách kiểm tra trạng thái
    → hoặc thông báo đẩy khi xong
        ↓
    Không thiết kế phần này thì
      "đã nhận" trở thành mơ hồ

⚠ Và DynamoDB on-demand là lựa chọn cũng đáng cân nhắc:

aws dynamodb update-table --table-name bai-lam \
  --billing-mode PAY_PER_REQUEST
On-demand chịu được đỉnh gấp đôi
  mức cao nhất trước đó ngay lập tức
        ↓
    Không cần đoán công suất
    → đắt hơn mỗi đơn vị nhưng
      không trả cho lúc rảnh
        ↓
    Kết hợp SQS + on-demand là
      an toàn nhất

⚠ Và SQS FIFO hay Standard — ở đây Standard đủ: | Loại | Thứ tự | Thông lượng | |---|---|---| | Standard | không bảo đảm | gần như không giới hạn | | FIFO | bảo đảm | 3.000 msg/s có batching |

Bài làm của mỗi học sinh độc lập
    → không cần thứ tự toàn cục
    → Standard, thông lượng cao hơn

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

  • **C. Bật auto scaling DynamoDB với Target Utilization 100% và trần 1.000 đơn vị, dùng S3 cho tài nguyên tĩnh — đây là phương án gần nhất và đưa tài nguyên tĩnh sang S3 là đúng hướng, nhưng nhắm 100% mức dùng không chừa biên nào, trần 1.000 đơn vị quá thấp, và không có CloudFront nên độ trễ toàn cầu vẫn cao.
  • **A. Nâng WCU lên 10.000 cố định và dùng CloudFront Functions để host ảnh — trả tiền cho công suất tối đa suốt ngày; và Functions không lưu trữ tệp.
  • **B. Thay DynamoDB bằng RDS Multi-AZ với read replica — vấn đề là đỉnh ghi; read replica chỉ giúp việc đọc.

Ghi nhớ

⚠ Bốn cách chịu đỉnh ghi — bảng phải thuộc: | Cách | Đặc điểm | |---|---| | SQS đệm | làm phẳng đỉnh, bất đồng bộ | | DynamoDB on-demand | tự chịu đỉnh, đắt hơn mỗi đơn vị | | Auto scaling | phản ứng chậm vài phút | | Cấp cố định mức đỉnh | đắt nhất |

Từ khoá nhận diện:

"spike in writes, cost-effective" → SQS đệm "images and static assets slow" → S3 + CloudFront "unpredictable traffic" → on-demand "decouple components" → SQS "must process in order" → SQS FIFO

Ba lưu ý về SQS: | Lưu ý | Chi tiết | |---|---| | Giữ tin tối đa 14 ngày | | | Visibility timeout phải dài hơn thời gian xử lý | | | Dead-letter queue cho tin xử lý hỏng | |

⚠ Visibility timeout đặt sai gây xử lý trùng:

Timeout 30 giây, xử lý mất 45 giây
        ↓
    Tin hiện lại trước khi xử lý xong
    → consumer khác nhận cùng tin
        ↓
    Bài làm ghi hai lần

Ba lưu ý về DLQ: | Lưu ý | Chi tiết | |---|---| | maxReceiveCount quyết định khi nào chuyển sang DLQ | | | Đặt cảnh báo khi DLQ có tin | | | DLQ trống nghĩa là mọi tin đã xử lý được | |

Ba lưu ý về consumer: | Lựa chọn | Đặc điểm | |---|---| | Lambda với SQS trigger | tự co giãn, đơn giản nhất | | ECS/Fargate | xử lý lâu, kiểm soát nhiều hơn | | EC2 với ASG theo độ dài hàng đợi | linh hoạt nhất |

⚠ Co giãn theo độ dài hàng đợi:

aws autoscaling put-scaling-policy \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "TargetValue": 100,
    "CustomizedMetricSpecification": {
      "MetricName": "ApproximateNumberOfMessagesVisible",
      "Namespace": "AWS/SQS", "Statistic": "Average"}}'

Ba lưu ý về tính bất biến khi xử lý: | Lưu ý | Chi tiết | |---|---| | SQS Standard giao ít nhất một lần | | | Consumer phải chịu được xử lý trùng | | | Dùng khoá duy nhất và ConditionExpression | |

table.put_item(
    Item={'ma_bai_lam': ma, ...},
    ConditionExpression='attribute_not_exists(ma_bai_lam)')

Ba lưu ý về CloudFront cho ứng dụng di động: | Lưu ý | Chi tiết | |---|---| | Bật nén (gzip, brotli) | | | Đặt TTL dài cho tài nguyên bất biến | | | HTTP/3 giảm độ trễ trên mạng di động | |

Ba lưu ý về tối ưu ảnh: | Lưu ý | Chi tiết | |---|---| | WebP nhỏ hơn PNG/JPEG đáng kể | | | Phục vụ nhiều kích cỡ theo thiết bị | | | Lambda@Edge đổi cỡ ảnh theo yêu cầu | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy thử tải với đỉnh nộp bài dự kiến | | | Kiểm ThrottledRequests của DynamoDB | | | Đo thời gian tải trang từ nhiều khu vực | |

Và một lời khuyên: hãy thiết kế cách báo trạng thái cho người dùng khi chuyển sang xử lý bất đồng bộ. Trả về "đã nhận" ngay lập tức làm ứng dụng nhanh hơn hẳn, nhưng với một bài thi thì học sinh cần biết chắc bài đã được ghi nhận — nếu không, cảm giác "nhanh" sẽ đổi thành cảm giác "không chắc chắn".

Câu 294 Domain - Continuous Improvement for Existing Solutions

A company runs its travel and tours website on AWS. The application only supports HTTP at the moment. To improve their SEO ranking and provide more security for their customers, they decided to enable SSL on their website. The company would also like to ensure the separation of roles between the Development team and the Security team in handling the sensitive SSL certificate. The Development team can log in to EC2 Instances but they should not have access to the SSL certificate, which only the Security team has exclusive control of. Currently, they are using an Application Load Balancer which provides loads of incoming traffic to an Auto Scaling group of On-Demand EC2 instances.

Which of the following options should the solutions architect implement to satisfy the above requirements?

  1. A Create a new private S3 bucket and then upload the SSL certificate owned by the Security team. Configure the EC2 instance to have exclusive access to the certificate and block any access from the Development team.
  2. B Retrieve a read-only copy of the SSL certificate upon the boot of the EC2 instance from a CloudHSM, which is exclusively managed by the Security team.
  3. C Store the SSL certificate in IAM and authorize access only to the Security team using an IAM policy. Configure the Application Load Balancer to use the SSL certificate instead of the EC2 instances.
  4. D

    In the web server, set the file owner of the SSL certificate to the Security team and set the file permissions to 700 which will deny all access to the Development team.

Xem giải thích

Đáp án

**C — Lưu chứng chỉ SSL trong IAM, chỉ cho phép đội bảo mật truy cập bằng IAM policy, và cấu hình Application Load Balancer dùng chứng chỉ đó thay vì đặt trên EC2.

Vì sao đúng

Đề nêu hai yêu cầu, và cả hai đều được giải quyết bởi cùng một quyết định kiến trúc: | Yêu cầu | Cách đáp ứng | |---|---| | Bật HTTPS cho website | kết thúc TLS ở ALB | | Đội phát triển KHÔNG chạm được chứng chỉ | chứng chỉ không nằm trên EC2 |

⚠ Điểm mấu chốt: chứng chỉ không có mặt trên máy thì không ai đọc được:

Chứng chỉ nằm trên EC2
    → đội phát triển đăng nhập
      được vào EC2
        ↓
    Dù đặt quyền tệp thế nào,
      họ có thể `sudo`
    → hoặc đọc từ tiến trình
      web server
        ↓
    Chuyển lên ALB: khoá riêng
      KHÔNG BAO GIỜ rời khỏi
      dịch vụ AWS

⚠ Đây là lý do phương án D sai hoàn toàn:

D: đặt quyền tệp 700, chủ sở hữu
  là đội bảo mật
        ↓
    Ai có `sudo` trên máy đó đều
      đọc được
        ↓
    Và web server phải đọc được
      khoá để phục vụ HTTPS
    → nghĩa là khoá vẫn nằm trên
      đĩa của máy mà đội phát triển
      truy cập được

Gắn chứng chỉ vào ALB:

aws elbv2 create-listener \
  --load-balancer-arn <arn-alb> \
  --protocol HTTPS --port 443 \
  --certificates CertificateArn=<arn-chung-chi> \
  --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
  --default-actions Type=forward,TargetGroupArn=<arn-tg>

⚠ Và IAM policy tách bạch vai trò:

{"Version": "2012-10-17", "Statement": [{
  "Effect": "Allow",
  "Action": ["iam:UploadServerCertificate",
             "iam:UpdateServerCertificate",
             "iam:DeleteServerCertificate",
             "iam:GetServerCertificate"],
  "Resource": "*"}]}
Chỉ đội bảo mật có chính sách này
        ↓
    Đội phát triển không tải lên,
      không đọc, không xoá được
        ↓
    Nhưng vẫn triển khai ứng dụng
      bình thường

⚠ Và kết thúc TLS ở ALB có lợi ích phụ về hiệu năng:

Bắt tay TLS tốn CPU
        ↓
    Làm ở ALB → EC2 không tốn CPU
      cho việc mã hoá
    → thêm công suất cho ứng dụng
        ↓
    Và ALB tự co giãn phần này

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

A: lưu chứng chỉ trong bucket S3
  riêng tư, EC2 đọc từ đó
        ↓
    Chứng chỉ VẪN được tải xuống
      máy EC2
    → đội phát triển vẫn đọc được
        ↓
    Chỉ đổi chỗ cất, không đổi
      ai đọc được

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

B: lấy "bản sao chỉ đọc" của chứng
  chỉ từ CloudHSM lúc khởi động
        ↓
    CloudHSM sinh ra để khoá riêng
      KHÔNG BAO GIỜ rời khỏi thiết bị
        ↓
    "Lấy bản sao ra" là làm ngược
      mục đích của HSM

⚠ CloudHSM dùng đúng cách thì rất khác:

Khoá riêng nằm trong HSM
        ↓
    Web server gửi yêu cầu KÝ tới HSM
    → HSM ký và trả kết quả
        ↓
    Khoá không bao giờ ra ngoài
    → gọi là SSL offloading với HSM

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

⚠ Kho chứng chỉ IAM là cơ chế cũ; ACM là cách làm hiện nay.

Tiêu chí ACM Kho chứng chỉ IAM
Cấp chứng chỉ công cộng miễn phí CÓ không
Tự gia hạn CÓ không
Xem trong console CÓ chỉ CLI/API
Khoá riêng xuất ra được KHÔNG không
Trạng thái hiện hành legacy
aws acm request-certificate --domain-name du-lich.vn \
  --subject-alternative-names "*.du-lich.vn" \
  --validation-method DNS
ACM cấp miễn phí và TỰ GIA HẠN
        ↓
    Không có khoảnh khắc nào chứng
      chỉ hết hạn vì ai đó quên
        ↓
    Và tách vai trò làm được bằng
      `acm:*` trong IAM policy

Chính sách tách vai trò với ACM:

{"Effect": "Deny",
 "Action": ["acm:ImportCertificate", "acm:DeleteCertificate",
            "acm:RequestCertificate"],
 "Resource": "*"}

AWS chỉ còn khuyến nghị kho chứng chỉ IAM cho những Region mà ACM chưa có mặt. Câu hỏi này viết trước khi ACM trở nên phổ biến; với kiến thức hiện nay, đáp án đúng là "lưu trong ACM" chứ không phải "lưu trong IAM".

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

  • **A. Tạo bucket S3 riêng tư chứa chứng chỉ, cấu hình EC2 truy cập độc quyền và chặn đội phát triển — đây là phương án gần nhất và bucket riêng tư có kiểm soát truy cập tốt, nhưng chứng chỉ vẫn được tải xuống máy EC2 mà đội phát triển đăng nhập được, nên việc tách vai trò không thành.
  • **B. Lấy bản sao chỉ đọc của chứng chỉ từ CloudHSM lúc máy khởi động — làm ngược mục đích của HSM; khoá riêng trong HSM sinh ra để không bao giờ rời khỏi thiết bị.
  • **D. Đặt chủ sở hữu tệp là đội bảo mật và quyền 700 — ai có sudo trên máy đều đọc được, và web server bắt buộc phải đọc được khoá đó.

Ghi nhớ

⚠ Bốn nơi giữ bí mật trên AWS — bảng phải thuộc: | Nơi | Hợp với | |---|---| | ACM | chứng chỉ TLS cho ALB, CloudFront, API Gateway | | Secrets Manager | mật khẩu CSDL, có tự xoay vòng | | Parameter Store | cấu hình và bí mật đơn giản, rẻ hơn | | CloudHSM | khoá phải nằm trong HSM chuyên dụng (FIPS 140-2 mức 3) |

Từ khoá nhận diện:

"developers must not access the certificate" → kết thúc TLS ở ALB, không đặt trên EC2 "free auto-renewing certificate" → ACM "key must never leave hardware" → CloudHSM "rotate database password automatically" → Secrets Manager "single-tenant HSM, FIPS 140-2 Level 3" → CloudHSM

Ba lưu ý về ACM: | Lưu ý | Chi tiết | |---|---| | Chứng chỉ ACM cấp KHÔNG xuất khoá riêng ra được | | | Chỉ dùng với dịch vụ AWS tích hợp | | | Cần trên EC2 thì dùng ACM Private CA | |

⚠ Điểm thứ hai là giới hạn quan trọng:

ACM cấp chứng chỉ công cộng
    → chỉ gắn được vào ALB, NLB,
      CloudFront, API Gateway
        ↓
    Muốn đặt trên EC2 hoặc máy tại
      chỗ
    → phải mua từ CA khác, hoặc
      dùng ACM Private CA

Ba lưu ý về ràng buộc Region: | Dịch vụ | Chứng chỉ ở Region nào | |---|---| | CloudFront | us-east-1 | | ALB/NLB | cùng Region với LB | | API Gateway regional | cùng Region |

Ba lưu ý về chính sách bảo mật TLS: | Lưu ý | Chi tiết | |---|---| | Chọn ELBSecurityPolicy-TLS13-* cho mới nhất | | | Chính sách cũ hỗ trợ client cũ nhưng yếu hơn | | | Kiểm tra bằng SSL Labs sau khi cấu hình | |

Ba lưu ý về tách vai trò: | Lưu ý | Chi tiết | |---|---| | Dùng IAM policy, không dùng quyền tệp | | | Permissions boundary chặn leo thang quyền | | | SCP chặn ở cấp tổ chức | |

⚠ Quyền tệp không phải cơ chế tách vai trò trên đám mây:

Ai có `sudo` là có tất cả
        ↓
    Và ai sửa được user data hoặc
      launch template cũng có tất cả
        ↓
    Tách vai trò phải làm ở tầng
      IAM, không phải tầng hệ điều hành

Ba lưu ý về gia hạn: | Lưu ý | Chi tiết | |---|---| | ACM tự gia hạn nếu xác thực bằng DNS | | | Chứng chỉ nhập vào phải tự gia hạn | | | Đặt cảnh báo DaysToExpiry trong CloudWatch | |

aws cloudwatch put-metric-alarm \
  --alarm-name chung-chi-sap-het-han \
  --namespace AWS/CertificateManager \
  --metric-name DaysToExpiry --statistic Minimum \
  --period 86400 --evaluation-periods 1 \
  --threshold 30 --comparison-operator LessThanThreshold

Ba lưu ý về mã hoá đầu cuối: | Lưu ý | Chi tiết | |---|---| | ALB → EC2 cũng mã hoá được | | | Dùng chứng chỉ tự ký ở chặng sau ALB được | | | ALB không xác thực chứng chỉ của target | |

⚠ Điểm cuối khác hẳn CloudFront:

ALB chấp nhận chứng chỉ tự ký
  ở target
        ↓
    CloudFront BẮT BUỘC origin dùng
      chứng chỉ CA công cộng

Ba việc kiểm chứng: | Việc | Cách | |---|---| | openssl s_client -connect ten-mien:443 xem chuỗi | | | Đăng nhập EC2 tìm tệp .key — không được có | | | Thử tài khoản đội phát triển gọi iam:GetServerCertificate | |

Và một lời khuyên: hãy dùng ACM với xác thực DNS thay vì tự quản chứng chỉ. Việc tách vai trò trong câu hỏi này chỉ là một nửa vấn đề — nửa còn lại là chứng chỉ tự quản luôn có ngày hết hạn, và ngày đó luôn rơi vào lúc người biết cách gia hạn đang đi vắng.

Câu 295 Domain - Continuous Improvement for Existing Solutions

A company hosts a serverless application on AWS using Amazon API Gateway and AWS Lambda with Amazon DynamoDB as the backend database. The application has a feature that allows users to create posts and reply to comments based on different topics. The API model currently uses the following methods:

- GET /posts/[postid] – used to get details about the post

- GET /users/[userid] – used to get details about a user

- GET /comments/[commentid] – used to get details of a comment

The application does not use API keys for request authorization. To increase user engagement on the web app, the company wants to reduce comment latency by making the comments appear in real-time.

Which of the following solution should be implemented to meet the requirements and improve user experience?

  1. A

    Leverage AWS AppSync by building GraphQL APIs and using Websockets to deliver comments in real-time.

  2. B

    Lower the API response time of the Lambda functions by increasing the concurrency limit. This allows functions to run in parallel to deliver the comments in real-time.

  3. C

    Update the application code to call the GET /comments/[commentid] API every 3 seconds to show comments in real-time without sacrificing performance.

  4. D

    Create a distribution on Amazon CloudFront and use edge-optimized APIs. Cache API responses in CloudFront to improve comment latency.

Xem giải thích

Đáp án

**A — Dùng AWS AppSync dựng API GraphQL và dùng WebSocket để đẩy bình luận theo thời gian thực.

Vì sao đúng

Đề nêu một yêu cầu mà mô hình REST hiện tại không đáp ứng được:

Bình luận phải xuất hiện THỜI GIAN THỰC
        ↓
    REST là mô hình client HỎI,
      server TRẢ LỜI
        ↓
    Server không có cách nào chủ
      động ĐẨY dữ liệu về client

⚠ Điểm mấu chốt: cần kết nối hai chiều, và đó là WebSocket: | Giao thức | Ai bắt đầu | |---|---| | HTTP/REST | chỉ client | | WebSocket | cả hai bên, kết nối giữ mở |

⚠ Và AppSync có subscription dựng sẵn trên WebSocket:

type Subscription {
  binhLuanMoi(maBaiViet: ID!): BinhLuan
    @aws_subscribe(mutations: ["taoBinhLuan"])
}
Một chỉ thị `@aws_subscribe`
        ↓
    AppSync tự quản lý kết nối
      WebSocket, tự đẩy tới mọi
      client đang theo dõi bài
      viết đó
        ↓
    Không phải viết máy chủ
      WebSocket nào

Schema đầy đủ:

type BinhLuan {
  maBinhLuan: ID!
  maBaiViet: ID!
  maNguoiDung: ID!
  noiDung: String!
  thoiDiem: AWSDateTime!
}

type Mutation { taoBinhLuan(maBaiViet: ID!, noiDung: String!): BinhLuan }
type Query { layBinhLuan(maBaiViet: ID!): [BinhLuan] }

⚠ Và GraphQL giải quyết luôn vấn đề gọi nhiều lần:

API hiện tại có ba endpoint riêng:
  /posts/{id}, /users/{id},
  /comments/{id}
        ↓
    Hiển thị một bài viết với
      bình luận và tên người viết
    → phải gọi nhiều lần
        ↓
    GraphQL: MỘT truy vấn lấy đủ
query {
  baiViet(maBaiViet: "BV-1") {
    tieuDe
    binhLuan { noiDung nguoiDung { ten anhDaiDien } }
  }
}

⚠ Và vì sao phương án C (hỏi lại mỗi 3 giây) sai:

1.000 người đang xem một bài
        ↓
    Mỗi người gọi 20 lần/phút
    → 20.000 lời gọi/phút
        ↓
    Phần lớn trả về "không có gì mới"
    → tốn tiền API Gateway, tốn
      Lambda, tốn RCU DynamoDB
        ↓
    Và vẫn trễ tới 3 giây

⚠ Đây là khác biệt căn bản giữa hỏi vòng và đẩy: | Tiêu chí | Hỏi vòng mỗi 3s | WebSocket | |---|---|---| | Độ trễ | tới 3 giây | gần như tức thì | | Lời gọi khi im lặng | vẫn đầy đủ | bằng 0 | | Chi phí | theo số client × tần suất | theo kết nối và tin nhắn thật |

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

Tăng giới hạn đồng thời của Lambda
        ↓
    Giúp xử lý nhiều yêu cầu hơn
    → không tạo ra khả năng ĐẨY
        ↓
    Client vẫn phải hỏi mới biết
      có bình luận mới

⚠ Và vì sao phương án D sai — cache làm dữ liệu CŨ hơn:

CloudFront cache phản hồi API
        ↓
    Bình luận mới đăng vẫn không
      hiện cho tới khi cache hết hạn
        ↓
    Đây là làm ngược yêu cầu

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Bình luận hiện gần như tức thì | | | Không tốn lời gọi khi không có gì mới | | | Một truy vấn lấy đủ dữ liệu liên quan | |

⚠ Và API Gateway WebSocket API là lựa chọn khác:

Muốn giữ REST cho phần còn lại
    → thêm một WebSocket API riêng
        ↓
    Nhưng phải tự quản danh sách
      connectionId, tự phát tán
    → AppSync làm sẵn việc đó
# Với WebSocket API, phải tự đẩy:
apigw = boto3.client('apigatewaymanagementapi',
                     endpoint_url=URL_QUAN_LY)
for ma_ket_noi in danh_sach_dang_xem:
    apigw.post_to_connection(
        ConnectionId=ma_ket_noi,
        Data=json.dumps(binh_luan).encode())

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

  • **C. Gọi GET /comments/[commentid] mỗi 3 giây để hiển thị bình luận — đây là phương án gần nhất và thật sự làm bình luận cập nhật thường xuyên, nhưng nó tạo ra lượng lời gọi rất lớn mà phần lớn không có dữ liệu mới, và vẫn trễ tới 3 giây.
  • **B. Tăng giới hạn đồng thời của Lambda để hàm chạy song song — giúp thông lượng nhưng không tạo ra cơ chế đẩy dữ liệu về client.
  • **D. Dựng CloudFront và cache phản hồi API — cache làm dữ liệu cũ đi, ngược hẳn với yêu cầu thời gian thực.

Ghi nhớ

⚠ Bốn cách đẩy dữ liệu về client — bảng phải thuộc: | Cách | Đặc điểm | |---|---| | AppSync subscription | GraphQL, quản lý sẵn, dễ nhất | | API Gateway WebSocket | tự quản connectionId | | IoT Core MQTT over WebSocket | rất nhiều thiết bị, chủ đề phân cấp | | Hỏi vòng (polling) | đơn giản nhất, tốn kém nhất |

Từ khoá nhận diện:

"real-time updates to clients" → WebSocket / AppSync subscription "reduce number of API calls, over-fetching" → GraphQL "bidirectional, full-duplex" → WebSocket "fan-out to many mobile devices" → AppSync hoặc IoT Core

Ba lưu ý về AppSync: | Lưu ý | Chi tiết | |---|---| | Resolver nối thẳng tới DynamoDB, Lambda, RDS, OpenSearch | | | Xác thực: API key, Cognito, IAM, OIDC, Lambda | | | Có cache máy chủ tuỳ chọn | |

⚠ Resolver trực tiếp bỏ được cả Lambda:

{"version": "2018-05-29",
 "operation": "Query",
 "query": {"expression": "maBaiViet = :bv",
           "expressionValues": {":bv": {"S": "$ctx.args.maBaiViet"}}}}
AppSync gọi thẳng DynamoDB
    → không có Lambda ở giữa
    → ít độ trễ hơn, rẻ hơn

Ba lưu ý về subscription: | Lưu ý | Chi tiết | |---|---| | Chỉ kích hoạt bởi mutation qua AppSync | | | Lọc được theo tham số | | | Ghi thẳng vào DynamoDB không kích hoạt subscription | |

⚠ Điểm cuối là bẫy thật:

Một dịch vụ khác ghi bình luận
  thẳng vào DynamoDB
        ↓
    AppSync không biết
    → subscription không bắn
        ↓
    Phải cho mọi đường ghi đi qua
      mutation của AppSync

Ba lưu ý về giới hạn: | Giới hạn | Giá trị | |---|---| | Kết nối WebSocket mỗi API | hàng trăm nghìn | | Kích thước payload subscription | 240 KB | | Thời gian kết nối tối đa | 24 giờ |

Ba lưu ý về REST và GraphQL: | Tiêu chí | REST | GraphQL | |---|---|---| | Số endpoint | nhiều | một | | Lấy thừa dữ liệu | hay xảy ra | client khai đúng cái cần | | Cache HTTP | dễ | khó hơn | | Thời gian thực | không có sẵn | subscription |

Ba lưu ý về chi phí: | Thành phần | Cách tính | |---|---| | Truy vấn và mutation | theo triệu thao tác | | Cập nhật thời gian thực | theo triệu tin nhắn | | Thời lượng kết nối | theo triệu phút |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Mở hai trình duyệt, đăng bình luận ở một bên | | | Đo độ trễ từ lúc đăng tới lúc hiện | | | Kiểm số lời gọi API giảm bao nhiêu | |

Và một lời khuyên: hãy cho mọi đường ghi bình luận đi qua mutation của AppSync. Subscription chỉ bắn khi dữ liệu thay đổi qua chính AppSync — một tiến trình nền ghi thẳng vào DynamoDB sẽ hoạt động hoàn hảo về mặt lưu trữ và hoàn toàn im lặng về mặt thông báo.

Câu 296 Domain - Continuous Improvement for Existing Solutions

A company wants to release a weather forecasting app for mobile users. The application servers generate a weather forecast every 15 minutes, and each forecast update overwrites the older forecast data. Each weather forecast outputs approximately 1 billion unique data points, where each point is about 20 bytes in size. This results in about 20GB of data for each forecast. Approximately 1,500 global users access the forecast data concurrently every second, and this traffic can spike up to 10 times more during weather events. The company wants users to have a good experience when using the weather forecast application so it requires that each user query must be processed in less than two seconds.

Which of the following solutions will meet the required application request rate and response time?

  1. A

    Create an Amazon OpenSearch cluster to store the weather forecast data points. Write AWS Lambda functions to query the ES cluster. Create an Amazon CloudFront distribution and point the origin to an Amazon API Gateway endpoint that invokes the Lambda functions. Configure a cache-control timeout of 15 minutes in the API caching section of the API Gateway stage.

  2. B

    Create an Amazon OpenSearch cluster to store the weather forecast data points. Write AWS Lambda functions to query the ES cluster. Create an Amazon CloudFront distribution and point the origin to an Amazon API Gateway endpoint that invokes the Lambda functions. Write an Amazon Lambda@Edge function to cache the data points on edge locations for a 15-minute duration.

  3. C

    Use an Amazon EFS volume to store the weather forecast data points. Mount this EFS volume on a fleet of Auto Scaling Amazon EC2 instances behind an Elastic Load Balancer. Create an Amazon CloudFront distribution and point the origin to the ELB. Configure a 15-minute cache-control timeout for the CloudFront distribution.

  4. D

    Create an Amazon S3 bucket to store the weather forecast data points as individual objects. Create a fleet of Auto Scaling Amazon EC2 instances behind an Elastic Load Balancer to query the objects on the S3 bucket. Create an Amazon CloudFront distribution and point the origin to the ELB. Configure a 15-minute cache-control timeout for the CloudFront distribution.

Xem giải thích

Đáp án

**C — Lưu dữ liệu dự báo trên một volume Amazon EFS, mount vào đội EC2 có Auto Scaling đứng sau load balancer; dựng CloudFront với origin là ELB và đặt cache-control 15 phút.

Vì sao đúng

Đề cho những con số quyết định:

1 tỷ điểm dữ liệu, mỗi điểm 20 byte
    → 20 GB mỗi lần dự báo
        ↓
    Cập nhật mỗi 15 phút, GHI ĐÈ
      dữ liệu cũ
        ↓
    1.500 truy vấn/giây, đỉnh 15.000
    → mỗi truy vấn dưới 2 giây

⚠ Điểm mấu chốt: cache 15 phút khớp chính xác chu kỳ cập nhật:

Dữ liệu chỉ đổi mỗi 15 phút
        ↓
    Cache 15 phút ở CloudFront
    → phần lớn truy vấn không bao
      giờ tới origin
        ↓
    15.000 truy vấn/giây chủ yếu
      do điểm biên phục vụ

⚠ Và đây là lý do phương án D (S3) thất bại:

1 tỷ điểm dữ liệu lưu thành
  1 tỷ OBJECT riêng
        ↓
    Mỗi lần dự báo phải ghi 1 tỷ
      object
    → và làm lại mỗi 15 phút
        ↓
    Chi phí PUT: 1 tỷ × 96 lần/ngày
    → hoàn toàn không khả thi
Và độ trễ mỗi lời gọi GetObject
  là hàng chục mili giây
    → EFS đọc nhanh hơn nhiều cho
      truy cập ngẫu nhiên nhỏ

⚠ Và EFS hợp vì nhiều instance cùng đọc một tập dữ liệu:

Đội EC2 co giãn theo tải
        ↓
    Máy mới thêm vào phải có ngay
      dữ liệu
        ↓
    EBS: gắn được vào một máy
      (trừ Multi-Attach io1/io2)
    → EFS: mọi máy mount cùng lúc

Mount EFS:

sudo mount -t efs -o tls,iam \
  fs-0abc123:/ /du-lieu-du-bao

⚠ Và ghi đè 20 GB mỗi 15 phút cần chú ý chế độ thông lượng: | Chế độ | Đặc điểm | |---|---| | Bursting | thông lượng theo dung lượng lưu trữ | | Elastic | tự co giãn, trả theo lượng đọc/ghi | | Provisioned | cấp cố định, không phụ thuộc dung lượng |

20 GB dữ liệu ở chế độ Bursting
    → thông lượng nền rất thấp
      (50 KB/s cho mỗi GB)
        ↓
    Ghi 20 GB trong vài phút
    → cạn tín dụng bùng nổ
        ↓
    Phải dùng Elastic hoặc
      Provisioned

⚠ Và vì sao hai phương án OpenSearch (A, B) không hợp:

Nạp 1 tỷ tài liệu vào OpenSearch
  mỗi 15 phút
        ↓
    Đánh chỉ mục là việc rất nặng
    → cụm phải rất lớn
        ↓
    Và dữ liệu bị GHI ĐÈ hoàn toàn
    → xây chỉ mục tìm kiếm cho dữ
      liệu tra theo khoá là quá thừa

⚠ Và phương án B còn sai về Lambda@Edge:

B nói dùng Lambda@Edge để "cache
  điểm dữ liệu ở điểm biên"
        ↓
    Lambda@Edge là mã chạy ở biên,
      không phải kho cache
        ↓
    CloudFront tự cache — đó là
      việc của nó

Đặt cache-control:

Cache-Control: public, max-age=900
aws cloudfront create-distribution --distribution-config '{
  "DefaultCacheBehavior": {
    "TargetOriginId": "elb-du-bao",
    "CachePolicyId": "<id-policy-900s>",
    "ViewerProtocolPolicy": "redirect-to-https"}}'

⚠ Và độ trễ dưới 2 giây gần như được bảo đảm nhờ cache:

Cache hit: phục vụ từ điểm biên
  gần người dùng
    → hàng chục mili giây
        ↓
    Cache miss: qua ELB tới EC2
      đọc EFS
    → vài trăm mili giây
        ↓
    Cả hai đều dưới 2 giây

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Cache hấp thụ gần hết lưu lượng | | | Mọi instance thấy cùng dữ liệu mới nhất | | | Không có chi phí PUT khổng lồ như S3 | |

⚠ Và cần chú ý tới việc ghi đè trong lúc đang phục vụ:

Ghi đè trực tiếp lên tệp đang đọc
        ↓
    Người dùng có thể đọc dữ liệu
      dở dang
        ↓
    Ghi vào thư mục mới rồi đổi
      symlink
    → đổi nguyên tử

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

⚠ Cả bốn phương án đều dùng CloudFront với TTL 15 phút — nên câu hỏi thật ra chỉ hỏi về tầng lưu trữ.

Và với một tập dữ liệu tra cứu theo khoá, cỡ 20 GB, ghi đè hoàn toàn mỗi 15 phút, có những lựa chọn hợp hơn cả EFS: | Lựa chọn | Vì sao đáng cân nhắc | |---|---| | DynamoDB | tra theo khoá, mili giây, co giãn sẵn | | ElastiCache | 20 GB vừa trong bộ nhớ, micro giây | | Tệp cục bộ trên mỗi instance | 20 GB chép vào máy khi khởi động, đọc từ đĩa cục bộ |

Lựa chọn cuối rất đáng chú ý:
  20 GB chép vào instance store
        ↓
    Không có tầng chia sẻ nào để
      trở thành nút thắt
    → và nhanh nhất
        ↓
    Đổi lại: mỗi máy mới phải chép
      20 GB khi khởi động

Đề không cho biết cách truy vấn dữ liệu (tra theo toạ độ? theo vùng?), mà đó chính là thứ quyết định tầng lưu trữ nào hợp.

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

  • **D. Lưu từng điểm dữ liệu thành object S3 riêng, đội EC2 truy vấn S3, CloudFront cache 15 phút — đây là phương án gần nhất và kiến trúc cache hoàn toàn giống đáp án, nhưng ghi 1 tỷ object mỗi 15 phút là chi phí và thời gian không khả thi.
  • **A. Dựng cụm OpenSearch, Lambda truy vấn, API Gateway cache 15 phút — nạp 1 tỷ tài liệu mỗi 15 phút là khối lượng đánh chỉ mục rất lớn cho một tập dữ liệu chỉ tra theo khoá.
  • **B. Như A nhưng dùng Lambda@Edge để cache — Lambda@Edge là nơi chạy mã, không phải kho cache; CloudFront đã tự cache.

Ghi nhớ

⚠ Bốn kho lưu trữ chia sẻ trên AWS — bảng phải thuộc: | Kho | Giao thức | Nhiều máy cùng ghi | |---|---|---| | EFS | NFS | CÓ | | FSx for Lustre | Lustre, POSIX | CÓ, hiệu năng rất cao | | FSx for Windows | SMB | CÓ | | EBS Multi-Attach | khối | CÓ, nhưng cần hệ tệp cụm |

Từ khoá nhận diện:

"shared POSIX file system" → EFS "HPC, machine learning, highest throughput" → FSx for Lustre "Windows SMB shares" → FSx for Windows "data changes every N minutes" → cache TTL bằng N "billions of small items" → KHÔNG dùng object riêng trong S3

Ba lưu ý về EFS: | Lưu ý | Chi tiết | |---|---| | Chế độ Elastic tự co giãn thông lượng | | | Lớp IA rẻ hơn cho tệp ít đọc | | | Mount target ở mỗi AZ | |

⚠ Chế độ Bursting là bẫy hiệu năng:

Thông lượng nền = 50 KB/s mỗi GB
        ↓
    20 GB → 1 MB/s nền
        ↓
    Tín dụng bùng nổ cho phép
      100 MB/s một lúc
    → hết tín dụng thì về 1 MB/s

Ba lưu ý về CloudFront cache: | Lưu ý | Chi tiết | |---|---| | TTL do Cache-Control của origin quyết định | | | Cache policy có thể ghi đè | | | Regional edge cache là tầng thứ hai | |

Ba lưu ý về chi phí S3: | Khoản | Ghi chú | |---|---| | PUT | ~0,005 USD/1.000 lời gọi | | GET | ~0,0004 USD/1.000 lời gọi | | Lưu trữ | theo GB-tháng |

⚠ Với 1 tỷ object, phí PUT một lần đã là 5.000 USD:

1.000.000.000 / 1.000 × 0,005
    = 5.000 USD
        ↓
    Nhân 96 lần mỗi ngày
    → con số vô lý

Ba lưu ý về co giãn đội EC2: | Lưu ý | Chi tiết | |---|---| | Warm pool giảm thời gian khởi động | | | Đặt min-size chịu được đỉnh nền | | | Health check kiểu ELB | |

Ba lưu ý về cập nhật dữ liệu nguyên tử: | Cách | Chi tiết | |---|---| | Ghi thư mục mới rồi đổi symlink | | | Ghi tệp tạm rồi rename | | | Đánh phiên bản trong đường dẫn | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy thử tải ở 15.000 truy vấn/giây | | | Đo tỷ lệ cache hit của CloudFront | | | Kiểm BurstCreditBalance của EFS | |

Và một lời khuyên: hãy đo tỷ lệ cache hit trước khi tin vào con số công suất origin. Cả kiến trúc này dựa vào việc CloudFront hấp thụ gần hết lưu lượng — nếu URL có tham số truy vấn khác nhau cho từng người dùng thì cache phân mảnh và toàn bộ 15.000 truy vấn/giây sẽ đổ thẳng vào origin.

Câu 297 Chọn nhiều đáp án Domain - Continuous Improvement for Existing Solutions

An adventure company runs a PostgreSQL database that is used to store events from its monitoring application on its on-premises data center. The database is unable to scale enough to handle frequent write events that need to be ingested into the database. The management has tasked the solutions architect to create a hybrid solution that will utilize the existing company VPN connection to AWS. Additional requirements are as follows:

  • Leverage AWS-managed services to minimize operation overhead

  • Create a buffer that automatically scales to accommodate the events that need to be ingested

  • A visualization tool to observe near real-time events and supports creating dashboards.

  • Has support for dynamic schemas and semi-structured JSON data.

Which of the following options should the solutions architect implement to meet the company requirements? (Select TWO.)

  1. A

    Create an Amazon OpenSearch Service domain to reliably ingest the events. Leverage the OpenSearch Dashboards tool to create near-real-time dashboards and visualizations.

  2. B

    Levering Amazon Neptune DB auto-scaling feature to reliably ingest the events. Use Neptune DB as the DB source for Amazon QuickSight to create near-real-time dashboards and visualizations.

  3. C

    Provision an Amazon Aurora PostgreSQL DB cluster to reliably ingest the events. Use this DB as the source for Amazon QuickSight to create near-real-time dashboards and visualizations.

  4. D

    Ingest the events using Amazon Data Firehose. Write a Lambda function to process and transform the buffered events.

  5. E

    Use Amazon Kinesis Data Stream to reliably ingest the events. Write a Lambda function to process and transform the buffered events.

Xem giải thích

Đáp án

**A và D — Dựng một domain Amazon OpenSearch Service để nhận sự kiện và dùng OpenSearch Dashboards vẽ bảng điều khiển gần thời gian thực; đồng thời nhận sự kiện qua Amazon Data Firehose và viết một hàm Lambda xử lý, biến đổi dữ liệu đã đệm.

Vì sao đúng

Đề liệt kê bốn yêu cầu, và cặp Firehose + OpenSearch phủ đủ cả bốn: | Yêu cầu | Thành phần | |---|---| | Dịch vụ AWS quản lý, ít vận hành | cả hai đều là dịch vụ quản lý | | Bộ đệm tự co giãn | Firehose | | Công cụ trực quan gần thời gian thực | OpenSearch Dashboards | | Schema động, dữ liệu JSON bán cấu trúc | OpenSearch |

⚠ Điểm mấu chốt: "schema động" loại ngay mọi CSDL quan hệ:

PostgreSQL, Aurora: schema CỐ ĐỊNH
    → thêm trường mới phải
      `ALTER TABLE`
        ↓
    OpenSearch: dynamic mapping
    → tài liệu JSON có trường mới
      thì tự thêm vào mapping

Đây là lý do phương án C (Aurora PostgreSQL) sai — nó chỉ chuyển vấn đề hiện tại lên đám mây.

⚠ Và Firehose là bộ đệm "tự co giãn" theo đúng nghĩa: | Tiêu chí | Firehose | Kinesis Data Streams | |---|---|---| | Quản lý shard | KHÔNG có shard | phải cấp hoặc dùng on-demand | | Tự co giãn | hoàn toàn | on-demand thì có | | Biến đổi bằng Lambda | tích hợp sẵn | phải tự viết consumer | | Ghi vào OpenSearch | tích hợp sẵn | phải tự viết |

Đề nói "tự động co giãn" và
  "ít vận hành nhất"
        ↓
    Firehose không có gì để chỉnh
    → KDS phải theo dõi shard,
      xử lý resharding

Đây là lý do phương án E (Kinesis Data Streams) thua.

Tạo luồng phân phối:

aws firehose create-delivery-stream \
  --delivery-stream-name su-kien-giam-sat \
  --amazonopensearchservice-destination-configuration '{
    "RoleARN": "arn:aws:iam::111122223333:role/Firehose",
    "DomainARN": "arn:aws:es:ap-southeast-1:111122223333:domain/giam-sat",
    "IndexName": "su-kien",
    "IndexRotationPeriod": "OneDay",
    "BufferingHints": {"IntervalInSeconds": 60, "SizeInMBs": 5},
    "S3BackupMode": "AllDocuments",
    "ProcessingConfiguration": {
      "Enabled": true,
      "Processors": [{"Type": "Lambda", "Parameters": [
        {"ParameterName": "LambdaArn", "ParameterValue": "<arn-lambda>"}]}]}}'

⚠ IndexRotationPeriod là chi tiết quan trọng cho dữ liệu chuỗi thời gian:

Một chỉ mục khổng lồ
    → xoá dữ liệu cũ phải xoá
      từng tài liệu
        ↓
    Xoay chỉ mục theo ngày
      (su-kien-2026.09.01)
    → xoá cả chỉ mục cũ, rất rẻ
        ↓
    Index State Management tự làm
      việc đó

Hàm biến đổi cho Firehose:

import base64, json

def xu_ly(event, context):
    ket_qua = []
    for ban_ghi in event['records']:
        dl = json.loads(base64.b64decode(ban_ghi['data']))
        dl['thoi_diem_iso'] = dl.pop('ts')
        dl['muc_do'] = dl.get('muc_do', 'thong-tin').lower()
        ket_qua.append({
            'recordId': ban_ghi['recordId'],
            'result': 'Ok',
            'data': base64.b64encode(
                (json.dumps(dl) + '\n').encode()).decode()})
    return {'records': ket_qua}

⚠ Hàm biến đổi phải trả về ĐÚNG mọi recordId nhận vào:

Thiếu một recordId
    → Firehose coi lô đó lỗi
        ↓
    Ba giá trị `result`:
      Ok — giữ lại
      Dropped — bỏ đi có chủ đích
      ProcessingFailed — chuyển
        sang S3 lỗi

⚠ Và S3BackupMode là lưới an toàn nên bật:

OpenSearch gặp sự cố kéo dài
    → Firehose thử lại rồi bỏ cuộc
        ↓
    Có backup S3: dữ liệu vẫn còn
    → nạp lại được sau
        ↓
    Không có: MẤT

⚠ Và vì sao phương án B (Neptune) sai hoàn toàn:

Neptune là CSDL ĐỒ THỊ
    → cho quan hệ giữa các thực thể
        ↓
    Sự kiện giám sát là chuỗi thời
      gian, không phải đồ thị
        ↓
    Và Neptune không phải nguồn
      dữ liệu của QuickSight

⚠ Và OpenSearch Dashboards khác QuickSight ở chỗ nào: | Tiêu chí | OpenSearch Dashboards | QuickSight | |---|---|---| | Nguồn dữ liệu | chỉ OpenSearch | nhiều nguồn | | Độ trễ | gần thời gian thực | theo lịch làm mới (SPICE) | | Hợp với | log, sự kiện, giám sát | báo cáo nghiệp vụ | | Chi phí thêm | đi kèm domain | theo người dùng |

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không có shard hay máy chủ nào phải quản | | | Schema tự thích ứng với dữ liệu mới | | | Bảng điều khiển đi kèm, không mua thêm | |

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

⚠ Câu này gần như trùng với một câu khác trong cùng lô (mã #10639): cũng PostgreSQL tại chỗ, cũng cần bộ đệm tự co giãn, cũng JSON bán cấu trúc với schema động, cũng cần bảng điều khiển gần thời gian thực. Đáp án của cả hai đều là Firehose + Lambda + OpenSearch.

Khác biệt duy nhất: câu này hỏi chọn hai phương án, câu kia hỏi chọn một phương án gộp cả kiến trúc. Cùng một kiến thức được kiểm tra hai lần trong cùng một đợt.

⚠ Và Firehose có độ trễ tối thiểu — "gần thời gian thực" là đúng, "thời gian thực" thì không:

BufferingHints tối thiểu 60 giây
  cho đích OpenSearch
        ↓
    Cần dưới một giây
    → phải đọc thẳng từ Kinesis
      Data Streams

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

  • **E. Dùng Kinesis Data Streams để nhận sự kiện và Lambda xử lý — đây là phương án gần nhất và thật sự là bộ đệm co giãn được, nhưng phải tự quản shard (hoặc chọn on-demand), tự viết consumer ghi vào đích, nhiều việc vận hành hơn Firehose.
  • **C. Dựng cụm Aurora PostgreSQL để nhận sự kiện, dùng làm nguồn cho QuickSight — schema cố định, không hợp với JSON có schema động; và chỉ chuyển đúng vấn đề hiện tại lên đám mây.
  • **B. Dùng Neptune với tính năng tự co giãn — Neptune là CSDL đồ thị, không hợp với sự kiện chuỗi thời gian.

Ghi nhớ

⚠ Bốn dịch vụ nhận dữ liệu luồng — bảng phải thuộc: | Dịch vụ | Vận hành | Độ trễ | |---|---|---| | Data Firehose | thấp nhất | tối thiểu 60 giây | | Kinesis Data Streams | quản shard | dưới 1 giây | | MSK (Kafka) | cao nhất | rất thấp | | SQS | thấp | thấp, nhưng không phát lại |

Từ khoá nhận diện:

"dynamic schema, semi-structured JSON" → OpenSearch hoặc DynamoDB "auto-scaling buffer, least ops" → Firehose "near real-time dashboards on log data" → OpenSearch Dashboards "business reports from many sources" → QuickSight "graph relationships" → Neptune

Ba lưu ý về OpenSearch Service: | Lưu ý | Chi tiết | |---|---| | Đặt trong VPC hoặc public endpoint | | | Dedicated master node cho cụm sản xuất | | | UltraWarm và Cold Storage cho dữ liệu cũ | |

⚠ Dedicated master node là bắt buộc cho sản xuất:

Không có master riêng
    → node dữ liệu vừa lưu vừa
      điều phối cụm
        ↓
    Node nặng tải → mất liên lạc
    → cụm chia đôi (split brain)
        ↓
    Ba master node ở ba AZ

Ba lưu ý về UltraWarm: | Lưu ý | Chi tiết | |---|---| | Lưu trên S3, cache cục bộ | | | Rẻ hơn nhiều cho dữ liệu ít truy vấn | | | Chỉ đọc, không ghi thêm được | |

Ba lưu ý về Firehose: | Lưu ý | Chi tiết | |---|---| | Đích: S3, Redshift, OpenSearch, Splunk, HTTP | | | Biến đổi bằng Lambda, chuyển sang Parquet | | | Không lưu giữ dữ liệu — mất là mất | |

Ba lưu ý về hàm biến đổi: | Lưu ý | Chi tiết | |---|---| | Trả đủ mọi recordId | | | Thêm ký tự xuống dòng cuối mỗi bản ghi | | | Timeout mặc định 1 phút, nâng được lên 5 | |

Ba lưu ý về Index State Management: | Lưu ý | Chi tiết | |---|---| | Tự chuyển chỉ mục sang UltraWarm | | | Tự xoá chỉ mục quá hạn | | | Khai bằng chính sách JSON | |

Ba lưu ý về kết nối lai: | Lưu ý | Chi tiết | |---|---| | VPN hoặc Direct Connect để gửi từ tại chỗ | | | Kinesis Agent chạy trên máy chủ nguồn | | | Hoặc gọi thẳng PutRecordBatch | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Kiểm DeliveryToAmazonOpenSearch.Success | | | Xem thư mục lỗi trong bucket backup | | | Đo độ trễ từ lúc gửi tới lúc thấy trên bảng | |

Và một lời khuyên: hãy bật sao lưu S3 cho luồng Firehose ngay từ đầu. Firehose không lưu giữ dữ liệu — nếu OpenSearch gặp sự cố quá 24 giờ thì mọi sự kiện trong khoảng đó biến mất, và với dữ liệu giám sát thì đó chính là khoảng thời gian bạn cần nhìn lại nhất.

Câu 298 Domain - Continuous Improvement for Existing Solutions

A company stores confidential financial documents as well as sensitive corporate information in an Amazon S3 bucket. There is a new security policy that prohibits any public S3 objects in the company's S3 bucket. In the event that a public object was identified, the IT Compliance team must be notified immediately and the object's permissions must be remediated automatically. The notification must be sent as soon as a public object was created in the bucket.

What is the MOST suitable solution that should be implemented by the Solutions Architect to comply with this data policy?

  1. A

    Automatically track S3 actions using the Trusted Advisor API and AWS Cloud Development Kit (CDK). Set up an Amazon EventBridge rule with an Amazon SNS Topic to notify the IT Compliance team when the Trusted Advisor detected a PutObject API call with public-read permission. Launch another CloudWatch Events rule that invokes an AWS Lambda function to turn the newly uploaded public object to private.

  2. B

    Set up a Systems Manager (SSM) Automation document that changes any public object in the bucket to private. Integrate Amazon EventBridge with AWS Lambda to create a scheduled process that checks the S3 bucket every hour. Configure the Lambda function to invoke the SSM Automation document when a public object is identified and to notify the IT Compliance team via email using Amazon SNS.

  3. C

    Enable object-level logging in the S3 bucket to automatically track S3 actions using CloudTrail. Set up an Amazon EventBridge rule with an SNS Topic to notify the IT Compliance team when a PutObject API call with public-read permission is detected in the CloudTrail logs. Launch another CloudWatch Events rule that invokes an AWS Lambda function to turn the newly uploaded public object to private.

  4. D

    Integrate Amazon Lex with Amazon GuardDuty to detect public objects in the S3 bucket and to automatically update the permission of a public object to private. Associate an SNS Topic to Amazon Lex to notify the IT Compliance team via email if a public object was identified.

Xem giải thích

Đáp án

**C — Bật object-level logging trên bucket để CloudTrail ghi lại thao tác S3; đặt một quy tắc EventBridge kèm SNS topic báo cho đội tuân thủ khi phát hiện lời gọi PutObject có quyền public-read; và một quy tắc nữa gọi Lambda đổi object vừa tải lên thành riêng tư.

Vì sao đúng

Đề nêu ba yêu cầu, và phương án này khớp từng cái: | Yêu cầu | Thành phần | |---|---| | Phát hiện object công khai | CloudTrail data event | | Báo NGAY khi được tạo | EventBridge + SNS | | Tự sửa quyền | Lambda |

⚠ Điểm mấu chốt: "ngay khi được tạo" loại phương án chạy theo lịch:

Phương án B kiểm mỗi giờ
        ↓
    Object công khai có thể tồn
      tại tới 59 phút
        ↓
    Với tài liệu tài chính mật,
      59 phút là quá dài

⚠ Và object-level logging phải bật riêng — đây là chi tiết dễ bỏ sót:

CloudTrail mặc định chỉ ghi
  MANAGEMENT event
    → CreateBucket, PutBucketPolicy
        ↓
    `PutObject`, `GetObject` là
      DATA event
    → KHÔNG ghi mặc định
        ↓
    Không bật: EventBridge không
      bao giờ thấy gì
aws cloudtrail put-event-selectors --trail-name trail-chinh \
  --advanced-event-selectors '[{
    "Name": "Ghi data event cua bucket tai chinh",
    "FieldSelectors": [
      {"Field": "eventCategory", "Equals": ["Data"]},
      {"Field": "resources.type", "Equals": ["AWS::S3::Object"]},
      {"Field": "resources.ARN", "StartsWith":
        ["arn:aws:s3:::tai-lieu-tai-chinh/"]}]}]'

⚠ Và giới hạn phạm vi là điều bắt buộc về chi phí:

Bật data event cho MỌI bucket
        ↓
    Mỗi lời gọi GetObject cũng
      sinh một bản ghi
        ↓
    Với bucket lưu lượng cao
    → hoá đơn CloudTrail rất lớn

Quy tắc EventBridge:

{"source": ["aws.s3"],
 "detail-type": ["AWS API Call via CloudTrail"],
 "detail": {
   "eventSource": ["s3.amazonaws.com"],
   "eventName": ["PutObject", "PutObjectAcl"],
   "requestParameters": {
     "x-amz-acl": ["public-read", "public-read-write"]}}}

Lambda gỡ quyền công khai:

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

def xu_ly(event, context):
    tham_so = event['detail']['requestParameters']
    kho = tham_so['bucketName']
    khoa = tham_so['key']
    s3.put_object_acl(Bucket=kho, Key=khoa, ACL='private')
    return {'da_sua': f'{kho}/{khoa}'}

⚠ Và vì sao phương án A sai — Trusted Advisor không phát sự kiện:

A nói "theo dõi thao tác S3 bằng
  Trusted Advisor API"
        ↓
    Trusted Advisor có kiểm tra
      "S3 Bucket Permissions"
    → nhưng chạy theo LỊCH,
      làm mới vài giờ một lần
        ↓
    Và nó kiểm quyền BUCKET,
      không kiểm từng object

⚠ Và vì sao phương án D vô nghĩa:

D nói tích hợp Amazon Lex với
  GuardDuty
        ↓
    Lex là dịch vụ hội thoại
      (chatbot)
    → không liên quan gì tới việc
      quét quyền S3
        ↓
    Và GuardDuty phát hiện hành vi
      bất thường, không sửa ACL

⚠ Nhưng cách phòng ngừa tốt hơn hẳn là chặn từ gốc:

aws s3api put-public-access-block --bucket tai-lieu-tai-chinh \
  --public-access-block-configuration \
    BlockPublicAcls=true,IgnorePublicAcls=true,\
BlockPublicPolicy=true,RestrictPublicBuckets=true
Block Public Access: object
  KHÔNG BAO GIỜ công khai được
        ↓
    Lời gọi PutObject với
      public-read bị TỪ CHỐI
    → không cần phát hiện, không
      cần sửa

⚠ Và ở cấp tổ chức thì dùng SCP:

{"Effect": "Deny",
 "Action": "s3:PutAccountPublicAccessBlock",
 "Resource": "*"}
Cấm cả việc TẮT Block Public
  Access
    → không ai gỡ lớp bảo vệ được

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Phản ứng trong vài giây | | | Sửa tự động, không cần người | | | Có dấu vết kiểm toán đầy đủ | |

⚠ Và một lưu ý về "vài giây":

CloudTrail data event tới
  EventBridge trong vài giây
        ↓
    Nhưng không phải tức thì
    → có một khoảng ngắn object
      thật sự công khai
        ↓
    Đây là điểm yếu cố hữu của
      mọi kiểm soát PHÁT HIỆN

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

⚠ S3 Event Notifications qua EventBridge là cách đơn giản hơn nhiều so với CloudTrail data event.

aws s3api put-bucket-notification-configuration \
  --bucket tai-lieu-tai-chinh \
  --notification-configuration '{"EventBridgeConfiguration": {}}'
Tiêu chí CloudTrail data event S3 → EventBridge
Chi phí tính theo bản ghi miễn phí
Cấu hình event selector một cờ trên bucket
Có thông tin ACL CÓ không có trong sự kiện
Câu này cần biết ACL của yêu cầu
    → nên CloudTrail vẫn là lựa
      chọn đúng ở đây
        ↓
    Nhưng nếu chỉ cần biết "có
      object mới"
    → S3 EventBridge rẻ hơn và
      đơn giản hơn

Và cách đúng nhất vẫn là Block Public Access — phòng ngừa thay vì phát hiện. Câu hỏi buộc chọn giải pháp phát hiện, nhưng trong thực tế, một chính sách công ty cấm object công khai nên được thực thi bằng Block Public Access ở cấp tài khoản cộng với SCP cấm tắt nó.

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

  • **B. Dùng SSM Automation đổi object công khai thành riêng tư, EventBridge chạy Lambda kiểm tra mỗi giờ — đây là phương án gần nhất và thật sự tự động khắc phục được, nhưng chu kỳ một giờ vi phạm yêu cầu "báo ngay khi object công khai được tạo".
  • **A. Theo dõi bằng Trusted Advisor API và CDK — Trusted Advisor chạy theo lịch, kiểm quyền ở cấp bucket chứ không theo từng lời gọi API.
  • **D. Tích hợp Amazon Lex với GuardDuty — Lex là dịch vụ hội thoại, hoàn toàn không liên quan.

Ghi nhớ

⚠ Bốn lớp bảo vệ chống S3 công khai — bảng phải thuộc: | Lớp | Kiểu | |---|---| | Block Public Access | phòng ngừa, mạnh nhất | | SCP cấm tắt BPA | phòng ngừa cấp tổ chức | | Config rule + remediation | phát hiện, sửa trong vài phút | | CloudTrail + EventBridge + Lambda | phát hiện, sửa trong vài giây |

Từ khoá nhận diện:

"notify immediately when created" → CloudTrail data event + EventBridge "prevent public objects entirely" → Block Public Access "check every hour" → quá chậm nếu đề nói "immediately" "find sensitive data in S3" → Macie

⚠ Macie là dịch vụ đáng nhắc cho tài liệu tài chính:

aws macie2 create-classification-job \
  --job-type ONE_TIME \
  --s3-job-definition '{"bucketDefinitions": [
    {"accountId": "111122223333",
     "buckets": ["tai-lieu-tai-chinh"]}]}'
Macie nhận diện dữ liệu nhạy cảm:
  số thẻ, số an sinh, khoá API
        ↓
    Và cảnh báo bucket công khai
      chứa dữ liệu đó

Ba lưu ý về CloudTrail data event: | Lưu ý | Chi tiết | |---|---| | Không ghi mặc định | | | Tính phí theo số bản ghi | | | Giới hạn phạm vi bằng advanced event selector | |

Ba lưu ý về Block Public Access: | Cờ | Tác dụng | |---|---| | BlockPublicAcls | từ chối PUT có ACL công khai | | IgnorePublicAcls | bỏ qua ACL công khai đã có | | BlockPublicPolicy | từ chối bucket policy công khai | | RestrictPublicBuckets | chặn truy cập ẩn danh |

⚠ Bật ở cấp TÀI KHOẢN là mạnh nhất:

aws s3control put-public-access-block \
  --account-id 111122223333 \
  --public-access-block-configuration \
    BlockPublicAcls=true,IgnorePublicAcls=true,\
BlockPublicPolicy=true,RestrictPublicBuckets=true
Áp cho mọi bucket, kể cả bucket
  tạo sau này

Ba lưu ý về ACL của S3: | Lưu ý | Chi tiết | |---|---| | Object Ownership mặc định là Bucket Owner Enforced | | | Chế độ đó VÔ HIỆU HOÁ hẳn ACL | | | AWS khuyến nghị dùng bucket policy thay ACL | |

⚠ Với bucket tạo sau tháng 4/2023, ACL đã tắt sẵn:

`x-amz-acl: public-read` bị từ chối
    → nên tình huống trong đề chỉ
      xảy ra với bucket cũ hoặc
      bucket đã bật lại ACL

Ba lưu ý về giám sát: | Công cụ | Việc | |---|---| | IAM Access Analyzer | tìm bucket chia sẻ ra ngoài | | Config rule s3-bucket-public-read-prohibited | đánh giá liên tục | | Security Hub | gom phát hiện, chấm điểm |

Ba lưu ý về Lambda khắc phục: | Lưu ý | Chi tiết | |---|---| | Cần quyền s3:PutObjectAcl | | | Ghi log lại object đã sửa | | | Cẩn thận vòng lặp: sửa ACL cũng sinh sự kiện | |

⚠ Vòng lặp là bẫy thật:

Lambda gọi PutObjectAcl
    → sinh một sự kiện CloudTrail
        ↓
    EventBridge khớp → gọi Lambda
      lại
        ↓
    Lọc theo `userIdentity` để bỏ
      qua lời gọi của chính Lambda

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tải lên một object với --acl public-read | | | Bấm giờ tới lúc nhận email và tới lúc ACL bị sửa | | | Kiểm Lambda không tự kích hoạt lại chính nó | |

Và một lời khuyên: hãy bật Block Public Access ở cấp tài khoản song song với cơ chế phát hiện này. Phát hiện và sửa trong vài giây vẫn để lại một khoảng thời gian tài liệu thật sự công khai — còn phòng ngừa thì khoảng đó bằng không.

Câu 299 Domain - Design for New Solutions

A FinTech startup has recently consolidated its multiple AWS accounts using AWS Organizations. It currently has two teams in its organization, a security team and a development team. The former is responsible for protecting their cloud infrastructure and making sure that all of their resources are compliant, while the latter is responsible for developing new applications that are deployed to EC2 instances. The security team is required to set up a system that will check if all of the running EC2 instances are using an approved AMI. However, the solution should not stop the development team from deploying an EC2 instance running on a non-approved AMI. The disruption is only allowed once the deployment has been completed. In addition, they have to set up a notification system that sends the compliance state of the resources to determine whether they are compliant.

Which of the following options is the most suitable solution that the security team should implement?

  1. A

    Use the Amazon Inspector service to automatically check all of the AMIs that are being used by your EC2 instances. Set up an SNS topic that will send a notification to both the security and development teams if there is a non-compliant EC2 instance running in their VPCs.

  2. B

    Use an AWS Config Managed Rule and specify a list of approved AMI IDs. This rule will check whether running EC2 instances are using specified AMIs. Configure AWS Config to stream configuration changes and notifications to an Amazon SNS topic which will send a notification for non-compliant instances.

  3. C

    Set up a Trusted Advisor check that will verify whether the running EC2 instances in your VPCs are using approved AMIs. Create a CloudWatch alarm and integrate it with the Trusted Advisor metrics that will check all of the AMIs being used by your EC2 instances and that will send a notification if there is a running instance which uses an unapproved AMI.

  4. D

    Create and assign an SCP and an IAM policy that restricts the AWS accounts and the development team from launching an EC2 instance using an unapproved AMI. Create a CloudWatch alarm that will automatically notify the security team if there are non-compliant EC2 instances running in their VPCs.

Xem giải thích

Đáp án

**B — Dùng một AWS Config Managed Rule khai danh sách AMI ID được duyệt; quy tắc này kiểm tra các instance đang chạy có dùng đúng AMI không; cấu hình Config gửi thay đổi cấu hình và thông báo tới một SNS topic.

Vì sao đúng

Đề nêu một ràng buộc rất bất thường và đó chính là chìa khoá:

"Giải pháp KHÔNG được ngăn đội
  phát triển khởi động instance
  với AMI chưa duyệt"
        ↓
    "Việc gián đoạn chỉ được phép
      SAU KHI đã triển khai xong"
        ↓
    Nghĩa là: KHÔNG ĐƯỢC chặn
    → chỉ được phát hiện

⚠ Đây là lý do phương án D sai dù nghe rất hợp lý:

D dùng SCP + IAM policy chặn việc
  khởi động AMI chưa duyệt
        ↓
    SCP là kiểm soát PHÒNG NGỪA
    → chặn ngay lúc gọi API
        ↓
    Vi phạm đúng ràng buộc đề đặt ra

⚠ Và AWS Config là dịch vụ phát hiện đúng nghĩa:

Instance được tạo
        ↓
    Config ghi lại configuration item
        ↓
    Đánh giá lại quy tắc liên quan
        ↓
    Không tuân thủ → NON_COMPLIANT
    → gửi thông báo
        ↓
    Instance VẪN CHẠY

Quy tắc dựng sẵn approved-amis-by-id:

aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "chi-dung-ami-da-duyet",
  "Source": {"Owner": "AWS",
             "SourceIdentifier": "APPROVED_AMIS_BY_ID"},
  "InputParameters": "{\"amiIds\":\"ami-0abc123,ami-0def456\"}",
  "Scope": {"ComplianceResourceTypes": ["AWS::EC2::Instance"]}}'

⚠ Và có biến thể theo THẺ, tiện hơn nhiều khi danh sách AMI hay đổi:

--config-rule '{
  "ConfigRuleName": "ami-co-the-da-duyet",
  "Source": {"Owner": "AWS",
             "SourceIdentifier": "APPROVED_AMIS_BY_TAG"},
  "InputParameters": "{\"amisByTagKeyAndValue\":\"TrangThai:da-duyet\"}"}'
Theo ID: duyệt AMI mới phải sửa
  quy tắc
        ↓
    Theo thẻ: gắn thẻ vào AMI mới
    → quy tắc không đổi

Gửi thông báo qua SNS:

aws configservice put-delivery-channel --delivery-channel '{
  "name": "kenh-mac-dinh",
  "s3BucketName": "config-luu-tru",
  "snsTopicARN": "arn:aws:sns:ap-southeast-1:111122223333:tuan-thu"}'

⚠ Và nên lọc bằng EventBridge thay vì nhận mọi thông báo Config:

{"source": ["aws.config"],
 "detail-type": ["Config Rules Compliance Change"],
 "detail": {"newEvaluationResult": {
   "complianceType": ["NON_COMPLIANT"]}}}
Delivery channel gửi MỌI thay đổi
  cấu hình
    → rất ồn
        ↓
    EventBridge chỉ bắn khi trạng
      thái tuân thủ ĐỔI

⚠ Và vì sao phương án A sai — Inspector không kiểm AMI:

Amazon Inspector quét LỖ HỔNG
  trong phần mềm
        ↓
    CVE trong gói cài đặt, cấu hình
      mạng rủi ro
        ↓
    Không có khái niệm "AMI này có
      trong danh sách duyệt không"

⚠ Và vì sao phương án C sai — Trusted Advisor không có kiểm tra này:

Trusted Advisor có danh sách kiểm
  CỐ ĐỊNH
        ↓
    Chi phí, hiệu năng, bảo mật,
      chịu lỗi, hạn ngạch
        ↓
    Không có "AMI được duyệt"
    → và không viết luật riêng được

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Không cản trở việc triển khai | | | Phát hiện liên tục, không theo lịch | | | Áp được cho toàn tổ chức bằng organization rule | |

⚠ Và triển khai cho cả tổ chức chỉ bằng một lệnh:

aws configservice put-organization-config-rule \
  --organization-config-rule-name ami-da-duyet-toan-to-chuc \
  --organization-managed-rule-metadata \
    RuleIdentifier=APPROVED_AMIS_BY_ID,\
InputParameters='{"amiIds":"ami-0abc123"}'

⚠ Và nếu muốn thêm hành động sau khi phát hiện:

aws configservice put-remediation-configurations \
  --remediation-configurations '[{
    "ConfigRuleName": "chi-dung-ami-da-duyet",
    "TargetType": "SSM_DOCUMENT",
    "TargetId": "AWS-StopEC2Instance",
    "Automatic": false}]'
`Automatic: false` — chỉ khắc phục
  khi người bấm nút
        ↓
    Hợp với đề: "gián đoạn chỉ được
      phép sau khi triển khai xong"
    → đội bảo mật quyết định thời
      điểm

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

  • **D. Tạo SCP và IAM policy chặn việc khởi động instance với AMI chưa duyệt, kèm CloudWatch alarm báo cho đội bảo mật — đây là phương án gần nhất và thật sự thực thi được chính sách một cách chắc chắn nhất, nhưng nó chặn ngay lúc triển khai, vi phạm ràng buộc "không được ngăn đội phát triển khởi động instance".
  • **A. Dùng Amazon Inspector kiểm tra AMI đang dùng — Inspector quét lỗ hổng phần mềm, không đối chiếu danh sách AMI được duyệt.
  • **C. Dùng Trusted Advisor kiểm tra AMI và CloudWatch alarm trên chỉ số của nó — Trusted Advisor có danh sách kiểm cố định, không có kiểm tra này và không viết luật riêng được.

Ghi nhớ

⚠ Bốn kiểu kiểm soát và thời điểm tác động — bảng phải thuộc: | Kiểu | Thời điểm | Ví dụ | |---|---|---| | Phòng ngừa | TRƯỚC khi xảy ra | SCP, IAM policy, BPA | | Phát hiện | SAU khi xảy ra | Config, GuardDuty, Security Hub | | Ứng phó | sau khi phát hiện | remediation, Lambda | | Chỉ thị | hướng dẫn con người | quy trình, tài liệu |

⚠ Đề nào nói "không được chặn" là đang hỏi kiểm soát PHÁT HIỆN.

Từ khoá nhận diện:

"must not prevent deployment" → Config rule, không phải SCP "prevent entirely" → SCP "check running instances comply" → Config rule "scan for CVEs" → Inspector "detect malicious activity" → GuardDuty

Ba lưu ý về Config managed rule: | Lưu ý | Chi tiết | |---|---| | Hàng trăm luật viết sẵn | | | Có tham số đầu vào tuỳ chỉnh | | | Kích hoạt theo thay đổi hoặc theo chu kỳ | |

⚠ Hai kiểu kích hoạt:

Configuration change: đánh giá
  ngay khi tài nguyên đổi
        ↓
    Periodic: đánh giá theo chu kỳ
      (1, 3, 6, 12, 24 giờ)
        ↓
    `approved-amis-by-id` kích hoạt
      theo thay đổi
    → phát hiện gần như tức thì

Ba lưu ý về custom rule: | Loại | Đặc điểm | |---|---| | Lambda | viết bằng mã, linh hoạt nhất | | Guard (Custom Policy) | DSL khai báo, không cần Lambda |

rule ami_da_duyet {
  configuration.imageId in
    ["ami-0abc123", "ami-0def456"]
}

Ba lưu ý về thông báo: | Cách | Đặc điểm | |---|---| | Delivery channel + SNS | mọi thay đổi, rất ồn | | EventBridge lọc theo compliance | chỉ khi trạng thái đổi | | Security Hub | gom và chấm điểm |

Ba lưu ý về quản lý AMI: | Lưu ý | Chi tiết | |---|---| | EC2 Image Builder dựng AMI theo pipeline | | | Chia sẻ AMI trong tổ chức bằng RAM | | | Gắn thẻ AMI đã duyệt để dùng với luật theo thẻ | |

⚠ EC2 Image Builder là mảnh ghép còn thiếu:

Danh sách AMI duyệt bằng tay
    → nhanh chóng lỗi thời
        ↓
    Image Builder: pipeline dựng AMI
      mới hằng tháng, có kiểm thử
    → tự gắn thẻ, tự chia sẻ
    → và tự phân phối tới các Region

Ba lưu ý về aggregator: | Lưu ý | Chi tiết | |---|---| | Gom kết quả nhiều tài khoản về một chỗ | | | Kiểu Organizations tự bao gồm tài khoản mới | | | Có truy vấn nâng cao bằng SQL | |

Ba lưu ý về chi phí Config: | Lưu ý | Chi tiết | |---|---| | Tính theo configuration item ghi lại | | | Và theo số lần đánh giá quy tắc | | | Giới hạn loại tài nguyên cần ghi | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Khởi động instance với AMI lạ — phải chạy được | | | Kiểm có nhận thông báo NON_COMPLIANT không | | | Xem timeline của instance trong Config | |

Và một lời khuyên: hãy dùng biến thể theo thẻ (approved-amis-by-tag) thay vì liệt kê ID. Danh sách AMI ID cứng trong quy tắc sẽ lỗi thời sau mỗi lần dựng bản vá mới — và một quy tắc tuân thủ mà chính nó luôn lạc hậu thì chỉ tạo ra cảnh báo giả.

Câu 300 Domain - Accelerate Workload Migration and Modernization


A company is hosting its application and MySQL database in its on-premises data center. The database increases at about 10GB per day and is approximately 25TB in total size. The company wants to migrate the database workload to the AWS cloud. A 50Mbps VPN connection is currently in place to connect the corporate network to AWS. The company plans to complete the migration to AWS within 3 weeks with the LEAST downtime possible.

Which of the following solutions should be implemented to meet the company requirements?

  1. A

    Create an AWS Database Migration Service (DMS) instance and an Amazon Aurora MySQL DB instance. Define the on-premises database server details and the Amazon Aurora MySQL instance details on the AWS DMS instance. Use the VPN connection to start the replication from the on-premises database server to AWS. Wait until the replication is complete then update the database DNS entry to point to the Aurora DB instance. Stop the database replication.

  2. B

    Request for an AWS Snowball device. Create a database export of the on-premises database server and load it to the Snowball device. Once the data is imported to AWS, provision an Amazon Aurora MySQL DB instance and load the data. Using the VPN connection, configure replication from the on-premises database server to the Amazon Aurora DB instance. Wait until the replication is complete then update the database DNS entry to point to the Aurora DB instance. Stop the database replication.

  3. C

    Create a snapshot of the on-premises database server and use VM Import/Export service to import the snapshot to AWS. Provision a new Amazon EC2 instance from the imported snapshot. Configure replication from the on-premises database server to the EC2 instance through the VPN connection. Wait until the replication is complete then update the database DNS entry to point to the EC2 instance. Stop the database replication.

  4. D

    Temporarily stop the on-premises application to stop any database I/O operation. Request for an AWS Snowball device. Create a database export of the on-premises database server and load it to the Snowball device. Once the data is imported to AWS, provision an Amazon Aurora MySQL DB instance and load the data. Update the database DNS entry to point to the Aurora DB instance. Start the application again to resume normal operations.

Xem giải thích

Đáp án

**B — Đặt một thiết bị AWS Snowball, xuất cơ sở dữ liệu tại chỗ và nạp vào thiết bị; khi dữ liệu đã vào AWS thì dựng một Aurora MySQL và nạp dữ liệu vào đó; rồi dùng kết nối VPN thiết lập sao chép từ CSDL tại chỗ sang Aurora và chờ tới khi đồng bộ.

Vì sao đúng

Đề cho những con số phải ghép lại:

25 TB dữ liệu, tăng 10 GB mỗi ngày
    → đường truyền VPN 50 Mbps
        ↓
    Phải xong trong 3 TUẦN
    → ngừng dịch vụ ÍT NHẤT có thể

⚠ Tính thời gian truyền 25 TB qua 50 Mbps:

25 TB = 200.000.000 Mb
        ↓
    Ở 50 Mbps: 4.000.000 giây
    = 46 NGÀY
        ↓
    Hiệu suất thực tế ~65%
    → khoảng 71 ngày
        ↓
    Hạn là 21 ngày → KHÔNG KỊP

Đây là lý do phương án A (chỉ dùng DMS qua VPN) thất bại.

⚠ Và đây là ngưỡng quyết định dùng Snowball: | Dung lượng | Băng thông | Nên dùng | |---|---|---| | 25 TB | 50 Mbps | Snowball (mạng mất 46+ ngày) | | 25 TB | 1 Gbps | mạng (khoảng 2,5 ngày) | | 1 TB | 50 Mbps | mạng (khoảng 2 ngày) |

⚠ Và điểm mấu chốt thứ hai: dữ liệu vẫn tăng 10 GB mỗi ngày:

Snowball chỉ chở được ẢNH CHỤP
  tại một thời điểm
        ↓
    Chu trình Snowball mất 1-2 tuần
        ↓
    Trong thời gian đó CSDL nguồn
      đã đổi thêm 100-140 GB
        ↓
    Phải có bước đồng bộ phần chênh

⚠ Đây chính là điểm phân biệt B với D:

D: dừng ứng dụng NGAY từ đầu
    → rồi mới xuất và chở đi
        ↓
    Ngừng dịch vụ suốt 1-2 tuần
    → vi phạm "ít gián đoạn nhất"
        ↓
    B: chở dữ liệu nền đi trước,
      rồi DMS đồng bộ phần chênh
      qua VPN
    → 100 GB qua 50 Mbps mất
      khoảng 5 giờ

Quy trình đầy đủ:

1. Đặt Snowball
        ↓
2. Xuất CSDL (mysqldump) và nạp
     vào thiết bị
        ↓
3. Gửi trả, AWS nạp vào S3
        ↓
4. Dựng Aurora MySQL, nạp từ S3
        ↓
5. DMS chế độ CDC đồng bộ phần
     chênh qua VPN
        ↓
6. Độ trễ về 0 → đổi DNS

Nạp từ S3 vào Aurora:

LOAD DATA FROM S3 's3://kho-di-tru/du-lieu.csv'
INTO TABLE giao_dich
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';

⚠ Và Aurora còn có cách nạp nhanh hơn từ backup Percona:

aws rds restore-db-cluster-from-s3 \
  --db-cluster-identifier cum-aurora \
  --engine aurora-mysql \
  --s3-bucket-name kho-di-tru \
  --s3-prefix backup-xtrabackup/ \
  --source-engine mysql --source-engine-version 8.0.35
Khôi phục từ Percona XtraBackup
    → nhanh hơn nhiều so với
      nạp từ dump SQL
        ↓
    Đây là cách khuyến nghị cho
      CSDL lớn

Tác vụ DMS chỉ chạy CDC:

aws dms create-replication-task \
  --replication-task-identifier dong-bo-phan-chenh \
  --migration-type cdc \
  --cdc-start-position "mysql-bin-changelog.000123:456789" \
  --source-endpoint-arn <arn-nguon> \
  --target-endpoint-arn <arn-aurora>

⚠ cdc-start-position là chi tiết quyết định:

Phải biết ĐÚNG vị trí binlog lúc
  chụp dump
        ↓
    `mysqldump --master-data=2` ghi
      vị trí đó vào đầu tệp
        ↓
    Sai vị trí: hoặc mất giao dịch,
      hoặc phát lại trùng

⚠ Và nguồn phải giữ binlog đủ lâu:

Chu trình Snowball 1-2 tuần
        ↓
    Binlog phải giữ ít nhất chừng
      đó
        ↓
    `expire_logs_days` mặc định
      thường ngắn hơn nhiều
    → hết binlog là không CDC được
      nữa, phải làm lại từ đầu
SET GLOBAL binlog_expire_logs_seconds = 2592000;  -- 30 ngày

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

C dùng VM Import/Export nhập
  snapshot của MÁY CHỦ
        ↓
    Được một EC2 chạy MySQL tự quản
    → không phải Aurora
        ↓
    Và snapshot 25 TB vẫn phải
      truyền qua mạng để nhập
        ↓
    Cùng vấn đề băng thông

Ba lợi ích: | Lợi ích | Chi tiết | |---|---| | Vượt được giới hạn băng thông | | | Ngừng dịch vụ chỉ vài phút lúc chuyển | | | Aurora là dịch vụ quản lý, hết việc vá máy chủ | |

⚠ Và một lưu ý: Snowball vs Snowball Edge:

"AWS Snowball" nguyên bản (50/80 TB)
  đã ngừng
        ↓
    Hiện nay là Snowball Edge:
      Storage Optimized (80 TB)
      Compute Optimized (28 TB)
        ↓
    25 TB vừa một thiết bị

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

  • **A. Dựng DMS và Aurora MySQL, sao chép qua VPN 50 Mbps — đây là phương án gần nhất và kiến trúc đích hoàn toàn đúng, nhưng 25 TB qua 50 Mbps mất hơn 46 ngày lý thuyết, vượt xa hạn 3 tuần.
  • **D. Dừng ứng dụng ngay từ đầu, dùng Snowball, nạp vào Aurora rồi khởi động lại — chu trình Snowball mất 1-2 tuần, nghĩa là ngừng dịch vụ suốt thời gian đó.
  • **C. Chụp snapshot máy chủ và dùng VM Import/Export — cho ra một EC2 tự quản chứ không phải Aurora, và snapshot vẫn phải truyền qua mạng.

Ghi nhớ

⚠ Mẫu di trú CSDL lớn — bảng phải thuộc:

1. Chở dữ liệu NỀN bằng Snowball
        ↓
2. Đồng bộ phần CHÊNH bằng DMS CDC
      qua mạng
        ↓
3. Chuyển đổi khi độ trễ về 0
Đây là mẫu chuẩn cho mọi bài toán
  "dữ liệu lớn + băng thông kém +
  ít gián đoạn"

Từ khoá nhận diện:

"TB of data, slow connection, deadline" → Snowball + CDC "minimal downtime database migration" → DMS full load + CDC "downtime acceptable" → dump và restore "change database engine" → thêm SCT

⚠ Cách tính nhanh thời gian truyền:

Số ngày ≈ (TB × 8.000.000) /
          (Mbps × 86.400 × 0,65)
        ↓
    25 TB ở 50 Mbps ≈ 71 ngày
    25 TB ở 1 Gbps ≈ 3,6 ngày

Ba lưu ý về Snowball Edge: | Lưu ý | Chi tiết | |---|---| | Storage Optimized 80 TB dùng được | | | Chu trình khoảng 1-2 tuần | | | Mã hoá tự động bằng KMS | |

Ba lưu ý về DMS CDC: | Lưu ý | Chi tiết | |---|---| | Nguồn phải bật binlog định dạng ROW | | | Giữ binlog đủ dài cho cả chu trình | | | Ghi lại vị trí binlog lúc chụp dump | |

⚠ Ba tham số MySQL bắt buộc:

log_bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL

Ba lưu ý về Aurora MySQL: | Lưu ý | Chi tiết | |---|---| | Tương thích MySQL, ít phải sửa ứng dụng | | | Tối đa 15 replica, reader endpoint tự cân bằng | | | Lưu trữ tự tăng tới 128 TB | |

Ba lưu ý về kiểm chứng dữ liệu: | Cách | Chi tiết | |---|---| | DMS data validation so từng dòng | | | Đếm số dòng mỗi bảng hai bên | | | So checksum vài bảng quan trọng | |

Ba lưu ý về chuyển đổi: | Bước | Chi tiết | |---|---| | Dừng ghi vào nguồn | | | Chờ CDCLatencyTarget về 0 | | | Đổi DNS với TTL ngắn đặt sẵn | |

⚠ Hạ TTL từ nhiều ngày trước:

TTL đang là 3600 giây
    → đổi DNS xong vẫn còn client
      gọi địa chỉ cũ tới một giờ
        ↓
    Hạ xuống 60 giây trước ngày
      chuyển vài ngày

Ba lưu ý về kế hoạch quay lui: | Lưu ý | Chi tiết | |---|---| | Giữ CSDL nguồn chạy thêm một thời gian | | | Dựng CDC ngược từ Aurora về nguồn | | | Có kịch bản đổi DNS ngược viết sẵn | |

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chạy ứng dụng thử trên Aurora trước khi chuyển | | | So hiệu năng truy vấn nặng nhất | | | Đo CDCLatencyTarget trước giờ chuyển | |

Và một lời khuyên: hãy kéo dài thời gian giữ binlog trên máy chủ nguồn trước khi gửi Snowball đi. Toàn bộ kế hoạch dựa vào việc DMS phát lại được mọi thay đổi kể từ lúc chụp dump — nếu binlog đã bị xoay vòng và xoá mất trong lúc thiết bị đang trên đường, bạn phải bắt đầu lại từ con số không.