บทที่ 13: Modernization & Refactoring
1. วัตถุประสงค์บท
หัวข้อที่มีชื่อว่า “1. วัตถุประสงค์บท”บทนี้เป็นเจ้าของครึ่งหลังของ Domain 4 ของ SAP-C02 (“Accelerate Workload Migration and Modernization”) ในส่วนที่ว่าด้วย การทำให้ workload ทันสมัย (modernize) และ refactor สถาปัตยกรรม — ต่อจากบทที่ 12 ที่ครอบคลุม migration mechanics (7 Rs, discovery, MGN, wave planning). บทที่ 12 แตะ Refactor เพียงในฐานะ 1 ใน 7 Rs; บทนี้ลงลึกว่า “เมื่อเลือก Refactor แล้ว จะทำอย่างไรให้ปลอดภัยและคุ้มค่า” ในมุม Solutions Architect ระดับ Professional ที่ต้องชั่ง agility vs risk vs ROI ไม่ใช่ modernize เพราะเป็นของใหม่
เป้าหมายเมื่อจบบท คุณต้องตอบข้อสอบที่ผสมประเด็นเหล่านี้ได้อย่างมั่นใจ:
- ระบุ แรงจูงใจในการ modernize (agility, cost, scale, resilience) และที่สำคัญกว่า — รู้ว่า “เมื่อไหร่ไม่ควร modernize” (business driver อ่อน, ROI ต่ำ, ความเสี่ยงสูงกว่าผลตอบแทน)
- ออกแบบการแตก monolith → microservices อย่างค่อยเป็นค่อยไปด้วย strangler fig pattern, decomposition ตาม bounded context, anti-corruption layer, และหลัก database-per-service
- เลือก containerization path ที่ถูกต้อง: AWS App2Container (A2C) และเกณฑ์เลือก orchestration ECS/EKS/Fargate (ต่อยอดจากบทที่ 05)
- ตัดสินใจ serverless refactoring ด้วย Lambda + API Gateway + EventBridge/Step Functions และรู้ว่า serverless เหมาะ/ไม่เหมาะ เมื่อใด (ต่อยอดจากบทที่ 05)
- ทำ database modernization ไปสู่ purpose-built/managed engine ด้วย Babelfish for Aurora PostgreSQL และ DMS + SCT (re-platform engine — กลไกเต็มดูบทที่ 07)
- วาง data & analytics modernization ด้วย data lake บน S3 และการ decouple ingest/process/serve
- ใช้ DevOps modernization (IaC/CI-CD, managed services) เพื่อลด undifferentiated heavy lifting (ต่อยอดจากบทที่ 11)
- เลือก deployment pattern ความเสี่ยงต่ำ (blue/green, canary) ระหว่าง modernize (ต่อยอดจากบทที่ 11)
ขอบเขตที่บทนี้ไม่ลงลึก (cross-reference แทน): migration mechanics/tools (MGN, ADS discovery, wave planning, cutover) → บทที่ 12; compute/integration service พื้นฐาน (ECS/EKS/Fargate/Lambda/SQS/SNS/EventBridge/Step Functions internals) → บทที่ 05; database engine detail (Aurora architecture, DynamoDB partition key, DMS full load + CDC, SCT) → บทที่ 07; observability/CI-CD/deployment mechanics เต็ม → บทที่ 11.
บทนี้สืบทอด convention <details><summary>เฉลย</summary> และ bullet “ทำไมตัวเลือกอื่นผิด” จากบท 01–12 และใช้ตาราง “requirement/keyword → pattern/บริการ → เหตุผล/trade-off” เป็นรูปแบบหลักของส่วนที่ 3
2. แนวคิดหลัก
หัวข้อที่มีชื่อว่า “2. แนวคิดหลัก”2.1 ทำไมต้อง modernize — และเมื่อไหร่ “ไม่ควร”
หัวข้อที่มีชื่อว่า “2.1 ทำไมต้อง modernize — และเมื่อไหร่ “ไม่ควร””Modernization คือการเปลี่ยนสถาปัตยกรรม/เทคโนโลยีของ workload ให้ใช้ประโยชน์จาก cloud-native capability (ต่างจาก migration ที่แค่ “ย้ายที่”). ในมุมข้อสอบ Pro การ modernize ไม่ใช่เป้าหมายในตัวเอง แต่เป็น investment ที่ต้องมี business driver ชัด. แรงจูงใจหลัก 4 ด้าน (ผูกกับ WAF pillars บทที่ 01):
| แรงจูงใจ | อาการของ workload เดิม | ผลลัพธ์ที่คาดหวัง | pillar ที่เกี่ยว |
|---|---|---|---|
| Agility | release ช้า, deploy ทั้ง monolith พร้อมกัน, ทีมเหยียบเท้ากัน | deploy อิสระต่อ service, time-to-market เร็วขึ้น | Operational Excellence |
| Scale | scale ทั้งก้อนทั้งที่ bottleneck อยู่ module เดียว, มี ceiling | scale เฉพาะส่วนที่ร้อน, elastic ตาม demand | Performance Efficiency, Reliability |
| Cost | จ่าย server 24/7 ที่ utilization ต่ำ, license หนัก | จ่ายตามใช้ (serverless), เลิก license commercial | Cost Optimization |
| Resilience | fault ที่ module เดียวล้มทั้งระบบ (blast radius กว้าง) | fault isolation ต่อ service, degrade แบบ graceful | Reliability |
“เมื่อไหร่ไม่ควร modernize” (จุดที่ข้อสอบ Pro ชอบวางกับดัก): Solutions Architect ที่โตแล้วต้องรู้จักตอบ “อย่าเพิ่ง”. สัญญาณที่ modernize ไม่คุ้ม:
- ไม่มี business driver ชัด — โจทย์บอกแค่ “ทีมอยากลอง microservices” โดยไม่มีปัญหา scale/agility จริง → นี่คือ over-engineering (ตัดตามหลักบทที่ 01)
- App ใกล้ EOL / จะปลด — modernize app ที่จะเลิกใช้ใน 1 ปี = เสียเปล่า → Retain/Retire (บทที่ 12) เหมาะกว่า
- COTS / ซื้อมา แก้ code ไม่ได้ — refactor ไม่ได้เลยเพราะไม่มี source → Rehost/Repurchase
- Deadline สั้น ต้องออกจาก data center เร็ว — refactor ใช้เวลานานสุดใน 7 Rs → Rehost ก่อน แล้ว modernize ทีหลังบน AWS (pattern “migrate then modernize”)
- ทีมยังไม่มี skill (people gap ตาม CAF บทที่ 12) — บังคับ refactor ทันทีเสี่ยงสูง
หลักสอบสำคัญ: เมื่อโจทย์มี constraint tight deadline + modernize พร้อมกัน คำตอบมักเป็น “rehost/relocate ก่อน แล้ว re-architect ทีหลัง” ไม่ใช่ refactor ทันที — เพราะ refactor ระหว่างวิ่งหนี data center = เสี่ยง cutover ล้ม. คำว่า incrementally modernize after migration เป็นสัญญาณของคำตอบนี้
2.2 Monolith → Microservices: Strangler Fig Pattern
หัวข้อที่มีชื่อว่า “2.2 Monolith → Microservices: Strangler Fig Pattern”การเขียน monolith ใหม่ทั้งก้อนแบบ “big bang rewrite” คือ anti-pattern ที่ข้อสอบจะให้เป็น distractor เสมอ — เสี่ยงสูง, ใช้เวลานาน, ไม่มี checkpoint. คำตอบที่ถูกคือ Strangler Fig Pattern (ตั้งชื่อตามต้นไทรที่ค่อย ๆ โอบรัดต้นไม้เดิมจนแทนที่):
หลักการ: วาง facade/proxy (มักเป็น API Gateway หรือ Application Load Balancer) ไว้หน้า monolith แล้วค่อย ๆ ดึงฟังก์ชันออกมาเป็น service ใหม่ทีละส่วน โดย route traffic ของ path นั้นไป service ใหม่ ในขณะที่ path ที่เหลือยังวิ่งเข้า monolith เดิม. เมื่อดึงครบทุกส่วน monolith ก็ “ถูกรัดจนตาย” แล้วปลดทิ้ง
ทำไมชนะ big-bang rewrite:
- ลด risk — แต่ละ increment เล็ก, ทดสอบ/rollback ได้, ระบบเดิมยังทำงาน
- ส่งมอบคุณค่าระหว่างทาง — ไม่ต้องรอ 2 ปีถึงจะได้ผล
- เรียนรู้และปรับ — ค้นพบ boundary ที่ผิดได้เร็วก่อนลงทุนหนัก
บริการ AWS ที่รองรับ: AWS Migration Hub Refactor Spaces (แตะแล้วบทที่ 12) เป็น infrastructure สำเร็จรูปสำหรับ strangler fig — มันสร้าง application proxy (Amazon API Gateway + AWS Transit Gateway + Network Load Balancer ภายใน) ที่จัดการ routing rule ระหว่าง monolith เดิมกับ microservice ใหม่ให้อัตโนมัติ ลด undifferentiated heavy lifting ของการ setup routing/networking เอง. keyword ในโจทย์: incrementally decompose, route traffic gradually, strangler
2.3 Decomposition ตาม Bounded Context และ Anti-Corruption Layer
หัวข้อที่มีชื่อว่า “2.3 Decomposition ตาม Bounded Context และ Anti-Corruption Layer”การแตก monolith ผิดจุดคือสาเหตุอันดับหนึ่งที่ microservices ล้มเหลว (ได้ “distributed monolith” ที่ service คุยกันแน่นจนแย่กว่าเดิม). หลักการแตกที่ถูก:
- Bounded context (จาก Domain-Driven Design): แตกตาม domain ธุรกิจ ที่มีขอบเขตความหมายชัด (เช่น Order, Inventory, Payment, Shipping) ไม่ใช่แตกตาม technical layer. แต่ละ service เป็นเจ้าของ domain logic + data ของตัวเอง มี interface ชัด coupling ต่ำ
- Database-per-service: แต่ละ microservice เป็นเจ้าของ data store ของตัวเอง — service อื่นห้ามเข้า database ตรง ต้องผ่าน API เท่านั้น. นี่คือหัวใจที่ทำให้ deploy/scale/เปลี่ยน schema ได้อิสระ. ต่อยอดจากบทที่ 07: การแตก data ยังเปิดโอกาสเลือก purpose-built database ต่อ service (Order → Aurora relational, Cart → DynamoDB, Session → ElastiCache) แทนยัดทุกอย่างลง relational เดียว
- Anti-Corruption Layer (ACL): ชั้น translation ที่คั่นระหว่าง service ใหม่กับ monolith เดิม (หรือ legacy system) เพื่อ แปลง model/protocol ไม่ให้ “ภาษาสกปรก” ของระบบเก่าซึมเข้ามาปนเปื้อน domain model ใหม่. ใน AWS มักทำเป็น Lambda/container เล็กที่ map request/response ระหว่างสองฝั่ง ระหว่างช่วง strangler
การจัดการ data ข้าม service (จุดที่ข้อสอบชอบถาม): เมื่อ data กระจายหลาย service แล้ว transaction แบบ ACID ข้าม service ทำไม่ได้ตรง ๆ ต้องใช้ pattern แบบ:
- Event-driven / eventual consistency ผ่าน EventBridge/SQS (บทที่ 05) — service ปล่อย event เมื่อ state เปลี่ยน service อื่น react
- Saga pattern — orchestrate ด้วย AWS Step Functions (บทที่ 05) เพื่อจัดการ business transaction ที่ข้ามหลาย service พร้อม compensating action เมื่อ step ล้มเหลว
- CQRS + materialized view — แยก read model ออกจาก write model สำหรับ query ข้าม domain
2.4 Containerization Path และ AWS App2Container (A2C)
หัวข้อที่มีชื่อว่า “2.4 Containerization Path และ AWS App2Container (A2C)”การ containerize เป็น modernization step ที่ risk ต่ำกว่า refactor เต็ม — ยังไม่เปลี่ยน business logic แต่ได้ portability, packing density, และ CI/CD ที่ดีขึ้น. เครื่องมือหลักของ AWS:
AWS App2Container (A2C) — CLI tool ที่ วิเคราะห์ application ที่รันอยู่ (Java/.NET) บน physical/VM/cloud แล้ว สร้าง container image + artifact สำหรับ deploy โดยอัตโนมัติ:
- discover running application → analyze dependency → generate Dockerfile + image → สร้าง ECS task definition / EKS deployment manifest + CloudFormation ให้พร้อม deploy
- ไม่ต้องแก้ source code (containerize as-is) — เหมาะ replatform สู่ container โดยทีมไม่ต้องเชี่ยว Docker
- keyword: containerize existing .NET/Java application, without rewriting, modernize to containers
การเลือก orchestration (ต่อยอดแกนตัดสินใจ compute บทที่ 05):
| ต้องการ | เลือก | เหตุผล |
|---|---|---|
| least operational overhead, ไม่อยากจัดการ node เลย | ECS on Fargate | serverless data plane, ไม่มี node ให้ patch; ECS control plane ฟรีและเรียบง่าย |
| ต้องการ Kubernetes API / portability / multi-cloud, มี team ecosystem k8s | EKS (Fargate หรือ EC2) | k8s มาตรฐาน, ใช้ Helm/operator เดิม; แลกกับ operational complexity สูงกว่า |
| ต้องการคุม kernel/GPU/special networking, Spot หนัก | ECS/EKS on EC2 | เข้าถึง instance เต็ม, ใช้ Spot ผ่าน capacity provider; แลกกับต้องจัดการ node |
หลักตัด distractor: โจทย์เน้น least operational overhead + container → Fargate; โจทย์เน้น existing Kubernetes skills/tooling หรือ portability across environments → EKS; โจทย์ไม่มีเหตุผลเชิง k8s ชัดแต่มีคนใส่ EKS มา → มักเป็น over-engineered distractor
2.5 Serverless Refactoring: Event-Driven Architecture
หัวข้อที่มีชื่อว่า “2.5 Serverless Refactoring: Event-Driven Architecture”ปลายทางที่ cloud-native ที่สุดของ refactor คือ serverless / event-driven — ตัด undifferentiated heavy lifting ของ server/scaling/patching ออกหมด. องค์ประกอบหลัก (กลไกเต็มบทที่ 05):
- AWS Lambda — compute event-driven จ่ายต่อ invocation, scale อัตโนมัติจาก 0 → พัน concurrent
- Amazon API Gateway (REST/HTTP) หรือ AppSync (GraphQL) — synchronous API front door แทน web server เดิม
- Amazon EventBridge — event bus กลางสำหรับ decouple producer/consumer แบบ content-routing (หัวใจของ event-driven ที่แท้จริง)
- AWS Step Functions — orchestrate workflow/saga ที่มีหลาย step มี retry/catch/audit
- Amazon SQS / SNS — buffer และ fan-out (บทที่ 05)
- purpose-built managed data: DynamoDB (serverless key-value), Aurora Serverless v2, S3
เมื่อ serverless เหมาะ:
- workload spiky / unpredictable / event-driven (จ่ายเฉพาะตอนใช้, scale-to-zero)
- ต้องการ least operational overhead, ทีมเล็ก, อยาก focus business logic
- แตก monolith เป็นชิ้นเล็ก stateless ตาม bounded context
เมื่อ serverless ไม่เหมาะ (จุดที่ข้อสอบวาง trap):
- long-running / heavy compute เกิน Lambda 15 นาที (batch/HPC/video render) → Fargate/EC2/Batch
- latency-sensitive สุด ๆ / cold start ยอมไม่ได้ และ steady traffic สูงสม่ำเสมอ → container ที่ warm ตลอดอาจถูกกว่าและนิ่งกว่า (Lambda provisioned concurrency ช่วยได้แต่มีค่าใช้จ่าย)
- traffic สูงคงที่ 24/7 ปริมาณมหาศาล — ที่ volume สูงมาก Lambda per-request อาจ แพงกว่า container/EC2 ที่ commit ด้วย Savings Plans (บทที่ 10)
- legacy protocol / stateful connection ยาว ที่ไม่เข้ากับ model event-driven
2.6 Database Modernization: สู่ Managed & Purpose-Built
หัวข้อที่มีชื่อว่า “2.6 Database Modernization: สู่ Managed & Purpose-Built”การ modernize database มี 2 มิติที่ข้อสอบชอบผสม (กลไก engine เต็มดูบทที่ 07):
(1) Re-platform สู่ managed — ย้าย self-managed database (บน EC2/on-prem) ไป managed service เพื่อลด ops (backup/patch/HA อัตโนมัติ). ตัวอย่าง: Oracle/SQL Server บน EC2 → RDS หรือ Aurora. นี่คือ Replatform ตาม 7 Rs (บทที่ 12)
(2) Re-engine / heterogeneous migration — เปลี่ยน engine เชิงพาณิชย์ (Oracle/SQL Server) ไป open-source (PostgreSQL/MySQL/Aurora) เพื่อ เลิก license หนัก และได้ cloud-native scaling. ทำผ่าน AWS SCT + AWS DMS (บทที่ 07): SCT แปลง schema/stored procedure, DMS ย้าย data ด้วย full load + CDC เพื่อ near-zero downtime
Babelfish for Aurora PostgreSQL (ตอบ cross-reference จากบทที่ 07): translation layer ที่ให้ Aurora PostgreSQL เข้าใจ T-SQL (SQL Server) และ TDS protocol โดยตรง. คุณค่าเชิง modernization:
- ย้ายออกจาก SQL Server ไป Aurora PostgreSQL โดย แก้ application code น้อยที่สุด — app เดิมที่พูด T-SQL ยังต่อได้เหมือนเดิมผ่าน Babelfish endpoint
- ลด license SQL Server ทันที, ได้ Aurora scaling/HA
- เหมาะเป็นสะพานระหว่าง strangler: ย้าย DB ก่อน แล้วค่อย ๆ rewrite query เป็น PostgreSQL-native ทีหลัง
- keyword: migrate off SQL Server, minimal application changes, reduce licensing cost
decompose relational monolith ไป purpose-built (ตอบ cross-reference จากบทที่ 07): เมื่อแตก service ตาม bounded context (2.3) ให้เลือก database ตรง access pattern ต่อ service — ไม่ต้องยัดทุก service ลง relational เดียว (one-size-fits-all เป็น anti-pattern ตามปรัชญา purpose-built บทที่ 07)
2.7 Data & Analytics Modernization: Data Lake บน S3
หัวข้อที่มีชื่อว่า “2.7 Data & Analytics Modernization: Data Lake บน S3”pattern การ modernize analytics ที่ออกสอบบ่อยคือการเลิก monolithic data warehouse บน-prem ที่ ingest/process/serve ผูกกันแน่น ไปเป็น data lake architecture ที่ decouple 3 ชั้น บน S3 (ต่อยอดจากบทที่ 06/07):
- Ingest — รับข้อมูลหลายแหล่งด้วย Kinesis Data Streams/Firehose (streaming), DataSync/DMS (batch/CDC) → landing ลง S3
- Store — S3 เป็น central data lake (durable 11 nines, ถูก, decouple storage จาก compute). ใช้ AWS Lake Formation จัดการ governance/permission และ AWS Glue Data Catalog เป็น metadata catalog
- Process — AWS Glue (serverless ETL), Amazon EMR (Spark/Hadoop) — scale compute แยกจาก storage
- Serve/Analyze — Amazon Athena (query S3 ตรงด้วย SQL, serverless), Amazon Redshift + Spectrum (warehouse + query S3), QuickSight (BI)
คุณค่าเชิงสถาปัตยกรรม: decouple storage จาก compute ทำให้ scale/จ่ายแต่ละชั้นอิสระ, เก็บ raw data ได้ทุกรูปแบบ (schema-on-read), และเพิ่ม consumer ใหม่ได้โดยไม่กระทบ pipeline เดิม. keyword: decouple ingestion from processing, schema-on-read, centralized data lake, serverless analytics
2.8 DevOps Modernization: IaC + CI/CD + Managed Services
หัวข้อที่มีชื่อว่า “2.8 DevOps Modernization: IaC + CI/CD + Managed Services”modernization ไม่ได้จบที่ architecture — ต้องมี delivery pipeline ที่ทันสมัยด้วย (ต่อยอดจากบทที่ 11):
- Infrastructure as Code — ทุกอย่างเป็น code (CloudFormation/CDK/Terraform) เพื่อ reproducible, version control, review ได้ (บทที่ 11). แทนการ provision มือ
- CI/CD — CodePipeline/CodeBuild/CodeDeploy (หรือ GitHub Actions) automate build/test/deploy → deploy บ่อย, เล็ก, ปลอดภัย
- ลด undifferentiated heavy lifting ด้วย managed services — หลักคิดหลักของ modernization: แทนที่จะรัน Kafka เอง → MSK/Kinesis; รัน Redis เอง → ElastiCache; รัน CI server เอง → CodeBuild. ทุกครั้งที่เลือก managed = ลด ops = ตอบ least operational overhead
2.9 Deployment Patterns ความเสี่ยงต่ำระหว่าง Modernize
หัวข้อที่มีชื่อว่า “2.9 Deployment Patterns ความเสี่ยงต่ำระหว่าง Modernize”การปล่อย version ใหม่ระหว่าง modernize ต้องมี safety net (กลไกเต็มบทที่ 11):
- Blue/Green — ยก environment ใหม่ (green) ขนานกับเดิม (blue) แล้ว switch traffic ทีเดียว; rollback = switch กลับทันที. เหมาะเมื่อต้อง fast rollback และทดสอบ green เต็มก่อน cut
- Canary — ปล่อย traffic ส่วนน้อย (เช่น 5%) ไป version ใหม่ก่อน สังเกต metric/error แล้วค่อยเพิ่ม; auto-rollback ด้วย CloudWatch alarm. เหมาะ validate ในสถานการณ์จริง ก่อน full rollout
- Linear — เพิ่ม traffic เป็นขั้นเท่า ๆ กัน (เช่น +10% ทุก 10 นาที)
ผูกกับ strangler fig: การ route traffic ทีละส่วนจาก monolith ไป microservice ก็คือรูปแบบ canary/weighted ระดับ architecture — ทำได้ผ่าน Route 53 weighted routing (บทที่ 04), ALB weighted target group, หรือ API Gateway canary release
3. ตารางเปรียบเทียบบริการ
หัวข้อที่มีชื่อว่า “3. ตารางเปรียบเทียบบริการ”3.1 Requirement/keyword → modernization pattern
หัวข้อที่มีชื่อว่า “3.1 Requirement/keyword → modernization pattern”| Requirement / keyword ในโจทย์ | Pattern/บริการ | เหตุผล / trade-off |
|---|---|---|
| incrementally decompose monolith, route traffic gradually | Strangler fig (Refactor Spaces) | ลด risk เทียบ big-bang; แลกกับต้องดูแล 2 ระบบพร้อมกันช่วงเปลี่ยนผ่าน |
| rewrite entire application at once | (มัก distractor) big-bang rewrite | เสี่ยงสูง ไม่มี checkpoint — ข้อสอบให้เป็นตัวเลือกผิด |
| containerize existing .NET/Java app, without rewriting | AWS App2Container (A2C) | auto สร้าง image + ECS/EKS artifact; ไม่ต้องแก้ code |
| container + least operational overhead | ECS on Fargate | ไม่มี node ให้จัดการ; ECS control plane เรียบง่ายกว่า EKS |
| container + existing Kubernetes tooling / portability | EKS | k8s API มาตรฐาน; แลกกับ operational complexity สูง |
| spiky/unpredictable, event-driven, pay per use | Lambda + API Gateway + EventBridge | serverless scale-to-zero; แลกกับ 15-min limit + cold start |
| workflow หลาย step + saga + audit | Step Functions | orchestrate + compensating action; state machine ตรวจสอบได้ |
| migrate off SQL Server, minimal code change, cut licensing | Babelfish for Aurora PostgreSQL | app พูด T-SQL ได้ต่อ; แลกกับบาง T-SQL feature ยังไม่รองรับครบ |
| เปลี่ยน engine (Oracle→PostgreSQL), near-zero downtime | SCT + DMS (full load + CDC) | heterogeneous conversion; แลกกับต้อง validate/test query ที่แปลง |
| decouple ingest/process/serve, serverless analytics | Data lake บน S3 + Glue + Athena | scale/จ่ายแต่ละชั้นอิสระ; แลกกับต้องออกแบบ governance (Lake Formation) |
| reduce operational overhead ของ Kafka/Redis/CI ที่รันเอง | managed service (MSK/ElastiCache/CodeBuild) | เลิก heavy lifting; แลกกับ config flexibility น้อยลงบ้าง |
3.2 Migrate-then-modernize vs modernize-first
หัวข้อที่มีชื่อว่า “3.2 Migrate-then-modernize vs modernize-first”| ปัจจัย | Rehost/Relocate ก่อน แล้ว modernize | Refactor ทันที (modernize-first) |
|---|---|---|
| deadline สั้น / วิ่งหนี data center | ✅ เหมาะ (ย้ายเร็วก่อน) | ❌ refactor ช้าเสี่ยง cutover พลาด |
| business driver modernize แรง + มีเวลา | เสีย effort ย้าย 2 รอบ | ✅ เหมาะ (ทำทีเดียวจบ) |
| team skill พร้อม | ไม่จำเป็นต้องพร้อมทันที | ต้องพร้อมสูง |
| risk | ต่ำช่วงย้าย, tackle modernize ทีหลังบน AWS | สูงถ้าทำพร้อมย้าย |
3.3 Container vs Serverless สำหรับ refactor target
หัวข้อที่มีชื่อว่า “3.3 Container vs Serverless สำหรับ refactor target”| มิติ | Container (ECS/EKS/Fargate) | Serverless (Lambda) |
|---|---|---|
| runtime ยาว | ✅ ไม่จำกัดเวลา | ❌ สูงสุด 15 นาที |
| cold start | ไม่มี (warm ตลอด) | มี (ลดด้วย provisioned concurrency) |
| cost ที่ traffic คงที่สูงมาก | มัก ถูกกว่า (+Savings Plans) | per-request อาจแพงกว่า |
| cost ที่ traffic spiky/ต่ำ | จ่าย idle | ✅ scale-to-zero ถูกกว่า |
| operational overhead | ปานกลาง (Fargate ต่ำ) | ✅ ต่ำสุด |
| portability | ✅ สูง (image มาตรฐาน) | ผูก AWS event model |
4. สถาปัตยกรรมตัวอย่างและ trade-off
หัวข้อที่มีชื่อว่า “4. สถาปัตยกรรมตัวอย่างและ trade-off”4.1 E-commerce monolith → microservices ด้วย strangler fig
หัวข้อที่มีชื่อว่า “4.1 E-commerce monolith → microservices ด้วย strangler fig”โจทย์: ร้านค้าออนไลน์รัน monolith Java บน EC2 หลังเดียว deploy ทั้งก้อนทุกครั้ง ทีมโตขึ้นเหยียบเท้ากัน checkout ช่วง flash sale scale ไม่ทัน. ต้องการ incrementally modernize โดยระบบต้องออนไลน์ตลอด
สถาปัตยกรรม:
- วาง API Gateway (หรือ Refactor Spaces proxy) หน้า monolith เป็น facade
- ดึง bounded context ที่ร้อนสุดออกก่อน — Checkout/Cart service เป็น Fargate microservice + DynamoDB (cart) — route path
/checkout/*ไป service ใหม่ ที่เหลือเข้า monolith - ใส่ anti-corruption layer (Lambda) แปลง model ระหว่าง service ใหม่กับ monolith ระหว่างเปลี่ยนผ่าน
- ทยอยดึง Order, Inventory, Payment ออกทีละตัวเป็น service + purpose-built DB ต่อ service; สื่อสารกันผ่าน EventBridge (order placed → inventory decrement)
- เมื่อดึงครบ ปลด monolith
Trade-off: ได้ scale เฉพาะ checkout + deploy อิสระ + resilience (checkout ล้มไม่ล้มทั้งร้าน) แต่แลกกับ operational complexity ของ distributed system (ต้องมี observability/tracing บทที่ 11, จัดการ eventual consistency). ทำไมไม่ big-bang rewrite: ร้านต้องออนไลน์ตลอด + risk สูงเกินรับ
4.2 Legacy .NET app บน Windows → container + เลิก SQL Server license
หัวข้อที่มีชื่อว่า “4.2 Legacy .NET app บน Windows → container + เลิก SQL Server license”โจทย์: enterprise app .NET Framework บน Windows Server + SQL Server, license หนัก, ต้องการลด cost + ops แต่ minimize application code changes และ reduce licensing
สถาปัตยกรรม:
- ใช้ AWS App2Container (A2C) วิเคราะห์ .NET app → สร้าง container image + ECS task definition อัตโนมัติ
- deploy บน ECS Fargate (Windows container) — ไม่ต้องจัดการ node, ไม่ต้อง patch OS เอง
- ย้าย SQL Server → Aurora PostgreSQL + Babelfish — app เดิมพูด T-SQL ต่อได้ผ่าน Babelfish endpoint, แก้ code น้อยสุด, เลิก SQL Server license
- ใช้ SCT assessment ประเมินว่า T-SQL ส่วนไหน Babelfish ยังไม่รองรับ ต้องแก้มือ
Trade-off: ลด license + ops ได้มาก โดยแตะ code น้อย; แลกกับ Babelfish รองรับ T-SQL ไม่ครบ 100% (ต้อง test) และ Windows container ยัง overhead กว่า Linux. ทำไมไม่ refactor เป็น .NET Core + full rewrite: เกิน scope/deadline + business driver คือ cost/license ไม่ใช่ agility
4.3 Batch report monolith → serverless event-driven data pipeline
หัวข้อที่มีชื่อว่า “4.3 Batch report monolith → serverless event-driven data pipeline”โจทย์: ระบบ report รัน cron บน EC2 pull ข้อมูลจากหลาย DB มาประมวลผลรวมเป็นก้อน utilization ต่ำแต่จ่าย 24/7; ต้องการ serverless, decouple, cost-effective
สถาปัตยกรรม:
- Ingest: Kinesis Data Firehose / DMS CDC ส่ง event เข้า S3 data lake
- Process (event-driven): S3 event → Lambda ประมวลผลชิ้นเล็ก; งานหนัก/ยาวใช้ Step Functions orchestrate หลาย Lambda + AWS Glue ETL
- Serve: Athena query S3 ตรง, QuickSight dashboard; ไม่มี server รันตลอด
- Orchestrate schedule: EventBridge Scheduler trigger workflow แทน cron บน EC2
Trade-off: จ่ายเฉพาะตอนรัน (scale-to-zero), decouple แต่ละชั้น scale อิสระ; แลกกับ ต้อง re-architect logic เป็น event-driven และจัดการ orchestration/observability. ทำไมไม่แค่ rehost EC2 cron: ไม่แก้ปัญหา utilization ต่ำ/จ่าย 24/7 ที่เป็น business driver
5. ข้อผิดพลาดที่พบบ่อยในข้อสอบ
หัวข้อที่มีชื่อว่า “5. ข้อผิดพลาดที่พบบ่อยในข้อสอบ”- เลือก big-bang rewrite แทน strangler fig — เมื่อโจทย์บอก “ระบบต้องออนไลน์ตลอด” หรือ “incrementally” การ rewrite ทั้งก้อนคือตัวเลือกผิดเสมอ
- Refactor ทันทีทั้งที่ deadline สั้น — พลาดหลัก “migrate then modernize”; เมื่อมี tight deadline + ต้องออกจาก data center ควร rehost/relocate ก่อน
- Modernize โดยไม่มี business driver — เลือก microservices/serverless เพราะ “ทันสมัย” ทั้งที่โจทย์ไม่มีปัญหา scale/agility จริง = over-engineering (ผิดตามหลักบทที่ 01)
- แตก microservices ตาม technical layer แทน bounded context — ได้ distributed monolith ที่ coupling แน่นกว่าเดิม
- ให้ service หลายตัวแชร์ database เดียว — ละเมิด database-per-service, ทำให้ deploy/scale อิสระไม่ได้; distractor ที่ดูเหมือนประหยัด
- สับสน A2C กับ MGN/DRS — A2C = containerize application (บทนี้); MGN = rehost server ทั้งเครื่อง (บทที่ 12); DRS = DR ต่อเนื่อง (บทที่ 08)
- เลือก EKS ทั้งที่ไม่มีเหตุผลเชิง Kubernetes — เมื่อโจทย์เน้น least operational overhead และไม่ต้องการ k8s API/portability คำตอบคือ Fargate/ECS ไม่ใช่ EKS (over-engineered)
- ยัด long-running/heavy batch ลง Lambda — ลืม 15-min limit; งานยาวต้อง Fargate/EC2/Batch/Step Functions
- เลือก Lambda ที่ traffic สูงคงที่มหาศาลโดยอ้าง cost — ที่ volume สูงมาก container + Savings Plans อาจถูกกว่า per-request Lambda
- คิดว่า Babelfish รองรับ T-SQL 100% — ต้องรัน SCT assessment เสมอเพื่อหา feature ที่ไม่รองรับ; และ Babelfish คือ path ลด code change ไม่ใช่ zero change
- ใช้ DMS โดยไม่ทำ SCT ใน heterogeneous migration — เปลี่ยน engine ต้องแปลง schema ก่อน (บทที่ 07)
- ลืม anti-corruption layer ตอน strangler — ปล่อยให้ model legacy ซึมเข้า service ใหม่จนออกแบบใหม่ก็ยังพันกับของเก่า
- modernize analytics โดยไม่ decouple storage/compute — ยก warehouse ทั้งก้อนขึ้น cloud แทนที่จะแยกเป็น S3 data lake + compute แยกชั้น พลาดประโยชน์หลัก
- จัดการ cross-service transaction ด้วย distributed 2-phase commit — แทนที่จะใช้ saga/event-driven eventual consistency ที่เหมาะกับ microservices
6. คำถามทบทวน
หัวข้อที่มีชื่อว่า “6. คำถามทบทวน”ข้อ 1. บริษัทมี monolith ขนาดใหญ่ที่ต้องการแตกเป็น microservices ทีละส่วนโดยระบบต้องให้บริการต่อเนื่องตลอดกระบวนการ ต้องการ managed infrastructure ที่ช่วย route traffic ระหว่างระบบเดิมกับ service ใหม่ ควรใช้อะไร?
A. เขียน microservices ทั้งหมดใหม่แล้ว cutover ทีเดียว B. AWS Migration Hub Refactor Spaces (strangler fig) C. AWS Application Migration Service (MGN) D. AWS DMS
เฉลย
ตอบ B — Refactor Spaces เป็น infrastructure สำเร็จรูปสำหรับ strangler fig pattern (proxy + routing) ให้ค่อย ๆ route traffic จาก monolith ไป microservice ใหม่ทีละส่วน โดยระบบเดิมยังทำงาน
- A ผิด — big-bang rewrite เสี่ยงสูง ขัด requirement “ให้บริการต่อเนื่อง/ทีละส่วน”
- C ผิด — MGN คือ rehost ย้าย server ทั้งเครื่อง ไม่เกี่ยวกับ decompose microservices (บทที่ 12)
- D ผิด — DMS ย้าย database ไม่ใช่ decompose application
ข้อ 2. บริษัทต้องออกจาก data center ภายใน 3 เดือน และต้องการทำให้ workload ทันสมัยด้วย เป็น microservices ในระยะยาว แนวทางที่เหมาะสมที่สุดคือ?
A. Refactor เป็น microservices ให้เสร็จก่อนย้ายทั้งหมด B. Rehost ด้วย MGN ก่อน แล้วค่อย re-architect เป็น microservices ทีหลังบน AWS C. Retain ไว้ที่ data center ต่อไป D. Repurchase เป็น SaaS ทั้งหมด
เฉลย
ตอบ B — pattern “migrate then modernize”: deadline สั้นทำให้ refactor ทันทีเสี่ยงเกินไป; rehost เร็วเพื่อออกจาก DC ทันเวลา แล้ว modernize บน AWS ที่มี tooling พร้อม
- A ผิด — refactor ใช้เวลานานสุดใน 7 Rs เสี่ยงไม่ทัน 3 เดือน
- C ผิด — ขัด requirement ที่ต้องออกจาก data center
- D ผิด — ไม่มีข้อมูลว่ามี SaaS ทดแทน และ repurchase ทั้ง portfolio ใน 3 เดือนไม่สมจริง
ข้อ 3. ทีมมี application .NET Framework บน Windows ต้องการ containerize โดยไม่แก้ source code และ deploy บน AWS แบบ least operational overhead ควรใช้ชุดเครื่องมือใด?
A. เขียน Dockerfile เองแล้ว deploy บน EKS with EC2 nodes B. AWS App2Container สร้าง image แล้ว deploy บน ECS Fargate C. AWS Elastic Beanstalk D. rehost บน EC2 ด้วย MGN
เฉลย
ตอบ B — A2C วิเคราะห์ .NET/Java app ที่รันอยู่แล้วสร้าง container image + ECS task definition อัตโนมัติ (ไม่ต้องแก้ code); Fargate = least operational overhead (ไม่มี node)
- A ผิด — เขียน Dockerfile เองไม่ least ops และ EKS+EC2 มี operational overhead สูง
- C ผิด — Beanstalk ไม่ใช่ containerization ของ app ที่มีอยู่แบบ automated และไม่ตรง “containerize without rewriting”
- D ผิด — MGN คือ rehost ทั้ง VM ไม่ใช่ containerize
ข้อ 4. องค์กรต้องการย้ายออกจาก Microsoft SQL Server ไป Aurora PostgreSQL เพื่อลด licensing cost โดยแก้ application code ให้น้อยที่สุด ควรใช้อะไร?
A. DMS อย่างเดียว B. Babelfish for Aurora PostgreSQL C. RDS for SQL Server D. DynamoDB
เฉลย
ตอบ B — Babelfish ให้ Aurora PostgreSQL เข้าใจ T-SQL/TDS ทำให้ app เดิมที่พูด SQL Server protocol ต่อได้โดยแก้ code น้อยสุด พร้อมเลิก SQL Server license
- A ผิด — DMS ย้าย data ได้ แต่ไม่ทำให้ app พูด T-SQL กับ PostgreSQL ได้ ต้องแก้ code เยอะ (คู่กับ SCT)
- C ผิด — RDS for SQL Server ยังต้องจ่าย SQL Server license ไม่ตอบ requirement ลด license
- D ผิด — DynamoDB เป็น NoSQL คนละ data model ต้อง re-architect หนัก
ข้อ 5. ระบบ report แบบ batch รันบน EC2 24/7 แต่ใช้งานจริงเพียงวันละไม่กี่ชั่วโมง ต้องการ modernize ให้ cost-effective และ decouple ingest/process/serve ควรออกแบบอย่างไร?
A. เพิ่ม Auto Scaling ให้ EC2 batch B. S3 data lake + Lambda/Glue (event-driven) + Athena, schedule ด้วย EventBridge C. ย้าย EC2 ไป Reserved Instances D. Rehost ทั้ง batch บน Fargate ที่รันตลอด
เฉลย
ตอบ B — serverless event-driven data pipeline: จ่ายเฉพาะตอนรัน (scale-to-zero), decouple storage (S3) จาก compute (Lambda/Glue) จาก serve (Athena) — ตรง requirement ทั้ง cost + decouple
- A ผิด — Auto Scaling ช่วย scale แต่ยังไม่ decouple และยังจ่าย baseline
- C ผิด — RI ลด cost แต่ยังจ่าย 24/7 และไม่ decouple/ไม่ modernize
- D ผิด — Fargate รันตลอดก็ยังจ่าย idle ไม่แก้ปัญหา utilization ต่ำ
ข้อ 6. ทีมกำลังแตก monolith เป็น microservices ควรใช้หลักใดในการกำหนดขอบเขตของแต่ละ service เพื่อหลีกเลี่ยง “distributed monolith”?
A. แตกตาม technical layer (UI/business/data) B. แตกตาม bounded context ของ domain ธุรกิจ พร้อม database-per-service C. แตกตามจำนวนทีมพัฒนา D. ให้ทุก service แชร์ database กลางเพื่อความสอดคล้องของข้อมูล
เฉลย
ตอบ B — bounded context (DDD) แตกตาม domain ที่มีขอบเขตความหมายชัด + database-per-service ทำให้ coupling ต่ำ deploy/scale อิสระ
- A ผิด — แตกตาม layer ทำให้ทุก service ต้องเปลี่ยนพร้อมกันเมื่อ feature เปลี่ยน = coupling สูง
- C ผิด — จำนวนทีมไม่ใช่เกณฑ์ domain boundary
- D ผิด — shared database ทำลายความอิสระ = distributed monolith แบบคลาสสิก
ข้อ 7. application ที่ refactor เป็น microservices ต้องจัดการ business transaction ที่ครอบหลาย service (order → payment → inventory) พร้อม rollback เมื่อ step ใดล้มเหลว ควรใช้ pattern/บริการใด?
A. Distributed two-phase commit ข้ามทุก database B. Saga pattern orchestrate ด้วย AWS Step Functions พร้อม compensating actions C. Lock ทุก table ระหว่าง transaction D. เก็บทุก service กลับเป็น monolith
เฉลย
ตอบ B — Saga pattern จัดการ distributed transaction แบบ eventual consistency; Step Functions orchestrate step + compensating action เมื่อ step ล้มเหลว โดยไม่ต้อง lock ข้าม service
- A ผิด — 2PC ข้าม microservices ทำได้ยาก/เปราะ scale ไม่ดี เป็น anti-pattern
- C ผิด — lock ข้าม service ทำลาย availability และ decoupling
- D ผิด — ย้อนกลับ monolith ไม่ใช่คำตอบ (ทิ้งประโยชน์ที่ได้)
ข้อ 8. โจทย์ระบุ workload ต้องการ container orchestration ที่ใช้ Helm chart และ operator เดิมของทีมได้ พร้อม portability ข้าม environment ควรเลือกอะไร (และเมื่อไหร่ Fargate/ECS ถึงเหมาะกว่า)?
A. ECS on Fargate เสมอ B. Amazon EKS C. Lambda D. Elastic Beanstalk
เฉลย
ตอบ B — requirement ระบุ Kubernetes ecosystem (Helm/operator) + portability ชัด → EKS. Fargate/ECS จะเหมาะกว่าเมื่อโจทย์เน้น least operational overhead และ ไม่มี เหตุผลเชิง k8s (ไม่ต้องการ k8s API/portability)
- A ผิด — ECS ไม่รองรับ Helm/k8s API ไม่ตอบ requirement portability เชิง k8s
- C ผิด — Lambda ไม่ใช่ container orchestration และมีข้อจำกัด runtime
- D ผิด — Beanstalk ไม่ใช่ k8s ecosystem
ข้อ 9. บริษัทต้องการ modernize data warehouse บน-prem ที่ ingest/process/serve ผูกกันแน่น ให้เป็นสถาปัตยกรรมที่ scale แต่ละส่วนอิสระและรองรับ serverless query ควรออกแบบอย่างไร?
A. ยก warehouse ทั้งก้อนขึ้น EC2 ขนาดใหญ่ B. Data lake บน S3 + Glue Data Catalog/Lake Formation + Athena/Redshift Spectrum C. เก็บทุกอย่างใน RDS instance เดียว D. ใช้ DynamoDB เป็น warehouse
เฉลย
ตอบ B — data lake บน S3 decouple storage จาก compute, Glue/Lake Formation จัดการ catalog/governance, Athena = serverless query, Redshift Spectrum query S3 ตรง — scale แต่ละชั้นอิสระ
- A ผิด — ยก monolith ขึ้น EC2 ไม่ decouple ไม่ scale อิสระ (แค่ rehost)
- C ผิด — RDS เดียวไม่ใช่ analytics/OLAP ที่ scale ได้ (บทที่ 07)
- D ผิด — DynamoDB เป็น OLTP key-value ไม่ใช่ analytical warehouse
ข้อ 10. ระหว่าง strangler migration ทีมต้องการปล่อย microservice ใหม่แบบ validate ในสถานการณ์จริงโดยส่ง traffic ส่วนน้อยก่อน และ auto-rollback ถ้า error สูง ควรใช้ deployment pattern ใด?
A. In-place deployment B. Canary deployment พร้อม CloudWatch alarm auto-rollback (หรือ weighted routing) C. Big-bang cutover D. Retain เดิมไว้ตลอด
เฉลย
ตอบ B — canary ส่ง traffic ส่วนน้อยไป version ใหม่ก่อน สังเกต metric แล้วค่อยเพิ่ม; ผูก CloudWatch alarm auto-rollback (บทที่ 11); ระดับ architecture ทำผ่าน Route 53/ALB weighted routing
- A ผิด — in-place ไม่มี traffic split/ค่อย ๆ validate เสี่ยงกระทบทั้งหมด
- C ผิด — big-bang cutover ขัดหลัก low-risk incremental
- D ผิด — retain ไม่ใช่ deployment ของ version ใหม่
7. Cross-references
หัวข้อที่มีชื่อว่า “7. Cross-references”- บทที่ 01 — หลัก over-engineering/keyword: least operational overhead, cost-effective ที่ใช้ตัด distractor ในการเลือก modernize/ไม่ modernize; mindset “อย่าทำเกินจำเป็น”
- บทที่ 05 — compute/integration primitive ที่บทนี้ประกอบเป็น pattern: ECS/EKS/Fargate/Lambda, SQS/SNS/EventBridge/Step Functions, API Gateway/AppSync (บทนี้ต่อยอดเชิง refactor target)
- บทที่ 06 — S3 durability/storage class เป็นฐานของ data lake; DataSync/Kinesis สำหรับ ingest
- บทที่ 07 — database engine detail: Aurora architecture, Babelfish, DMS full load+CDC, SCT, purpose-built philosophy, DynamoDB/Redshift/Athena/Glue (บทนี้ใช้ในบริบท decompose/re-engine)
- บทที่ 08 — DRS (DR ต่อเนื่อง) เทียบกับ A2C/MGN; resilience ที่ได้จาก fault isolation ของ microservices
- บทที่ 11 — IaC/CI-CD, deployment strategies (blue/green, canary, linear + auto-rollback), observability/tracing ที่จำเป็นสำหรับ distributed microservices
- บทที่ 12 — migration mechanics: 7 Rs (Refactor เป็น 1 ใน 7), MGN vs A2C vs DRS, Refactor Spaces (บทนี้ลงลึก strangler), “migrate then modernize”
- บทที่ 14 — บทสังเคราะห์จะรวม decision framework เลือก compute/database/modernization path ข้าม domain
สรุปแกนตัดสินใจของบทนี้ (นำไปใช้ต่อบทที่ 14): (1) modernize ต่อเมื่อมี business driver ชัด — ไม่งั้นอย่าทำ; (2) monolith → microservices ใช้ strangler fig ไม่ใช่ big-bang, แตกตาม bounded context + database-per-service; (3) containerize ด้วย A2C, เลือก orchestration ตามแกนบทที่ 05 (Fargate=least ops, EKS=k8s portability); (4) serverless เหมาะ spiky/event-driven ไม่เหมาะ long-running/steady-high-volume; (5) database modernize ผ่าน Babelfish (ลด SQL Server license/code change) หรือ SCT+DMS (re-engine); (6) analytics modernize = data lake บน S3 decouple ingest/process/serve; (7) deadline สั้น → migrate then modernize