Skip to content

บทที่ 6 — Cloud Platforms + IaC

← บทที่ 5 | สารบัญ | บทที่ 7 →

TL;DR: บทนี้ตอบ 2 คำถามหลัก — "เลือก cloud เจ้าไหน" และ "เขียนโครงสร้างพื้นฐานเป็นโค้ดยังไง"

  • เปรียบเทียบ AWS / GCP / Azure พร้อมหลักช่วยตัดสินใจ
  • รู้จักรูปแบบบริการ (IaaS → FaaS = ดูแลเองทั้งเครื่อง → ดูแลแค่ฟังก์ชัน)
  • ใช้ Terraform / OpenTofu ตั้งแต่ resource แรกจนถึง module
  • พื้นฐานเรื่องลดค่าใช้จ่ายและความปลอดภัย

ข้ามได้ถ้า: ใช้ Terraform คล่อง + รู้ข้อดี-ข้อเสียของ cloud แต่ละเจ้าแล้ว

หลังจบบท คุณจะ:

  • เปรียบเทียบ AWS / GCP / Azure / others — เลือกได้มีเหตุผล ไม่ใช่ตาม trend
  • เลือก service ตาม use case (มี decision rubric ให้)
  • ใช้ Terraform / OpenTofu เขียน infrastructure
  • เข้าใจ cost optimization
  • รู้ pattern ของ cloud architecture

📖 เส้นทางอ่านแนะนำ (บท 6 ยาว 1500+ บรรทัด)

🟢 เส้นทางเริ่มต้น (อ่านก่อน): 0 → 1 → 2 → 3 → 7 (Heroku/Render) → 8 (Free Tier) → 10 (Terraform Basics) → 27 (Checkpoint)

🟡 หลังจับหลักได้แล้ว: 4 (Core Services) → 5 (AWS CLI) → 9 (IaC) → 11–13 (Variables/Outputs/Modules) → 20 (Cost) → 21 (Security)

🔴 ขั้นสูง (ข้ามได้ก่อน): 14 (Full Stack Example) → 15–16 (Best Practices/Patterns) → 23 (Multi-Cloud) → 25 (Real-World Cost)


0. Prerequisites + Decision Framework

คุณควรรู้:

  • ✅ Linux + SSH (บทที่ 1)
  • ✅ Docker (บทที่ 3) — เพราะ deploy ส่วนใหญ่เป็น container
  • ❌ ไม่ต้องเคยมี cloud account — เริ่ม free tier ในบทนี้

ก่อนเลือก cloud — ถามตัวเอง 4 ข้อ

text
1. ทีมรู้ stack อะไรอยู่แล้ว?
   → ถ้าทีมใช้เทคโนโลยี Microsoft เป็นหลัก (.NET, Windows Server, AD)
       → Azure (เชื่อมต่อกันได้ดีกว่า)
   → ถ้าใช้ Google Workspace + งาน ML/Data → GCP

2. Project ขนาดไหน?
   → MVP / side project → Render, Railway, Fly.io ($5-25/เดือน)
   → Startup กำลังโต → ใช้ cloud หลักเจ้าเดียว (AWS/GCP)
   → Enterprise → ต้องคิดเรื่อง multi-region + compliance ด้วย

3. คุณ deploy แบบไหน?
   → Function/API → Lambda, Cloud Run (ถูกสุด, scale ลงเหลือ 0 ได้)
   → Container → ECS Fargate, Cloud Run (ไม่ต้องจัดการเครื่อง node เอง)
   → Kubernetes → EKS/GKE/AKS (ถ้ามีคนคอยดูแล cluster)

4. งบประมาณเท่าไหร่?
   → < $50/เดือน → DigitalOcean, Hetzner, Vercel free tier
   → $50-500/เดือน → AWS/GCP free tier + เครื่องเล็ก
   → $500+/เดือน → เริ่มจริงจังเรื่อง optimization (Reserved/Savings Plan)

1. Why Cloud

ก่อนจะเลือก cloud เจ้าไหน ต้องเข้าใจก่อนว่าทำไมโลกถึงย้ายจาก "ซื้อเซิร์ฟเวอร์ตั้งเอง" (on-premise) มาเป็น cloud หัวใจมี 4 ข้อ:

  • จ่ายตามใช้จริง
  • สร้างได้ในไม่กี่นาที
  • scale อัตโนมัติ
  • มี managed service (บริการที่ cloud ดูแลระบบหลังบ้านให้ เช่น patch, backup, scaling — เราไม่ต้องดูแลเอง) ให้ใช้

ลองเทียบสองโลกนี้:

text
On-premise (ซื้อเซิร์ฟเวอร์ตั้งเอง):    Cloud:
- ซื้อเซิร์ฟเวอร์ ($$$)               - จ่ายตามใช้จริง
- ตั้ง datacenter เอง                  - สร้างได้ในไม่กี่นาที
- scale ต้องทำมือ                       - scale อัตโนมัติ
- ต้องมีทีม IT ดูแล                     - มี managed service ให้
- ความจุตายตัว                          - ยืดหดได้ (elastic)

ปี 2026 — 95% startup ใช้ cloud


2. Big 3 + Others

ตลาด cloud มีเจ้าใหญ่ 3 ราย (AWS, GCP, Azure) ที่ครองส่วนแบ่งส่วนใหญ่ แต่ละเจ้าเด่นคนละด้าน บวกกับผู้เล่นเล็กที่เรียบง่าย/ถูกกว่าสำหรับงานบางแบบ (DigitalOcean, Hetzner, Vercel, Fly.io) มารู้จักจุดแข็งของแต่ละเจ้าเพื่อเลือกให้เหมาะกับงาน:

AWS (Amazon Web Services) ⭐ ผู้นำตลาด

  • มีบริการเยอะที่สุด (200+ services)
  • เอกสารเยอะที่สุด, ชุมชนใหญ่ที่สุด
  • navigate ยาก (เมนูเยอะ, ชื่อบริการเยอะ)

GCP (Google Cloud Platform)

  • เหมาะกับงาน data / ML ที่สุด
  • Kubernetes (GKE) ทำได้ดีที่สุด — Google คือคนสร้าง K8s
  • เป็นมิตรกับนักพัฒนา (developer-friendly)

Azure (Microsoft)

  • เหมาะกับ enterprise ที่ใช้ Windows / .NET
  • Identity แข็งแรง (AAD = Azure Active Directory — ระบบจัดการ user/สิทธิ์ขององค์กร)
  • เชื่อมกับ Office 365 / Microsoft 365 ได้ดี

Others

  • DigitalOcean — เรียบง่าย + ราคาถูก (เน้นนักพัฒนา)
  • Hetzner — ถูกที่สุด (เซิร์ฟเวอร์อยู่ในเยอรมัน, เหมาะกับ EU)
  • Linode (Akamai) — VPS แบบง่าย ๆ
  • Vercel — hosting สำหรับเว็บฝั่ง frontend
  • Render / Railway — แนวเดียวกับ Heroku, deploy ง่าย
  • Fly.io — deploy แบบ edge (กระจายไปหลายเมืองทั่วโลก)
  • CloudflareCDN + Workers (รันโค้ดที่ edge)

3. Cloud Service Models

cloud ให้บริการหลาย "ระดับ" ตามว่าคุณอยากดูแลเองแค่ไหน — IaaS (จัดการ OS+app เอง), PaaS (จัดการแค่ app), SaaS (ใช้บริการสำเร็จรูป), FaaS (อัปแค่ฟังก์ชัน) ยิ่งลงล่างยิ่งสบายแต่ยืดหยุ่นน้อยลง

อุปมา "pizza as a service" ช่วยให้เห็นภาพว่าแต่ละ model ดูแลอะไรเอง/ปล่อยให้ cloud จัดการ:

ทำพิซซ่ากินเอง (On-premise)ซื้อแป้ง+ส่วนผสมสำเร็จ (IaaS)สั่ง Delivery มาบ้าน (PaaS)ไปกินที่ร้าน (SaaS)
คุณดูแลทุกอย่าง — แป้ง, เตา, เสิร์ฟapp + OS (เช่าแค่ VM)แค่ app ของคุณเองแค่ใช้งาน
cloud ดูแลhardware + networkhardware + OS + runtimeทุกอย่าง
ตัวอย่างServer ในออฟฟิศEC2, Compute EngineApp Engine, HerokuGmail, Notion

ลองดูสเปกตรัมนี้:

text
On-premise (ตั้งเอง):  ดูแลทุกอย่างเอง

IaaS:         ดูแล app + OS (เช่าแค่ VM)         ← EC2, Compute Engine

PaaS:         ดูแลแค่ app                        ← App Engine, Heroku

SaaS:         ใช้บริการสำเร็จรูป                  ← Gmail, Notion

Function/FaaS: อัปโหลดแค่ฟังก์ชัน                 ← Lambda, Cloud Functions

4. Core Services (AWS focus)

cloud แต่ละเจ้ามีบริการเป็นร้อย แต่จริง ๆ แล้วจัดกลุ่มได้ไม่กี่หมวด: compute (รันโค้ด), storage (เก็บไฟล์), database, network, identity/security และ messaging ตารางเทียบนี้ช่วยให้เห็นว่าบริการชื่อต่างกันของ AWS/GCP/Azure จริง ๆ คือของแบบเดียวกัน — รู้หมวดเดียวก็ย้าย cloud ได้

💡 คำย่อที่จะเจอบ่อยในตารางข้างล่าง

  • EC2 (Elastic Compute Cloud) = เครื่อง VM ของ AWS
  • ECS (Elastic Container Service) = service รัน Docker container ของ AWS (AWS เป็นคนจัดการ)
  • EKS (Elastic Kubernetes Service) = บริการ Kubernetes managed ของ AWS
  • GKE / AKS = ฝั่ง GCP / Azure ของ EKS
  • EBS (Elastic Block Store) = ดิสก์ผูกติด VM (เหมือน SSD ในเครื่อง)
  • EFS (Elastic File System) = ที่เก็บไฟล์ที่ mount แชร์หลายเครื่องได้
  • S3 (Simple Storage Service) = ที่เก็บไฟล์แบบ object (รูป, video, backup)
  • VPC (Virtual Private Cloud) = network ส่วนตัวของคุณใน cloud (เหมือน LAN ออฟฟิศ แต่อยู่บน cloud)
  • ALB / NLB = Application / Network Load Balancer — กระจาย traffic เข้าหลายเครื่อง (ALB เข้าใจ HTTP, NLB เร็วระดับ TCP)
  • KMS (Key Management Service) = ที่เก็บกุญแจเข้ารหัส
  • CDN (Content Delivery Network) = เครือข่าย cache เนื้อหาตามจุดต่าง ๆ ใกล้ผู้ใช้

Compute (รันโค้ด/แอปพลิเคชัน)

AWSGCPAzure
VM (เครื่องเสมือน)EC2Compute EngineVM
ContainerECS, EKSGKE, Cloud RunAKS, Container Apps
Serverless (ฟังก์ชัน)LambdaCloud Functions, Cloud RunFunctions
Static (เว็บนิ่ง)S3 + CloudFrontCloud Storage + CDNBlob + CDN

💡 2026 มาแรง: ARM Graviton (ของ AWS) — CPU แบบ ARM ของ AWS ราคาถูกกว่า x86 ราว 20-40% (instance ลงท้าย g เช่น t4g, m7g, c7g). EKS Auto Mode (เปิด 2024) — AWS ดูแลเรื่อง node ให้หมด, ใช้ Karpenter (CNCF graduated — ผ่านมาตรฐานความสำเร็จระดับสูงสุดของ Cloud Native Computing Foundation จึงเชื่อถือได้ว่าโปรเจกต์เสถียร) ขยาย node ตามภาระงานอัตโนมัติ

Storage (เก็บข้อมูล/ไฟล์)

AWSGCPAzure
Object storage (ไฟล์รวม metadata)S3Cloud StorageBlob
Block (ดิสก์ผูก VM)EBSPersistent DiskManaged Disk
File (mount แชร์ระหว่างเครื่อง)EFSFilestoreFiles
Archive (เก็บนาน, ดึงช้า, ถูกมาก)GlacierColdlineArchive

Database

AWSGCPAzureคำอธิบาย
Relational (SQL)RDS, AuroraCloud SQL, SpannerSQL DBDB แบบ SQL ปกติ — RDS/Cloud SQL = MySQL/Postgres managed; Aurora/Spanner = engine เร็วขึ้น/scale ได้ดีขึ้น
NoSQLDynamoDBFirestore, BigtableCosmos DBkey-value / document DB ที่ scale ใหญ่มาก ๆ ได้
CacheElastiCacheMemorystoreCache for RedisRedis/Memcached managed สำหรับ cache ในแอป
SearchOpenSearch(managed Elasticsearch)SearchElasticsearch managed สำหรับค้นหา full-text
Data Warehouse (analytics)RedshiftBigQuery ⭐Synapseฐานข้อมูลขนาดใหญ่สำหรับ analytics + BI

Network

AWSGCPAzureคำอธิบาย
Virtual NetworkVPCVPCVNetเครือข่ายส่วนตัวของคุณบน cloud (กั้นแยกจากคนอื่น)
Load BalancerALB / NLBCloud Load BalancingLBกระจาย traffic เข้าหลายเครื่อง (ALB ฝั่ง AWS เป็น HTTP, NLB เป็น TCP; Classic ELB เลิกใช้สำหรับโปรเจกต์ใหม่)
DNSRoute 53Cloud DNSDNSระบบจำเส้นทางจากชื่อเว็บไป IP
CDNCloudFrontCloud CDNCDNcache เนื้อหาที่ edge ใกล้ผู้ใช้ทั่วโลก

Identity + Security

AWSGCPAzureคำอธิบาย
IAM (ระบบสิทธิ์)IAMIAMAAD (Azure AD / Entra ID)กำหนดว่า user/service ทำอะไรได้บ้าง
Secrets (เก็บความลับ)Secrets ManagerSecret ManagerKey Vaultเก็บ password / API key / cert
KMS (Key Management Service)KMSCloud KMSKey Vaultจัดเก็บ + หมุนกุญแจเข้ารหัส

💡 เพิ่มเติม 2026 (AWS): GuardDuty = ระบบตรวจจับภัยอัตโนมัติจาก log; Security Hub = dashboard รวม finding ความปลอดภัย; IAM Access Analyzer = หา policy ที่เปิดสิทธิ์เกินจำเป็น; AWS Config = ตรวจสอบ config drift; Trusted Advisor = check best practices

Messaging (ส่งข้อความระหว่างระบบ)

AWSGCPAzureคำอธิบาย
QueueSQSCloud Tasks, Pub/SubQueue Storageคิวข้อความแบบเข้าก่อนออกก่อน
Pub/SubSNSPub/SubEvent Gridกระจายข้อความให้ subscriber หลายตัว
StreamKinesisPub/Sub, DataflowEvent Hubsสตรีมข้อมูลความเร็วสูง (เช่น log, IoT)

5. AWS Common Services — Brief

💡 AWS CLI Setup ใน 5 นาที (ถ้าจะลอง command ในข้อนี้):

Prerequisite: ต้องมี AWS account แล้ว (ผูกบัตรเครดิต + verify ตัวตนทาง SMS / โทรกลับ ตอนสมัคร — ใช้เวลาประมาณ 10-15 นาที)

สำคัญ: ตั้ง billing alert ที่ $10 ทันทีหลังเปิด account เพื่อไม่ให้ค่าใช้จ่ายระเบิด

bash
# 1. ติดตั้ง AWS CLI v2
# macOS:   brew install awscli
# Linux:   ทำตามคู่มืออัปเดตที่ https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
# Windows: winget install Amazon.AWSCLI

# 2. ⭐ แนะนำสำหรับปี 2026: ใช้ IAM Identity Center (SSO) แทน access key
#    aws configure sso  → login ผ่าน browser, credential หมดอายุอัตโนมัติ
#    AWS เลิกแนะนำ static access key สำหรับมนุษย์ใช้งานตั้งแต่ปี 2023
#
#    ถ้าจำเป็นต้องใช้ access key (เช่นในระบบ CI ที่ตั้ง SSO ไม่ได้):
#    IAM → Users → Security credentials → Create access key
#    ⚠️ ห้ามใช้ root account — สร้าง IAM user แยกที่มีสิทธิ์น้อยที่สุดที่จำเป็น

# 3. ตั้งค่า credential
aws configure
#   AWS Access Key ID:     AKIA...
#   AWS Secret Access Key: ...
#   Default region name:   ap-southeast-1   (Singapore — region ที่ใกล้ไทยสุดและใช้งานได้แน่นอน)
#                          ⚠️ AWS อาจเปิด region ใหม่ในไทย/ใกล้ไทยเพิ่มในอนาคต —
#                             เช็ค region code ล่าสุดที่ https://aws.amazon.com/about-aws/global-infrastructure/regions_az/
#                             ก่อนใช้จริงเสมอ (อย่าเชื่อ region code ที่เห็นในหนังสือ/บทความเก่าเพียงอย่างเดียว)
#   Default output format: json

# 4. ทดสอบ
aws sts get-caller-identity
#   → คืนค่า account id + arn ของ user → พร้อมใช้

สรุปวิธีปลอดภัย (2026): SSO > IAM role (กรณีรันบน EC2/ECS) >> static access key (หลีกเลี่ยง)

EC2 (VM)

bash
# สั่งสร้างเครื่อง
aws ec2 run-instances \
    --image-id ami-xxx \         # AMI ID — ไปเลือกจาก AWS Console > EC2 > AMI Catalog (เช่น Ubuntu/Amazon Linux)
    --instance-type t3.micro \
    --key-name my-key \          # SSH key ที่สร้างไว้แล้วใน EC2 > Key Pairs
    --security-group-ids sg-xxx  # security group (firewall) ที่สร้างไว้แล้ว

Instance types — cloud แบ่งขนาด VM เป็น "ตระกูล" (family) ที่ optimize ให้เหมาะกับงานต่างกัน (เน้น CPU / เน้น RAM / สมดุลทั้งคู่) ถ้ายังไม่รู้จะเลือกอะไร เริ่มจาก general-purpose หรือ burstable ก่อนได้เลย ค่อยเปลี่ยนทีหลังเมื่อรู้ว่างานหนักด้านไหน (กลุ่มแรกที่ควรรู้):

  • t3.micro — แบบ burstable (ปกติ CPU ต่ำ แต่พุ่งแรงได้ชั่วครู่เวลามีงานเข้า เหมาะเว็บทั่วไปที่ traffic ไม่สม่ำเสมอ), ราคาถูก, อยู่ใน free tier
  • t3.medium — general purpose ใช้ทั่วไป
  • m5.large — balanced (CPU/RAM สมดุล) สำหรับ workload กลาง
  • c5.large — compute optimized (CPU แรง) เหมาะกับงานคำนวณ
  • r5.large — memory optimized (RAM เยอะ) เหมาะกับ in-memory cache / DB

💡 ARM Graviton — ถูกกว่า 20-40%: instance ลงท้าย g (เช่น t4g.micro, m7g.large, c7g.large, r7g.large) ใช้ CPU แบบ ARM ของ AWS เอง ราคาประหยัดกว่า x86 มาก ปี 2026 software ส่วนใหญ่ (Java, Node, Go, Python, Postgres, Redis, Nginx) รองรับ ARM แล้ว — default ใหม่ของโปรเจกต์ใหม่ควรเป็น Graviton

S3 (Object Storage)

bash
# อัปโหลด
aws s3 cp file.txt s3://my-bucket/
aws s3 sync ./folder s3://my-bucket/folder   # sync ทั้ง folder

# ดาวน์โหลด
aws s3 cp s3://my-bucket/file.txt .

# เปิดเป็นเว็บ (static website hosting)
aws s3 website s3://my-bucket --index-document index.html

⚠️ เรื่องสำคัญเรื่องเว็บ static บน S3

  1. ตั้งแต่เมษายน 2023 AWS เปิด S3 Block Public Access ให้ทุก bucket ใหม่โดยอัตโนมัติ — ถ้าจะ host เว็บ public ต้องไป ปิด Block Public Access แค่บาง bit ที่จำเป็น + เพิ่ม bucket policy ที่อนุญาตเฉพาะ s3:GetObject
  2. อย่าปิดทั้งหมด — เพราะจะกลายเป็น bucket เปิดทั้ง bucket (ข่าว data leak ส่วนใหญ่มาจากตรงนี้)
  3. ทางที่ปลอดภัยกว่า = วาง CloudFront ทับและให้ S3 bucket เป็น private โดย access ผ่าน Origin Access Control (OAC — กลไกให้ CloudFront เข้าถึง S3 private ได้โดยไม่ต้องเปิด public)

ใช้สำหรับ:

  • ที่เก็บไฟล์ user upload (รูป, video, attachment)
  • โฮสต์เว็บแบบ static (HTML/CSS/JS)
  • backup ข้อมูล
  • Data lake (ที่เก็บข้อมูลดิบสำหรับ analytics)

RDS (Managed Database)

text
RDS PostgreSQL:
  - Multi-AZ (กระจายข้าม availability zone) เพื่อ HA (high availability — ระบบไม่ล่มเวลา zone หนึ่งมีปัญหา)
  - Backup อัตโนมัติทุกวัน
  - เข้ารหัสตอนเก็บ (encryption at rest) — ต้องเปิดตอนสร้าง เปลี่ยนทีหลังไม่ได้
  - Read replica — สร้างสำเนาอ่านอย่างเดียวกระจายภาระ query
  - Failover อัตโนมัติ — สลับไป AZ สำรองเมื่อ primary ล่ม

💡 AZ (Availability Zone) = data center ย่อยภายใน region เดียวกัน แยกตัวอาคาร/ระบบไฟ/network เพื่อกัน fault — region หนึ่งมัก มี 3 AZ ขึ้นไป

💡 2026 ทางเลือกใหม่: Aurora Serverless v2 — Postgres/MySQL compatible ที่ scale CPU/RAM อัตโนมัติเป็นวินาที จ่ายตามใช้จริง เหมาะกับ workload ที่ traffic ไม่สม่ำเสมอ

→ จ่ายแพงกว่ารัน DB เองนิดหน่อย แต่ไม่ต้องดูแล backup / patch / failover เอง

Lambda (Serverless Function)

python
# lambda_function.py
def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': 'Hello'
    }
bash
# Deploy
zip function.zip lambda_function.py
aws lambda create-function \
    --function-name hello \
    --runtime python3.13 \                # ปี 2026 รองรับถึง 3.13 (เลือก runtime ใหม่ล่าสุดที่ stable)
    --architectures arm64 \               # ⭐ ARM Graviton — ถูกกว่า x86 ~20%
    --handler lambda_function.lambda_handler \
    --zip-file fileb://function.zip \
    --role arn:aws:iam::<account-id>:role/lambda-execution-role
    # ⚠️ --role ต้องใส่เสมอ — เป็น IAM role ที่ Lambda ใช้รันฟังก์ชัน (สร้างล่วงหน้าไว้ก่อน
    #   คล้าย pattern IAM role ในหัวข้อ 21 ด้านล่าง) ถ้าไม่ใส่ AWS จะ error ทันที

Pricing:

  • Free tier: 1M req/เดือน (ไม่หมดอายุ — always free)
  • $0.20 / 1M req + ค่า compute ตามเวลารัน

ใช้สำหรับ:

  • API endpoint (ผ่าน API Gateway / Function URL)
  • Event handler — เช่น มีไฟล์อัปขึ้น S3 → trigger ฟังก์ชันมา process
  • Scheduled task — งาน cron ที่รันตามเวลา
  • Webhook — รับ event จาก external service

CloudFront (CDN)

text
ผู้ใช้ → CloudFront edge → S3 / EC2 / ALB (Application Load Balancer)
        (cache ไว้, อยู่ใกล้ผู้ใช้)

→ กระจาย static asset ทั่วโลก + ป้องกัน DDoS เบื้องต้น


6. Choosing Compute Service

มีบริการ compute เยอะจนเลือกไม่ถูก? ใช้คำถามไล่ทีละขั้น — มี container ไหม? ต้องการ Kubernetes เต็มรูปแบบไหม? อยากคุม config มากแค่ไหน? — flowchart นี้พาคุณไปยังตัวเลือกที่เหมาะ พร้อมเทียบราคาคร่าว ๆ ของแต่ละแบบ:

Pricing (ราคาคร่าว ๆ — ถูก → แพง)

text
$$$$  EC2 + EKS (control plane) + เครื่องมือเสริม — แพงสุด, ต้องดูแล cluster
$$$   ECS, ALB, NLB (Application/Network Load Balancer)
$$    Cloud Run, Azure App Service
$     Lambda, Cloud Functions (จ่ายต่อ request)

7. Heroku / Render / Railway — Easiest Path

ถ้าเพิ่งเริ่มหรือทำโปรเจกต์เล็ก/MVP ไม่ต้องปวดหัวกับ AWS — platform แบบ Heroku/Render/Railway ซ่อนความซับซ้อนทั้งหมดไว้ แค่ต่อ GitHub หรือ push code มันก็ deploy ให้เลย ค่าใช้จ่ายไม่กี่ดอลลาร์ต่อเดือน เหมาะกับการเริ่มต้นที่สุด:

สำหรับโปรเจกต์เล็ก:

bash
# Heroku (เลิก free tier ตั้งแต่ พ.ย. 2022 — เริ่มที่ ~$5/เดือน)
heroku create my-app
git push heroku main
# deploy เสร็จเรียบร้อย

# Render
# วิธีใช้: เชื่อม GitHub repo → push code → deploy อัตโนมัติ

# Railway
railway up

ราคา: $5-25/เดือนสำหรับแอปเล็ก

→ เหมาะกับมือใหม่ + MVP (Minimum Viable Product = เวอร์ชันแรกที่ใช้ได้)


8. AWS Free Tier

ข่าวดีสำหรับคนอยากลองของจริงโดยไม่เสียเงิน — AWS มี free tier ให้ลองของจริงโดยไม่เสียเงินตอนเริ่ม ⚠️ ตั้ง billing alert เสมอ เพราะถ้าเผลอใช้เกินโควต้าจะโดนเก็บเงินทันที

⚠️ AWS เปลี่ยนโครงสร้าง Free Tier เดือนกรกฎาคม 2024

มี 2 โครงสร้างที่ต่างกัน — เช็คก่อนว่าบัญชีตัวเองอยู่ที่ไหน:

บัญชีก่อน Jul 2024 ("Legacy Free Tier") — 12 months free + always-free:

  • 750 hr/month EC2 t2.micro / t3.micro
  • 5 GB S3
  • 750 hr RDS db.t2.micro / db.t3.micro
  • 1M Lambda req (always-free)
  • 100k SNS, 750 hr ELB
  • ใช้ใหม่ทุกบริการได้ทั้ง 12 เดือน

บัญชีหลัง Jul 2024 ("Free Plan") — แบ่ง 2 ขั้น:

  • 6 เดือนแรก: $200 credit (free + ใช้กับบริการอะไรก็ได้)
  • หลัง 6 เดือน: ต้อง upgrade เป็น paid account (จ่ายตามใช้จริงตามราคาปกติ) — ถ้าไม่ upgrade บัญชีจะถูกปิด
  • กลไกป้องกัน: ถ้า credit หมดก่อนครบ 6 เดือน บัญชีจะถูก "paused" อัตโนมัติ — resource ทั้งหมดถูกหยุดและจะถูกลบหลังผ่านไป 90 วันถ้าไม่ upgrade (จึงควร backup ของสำคัญไว้ก่อน)
  • ดู AWS Free Plan announcement

⚠️ ข้อมูล Free Tier อ้างอิงจากประกาศ AWS เดือนกรกฎาคม 2024 — ตรวจสอบ terms ล่าสุดที่ https://aws.amazon.com/free/ ก่อนเสมอ เพราะ AWS เปลี่ยน free tier บ่อยและรายละเอียดอาจแตกต่างตาม region หรือช่วงเวลา

→ ปัจจุบัน (ปี 2026) บัญชีใหม่ทั้งหมดเข้า Free Plan — ลองเล่นได้ 6 เดือนเต็มที่ ไม่ต้องกังวล bill ระเบิด

⚠️ ทั้งสองโครงสร้าง: ตั้ง billing alert ($10/$100/$1000) — กันความเข้าใจผิดเรื่อง quota


9. Infrastructure as Code (IaC)

การคลิกสร้าง resource ใน console ทีละอันมีปัญหาหลายอย่าง เช่น ทำซ้ำไม่ได้ ไม่มี version control และแต่ละ environment เพี้ยนกัน (drift)

IaC แก้ปัญหานี้ด้วยการเขียน infrastructure เป็น "โค้ด" — โค้ดนี้ Git เก็บประวัติได้ รันแล้วได้ผลเหมือนเดิมทุกครั้ง และทำลาย/สร้างใหม่ได้ ลองเทียบสองวิธี:

text
คลิกสร้างใน console (manual):
- ทำซ้ำไม่ได้ (ไม่รู้กดอะไรไปบ้าง)
- ไม่มี version control
- แต่ละ environment เพี้ยนกัน (drift)
- คนใหม่ onboarding ลำบาก ต้องสอนปากต่อปาก

IaC (Terraform ฯลฯ):
- โค้ดคือ source of truth (แหล่งความจริงเดียว)
- เก็บประวัติใน Git ได้
- โค้ดเดียวกัน → infra เหมือนเดิมทุกครั้ง
- ทำลายและสร้างใหม่ได้ (disposable + recreatable)

9.5 Terraform vs OpenTofu — เรื่องที่ต้องรู้ปี 2026

สิงหาคม 2023 — HashiCorp เปลี่ยน license ของ Terraform จาก open source (MPL) เป็น BSL (Business Source License) → ห้าม vendor อื่นเอาไปทำเป็น product แข่ง

💡 MPL (Mozilla Public License) = license แบบ open source ที่ให้ใช้/แก้/ขายต่อได้ค่อนข้างเสรี ส่วน BSL เข้มกว่า — ใช้ฟรีได้แต่ห้ามเอาไปทำบริการแข่งกับเจ้าของ

ผลที่เกิด: community fork ออกมาเป็น OpenTofu (อยู่ใต้ Linux Foundation, license MPL เดิม) — release v1.7 stable เดือนพฤษภาคม 2024, ตามด้วย v1.8 (สิงหาคม 2024), v1.9 (ม.ค. 2025), v1.10+ (เพิ่ม S3 native locking)

💡 HCL (HashiCorp Configuration Language) = ภาษาที่ใช้เขียน Terraform — มี syntax คล้าย JSON ผสม INI อ่านง่าย

TerraformOpenTofu
License (สัญญาอนุญาต)BSL (จำกัดการนำไปใช้เชิงพาณิชย์)MPL (open source แท้ ใช้ฟรี)
ความเข้ากันได้ใช้แทน Terraform ได้ทันที (binary drop-in)
HCL syntaxเหมือนกันเหมือนกัน (อิง HCL v1.5)
State formatเหมือนกันเหมือนกัน
Provider ecosystemhashicorp registryOpenTofu registry + ใช้ของ Terraform ได้
คนหนุนหลังHashiCorp (ตอนนี้อยู่ใน IBM)Linux Foundation
การนำไปใช้ปี 2026ยังนิยมGruntwork, GitHub, Cisco และอีกหลายเจ้าหันมาใช้/แนะนำ

คำแนะนำปี 2026:

  • Project ใหม่ / personal → ใช้ OpenTofu (free, no vendor lock)
  • Project เดิม / enterprise มี HashiCorp Cloud → ใช้ Terraform ต่อได้
  • ทั้ง 2 = command tofu หรือ terraform แทนกันได้ (CLI compatible)

หนังสือเล่มนี้ใช้ command terraform แต่ทุกอย่าง work กับ tofu เช่นกัน


10. Terraform Basics

Terraform คือเครื่องมือ IaC ยอดนิยมที่สุด — เขียนภาษา HCL บอกว่าอยากได้ resource อะไร แล้วมันจัดการสร้างให้ตรงตามนั้น ตัวอย่างแรกนี้คือโครง main.tf ที่ประกาศ provider (AWS) และ backend สำหรับเก็บ state ซึ่งเป็นจุดเริ่มของทุกโปรเจกต์ Terraform:

📌 Prerequisite ของ backend "s3" (chicken-and-egg ที่งงบ่อย): bucket my-terraform-state และตาราง DynamoDB ที่ใช้ lock ต้องสร้างด้วยมือผ่าน AWS Console (หรือ CLI) ก่อน — เพราะ Terraform เองยังไม่ทำงานจนกว่าจะมี backend ที่ใช้ได้ พอสร้างเสร็จแล้วค่อย terraform init แล้วใช้ต่อไปได้เลย

⚠️ ต้องมีสิทธิ์ s3:CreateBucket / s3:PutBucketVersioning และ dynamodb:CreateTable บน IAM user/role ที่ใช้รันคำสั่งด้วย และชื่อ bucket ต้อง unique ทั่วโลก (ทุก AWS account รวมกัน) — ถ้าเจอ error BucketAlreadyExists ให้เปลี่ยนชื่อ เช่น ต่อท้ายด้วย account id หรือเลขสุ่ม (my-terraform-state-8823471)

bash
# สร้าง S3 bucket สำหรับเก็บ state (ทำครั้งเดียว)
aws s3 mb s3://my-terraform-state --region us-east-1
aws s3api put-bucket-versioning \
  --bucket my-terraform-state \
  --versioning-configuration Status=Enabled

# สร้าง DynamoDB table สำหรับ lock (ถ้าใช้ Terraform < 1.10 ที่ยังไม่มี S3 native locking)
aws dynamodb create-table \
  --table-name tf-locks \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST \
  --region us-east-1
# หมายเหตุ: Terraform 1.10+ / OpenTofu 1.10+ ใช้ use_lockfile = true แทน DynamoDB ได้เลย
hcl
# main.tf

terraform {
  required_version = ">= 1.6.0"   # pin version Terraform/OpenTofu — กัน state ถูก upgrade โดย dev ที่เครื่องเวอร์ชันใหม่ผิด

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true            # เข้ารหัส state ตอนเก็บ
    use_lockfile   = true            # ⭐ S3 native locking (Terraform 1.10+/OpenTofu 1.10+) — ไม่ต้องใช้ DynamoDB แล้ว
    # dynamodb_table = "tf-locks"    # วิธีเก่า (ยังใช้ได้) — ใช้ตาราง DynamoDB lock; ถ้า Terraform < 1.10 ต้องใช้ตัวนี้
  }
}

provider "aws" {
  region = "us-east-1"
}

# สร้าง resource — S3 bucket
resource "aws_s3_bucket" "uploads" {
  bucket = "my-app-uploads"

  tags = {
    Environment = "prod"
    ManagedBy   = "terraform"
  }
}

resource "aws_s3_bucket_versioning" "uploads" {
  bucket = aws_s3_bucket.uploads.id
  versioning_configuration {
    status = "Enabled"
  }
}

Commands

bash
terraform init              # ดาวน์โหลด provider (ทำครั้งแรก)
terraform plan              # ดูตัวอย่างว่าจะเปลี่ยนอะไรบ้าง (ยังไม่ลงมือ)
terraform apply             # ลงมือสร้างจริง (ถามยืนยันก่อน)
terraform apply -auto-approve   # โหมด CI (ไม่ถามยืนยัน) — ดูคำเตือนด้านล่าง
terraform destroy           # ลบทุกอย่างที่สร้างไว้
terraform show              # ดู state ปัจจุบัน
terraform output            # แสดงค่า output

⚠️ -auto-approve ใช้เฉพาะในสภาพแวดล้อม CI/CD ที่ผ่าน code review แล้วเท่านั้น — อย่าใช้บน production หรือตอนเรียนครั้งแรก เพราะถ้า plan ผิด resource จะถูกลบหรือสร้างใหม่ทันทีโดยไม่มีขั้นตอนยืนยัน

Workflow

text
1. Edit .tf file
2. terraform plan
3. Review changes
4. terraform apply
5. Commit to git

11. Terraform Variables

เพื่อไม่ให้ hardcode ค่าลงในโค้ด Terraform ใช้ "variable" — ทำให้ config เดียวกันใช้ได้หลาย environment (dev/staging/prod) โดยส่งค่าต่างกันตอน apply ยังใส่ validation กันค่าผิดได้ด้วย ตัวอย่างนี้แสดงการประกาศตัวแปร, validation และการส่งค่าผ่าน .tfvars:

hcl
# variables.tf
variable "region" {
  type    = string
  default = "us-east-1"
}

variable "environment" {
  type        = string
  description = "Environment (dev/staging/prod)"
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Must be dev, staging, or prod"
  }
}

variable "instance_count" {
  type    = number
  default = 2
}

# Use
provider "aws" {
  region = var.region
}

resource "aws_instance" "web" {
  count         = var.instance_count
  ami           = "ami-xxx"
  instance_type = "t3.micro"
  tags = {
    Environment = var.environment
  }
}
bash
# Pass values
terraform apply -var="environment=prod"
terraform apply -var-file="prod.tfvars"
hcl
# prod.tfvars
region         = "us-east-1"
environment    = "prod"
instance_count = 5

12. Terraform Outputs

หลัง apply เสร็จ เรามักอยากรู้ค่าที่ระบบสร้างให้ (เช่น IP ของ instance, ชื่อ bucket) — "output" คือวิธีดึงค่าเหล่านี้ออกมาแสดงหรือส่งต่อให้ module/เครื่องมืออื่น ค่าที่ลับ (password) ทำเครื่องหมาย sensitive เพื่อซ่อนจาก log ได้:

hcl
# outputs.tf
output "instance_ips" {
  value = aws_instance.web[*].public_ip
}

output "s3_bucket_name" {
  value     = aws_s3_bucket.uploads.id
  sensitive = false
}

output "db_password" {
  value     = aws_db_instance.main.password
  sensitive = true     # hide in console
}
bash
terraform output instance_ips
terraform output -json | jq

13. Modules (Reusable)

เมื่อ infrastructure ใหญ่ขึ้น การเขียนทุกอย่างในไฟล์เดียวจะรกและซ้ำ — "module" คือการจับ resource ที่ทำงานร่วมกัน (เช่น network, database) มัดเป็นชุดที่ reuse ได้ รับ input และคืน output ทำให้แยกความรับผิดชอบและ reuse ข้ามโปรเจกต์ได้เหมือนฟังก์ชัน:

text
project/
├── main.tf
├── variables.tf
├── modules/
│   ├── network/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── database/
│       ├── main.tf
│       └── ...
hcl
# main.tf
module "network" {
  source = "./modules/network"
  
  vpc_cidr    = "10.0.0.0/16"
  environment = var.environment
}

module "database" {
  source = "./modules/database"
  
  vpc_id      = module.network.vpc_id
  environment = var.environment
}

→ Reuse + parameterize


14. Real Example — Full Stack

มาดูตัวอย่างจริงที่ประกอบทุกอย่างเข้าด้วยกัน — Terraform ที่สร้าง stack ครบ: VPC, subnet (แยก public/private), NAT, security group, RDS Postgres ใน private subnet, ECS Fargate, ALB อ่านไล่ลงมาจะเห็นว่า infrastructure ทั้งก้อนถูกอธิบายเป็นโค้ดที่ apply ครั้งเดียวจบ และ destroy ทิ้งได้หมด

💡 CIDR notation (เช่น 10.0.0.0/16) = วิธีเขียน range ของ IP — เลขหลัง / บอกว่ามีกี่ bit คงที่ ที่เหลือใช้แจกได้ — /16 = 65,536 IP, /24 = 256 IP

hcl
# ---------- Network ----------
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = { Name = "my-app-vpc" }
}

# data source — อ่าน list ของ availability zones (AZ = data center ย่อยใน region)
data "aws_availability_zones" "available" {
  state = "available"
}

# Public subnet — สำหรับ ALB และ NAT Gateway
resource "aws_subnet" "public" {
  count                   = 2
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.${count.index}.0/24"
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true

  tags = { Name = "public-${count.index}" }
}

# Private subnet — สำหรับ RDS และ ECS task (ไม่มี public IP)
resource "aws_subnet" "private" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 10}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = { Name = "private-${count.index}" }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
}

# ⚠️ NAT Gateway = ตัวกลางที่ทำให้เครื่องใน private subnet ออกอินเทอร์เน็ตได้ (เช่น ดึง Docker image, OS update)
#   "NAT" = Network Address Translation — แปลงที่อยู่ระหว่าง private network กับ internet
#   ราคา ~$32/เดือนต่อตัว + ค่า data transfer — ตัว dev environment ใช้ 1 ตัวพอ, prod ค่อยใส่ตัวละ AZ
resource "aws_eip" "nat" {
  domain = "vpc"
}

resource "aws_nat_gateway" "main" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public[0].id
}

# (ตัด route table ออกเพื่อความสั้น — ในงานจริงต้องมี route ของ public ไป IGW, private ไป NAT)

# ---------- Database (Private subnet + Secrets Manager + random password) ----------
resource "aws_db_subnet_group" "main" {
  name       = "main"
  subnet_ids = aws_subnet.private[*].id   # ✅ RDS อยู่ใน private subnet (ไม่มี IP สาธารณะ)
}

# สุ่ม password ครั้งเดียว — เก็บใน Secrets Manager, ไม่ต้องใส่ตรง .tf หรือ tfvars
resource "random_password" "db" {
  length  = 32
  special = true
}

resource "aws_secretsmanager_secret" "db" {
  name = "myapp/db/credentials"
}

resource "aws_secretsmanager_secret_version" "db" {
  secret_id = aws_secretsmanager_secret.db.id
  secret_string = jsonencode({
    username = "appuser"
    password = random_password.db.result
    host     = aws_db_instance.postgres.address
    port     = aws_db_instance.postgres.port   # ✅ อ้างจาก resource จริง ไม่ hardcode — กัน secret ผิดถ้าเปลี่ยน engine
    dbname   = "myapp"
  })
}

resource "aws_db_instance" "postgres" {
  identifier        = "my-app-db"
  engine            = "postgres"
  engine_version    = "16"               # pin แค่ major (เลขเวอร์ชันรูปแบบ major.minor.patch — "pin major"
                                          # แปลว่าล็อกแค่เลขตัวแรก เช่น 16.x.y เปลี่ยนได้อัตโนมัติ แต่ 16→17 ต้องสั่งเอง)
                                          # → รับ minor patch อัตโนมัติ (security fix)
  # ⚠️ minor patch อัตโนมัติจะติดตั้งใน maintenance window ที่ตั้งไว้ (อาจทำให้ DB restart สั้น ๆ)
  #   งาน prod จริงควรกำหนด maintenance_window เอง (เช่นดึกช่วง traffic น้อย) ไม่ปล่อย default
  instance_class    = "db.t3.medium"
  allocated_storage = 20
  storage_encrypted = true

  db_name  = "myapp"
  username = "appuser"
  password = random_password.db.result   # ดึงจาก random_password (อยู่ใน state ที่เข้ารหัสบน S3)

  db_subnet_group_name   = aws_db_subnet_group.main.name
  vpc_security_group_ids = [aws_security_group.db.id]
  publicly_accessible    = false         # ✅ ปิด public access ทั้ง subnet และ flag

  backup_retention_period = 7
  multi_az                = var.environment == "prod"   # prod = multi-AZ, dev/staging = single AZ (ประหยัด)
  skip_final_snapshot     = var.environment != "prod"   # dev = ลบทิ้งได้ทันที, prod = บังคับให้ snapshot ก่อนทำลาย
  deletion_protection     = var.environment == "prod"

  tags = { Environment = var.environment }
}

# ---------- ECS task role + execution role ----------
# execution role = ใช้ตอน ECS pull image + เขียน log + ดึง secret
resource "aws_iam_role" "ecs_execution" {
  name               = "ecs-execution"
  assume_role_policy = data.aws_iam_policy_document.ecs_assume.json
}

data "aws_iam_policy_document" "ecs_assume" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy_attachment" "ecs_execution_default" {
  role       = aws_iam_role.ecs_execution.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

# ให้ execution role ดึง secret จาก Secrets Manager ได้
resource "aws_iam_role_policy" "ecs_execution_secrets" {
  role = aws_iam_role.ecs_execution.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = ["secretsmanager:GetSecretValue"]
      Resource = [aws_secretsmanager_secret.db.arn]
    }]
  })
}

# task role = สิทธิ์ของแอปเอง (เข้า S3, ฯลฯ) — แยกจาก execution role ตามหลัก least privilege
resource "aws_iam_role" "ecs_task" {
  name               = "ecs-task"
  assume_role_policy = data.aws_iam_policy_document.ecs_assume.json
}

# ---------- Compute (ECS Fargate) ----------
resource "aws_ecs_cluster" "main" {
  name = "my-app"
}

resource "aws_ecs_task_definition" "web" {
  family                   = "web"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = 256
  memory                   = 512
  execution_role_arn       = aws_iam_role.ecs_execution.arn  # ✅ ขาดไม่ได้
  task_role_arn            = aws_iam_role.ecs_task.arn       # ✅ ขาดไม่ได้

  runtime_platform {
    cpu_architecture        = "ARM64"   # ⭐ Graviton — ถูกกว่า ~20%
    operating_system_family = "LINUX"
  }

  container_definitions = jsonencode([{
    name  = "web"
    image = "ghcr.io/myorg/myapp:1.0"
    portMappings = [{ containerPort = 8080 }]

    # ✅ ใช้ secrets block ดึงจาก Secrets Manager (ไม่ใช่ environment plain text)
    secrets = [
      {
        name      = "DATABASE_URL"
        valueFrom = "${aws_secretsmanager_secret.db.arn}:url::"   # field "url" ภายใน secret
      }
    ]

    # environment สำหรับค่าที่ไม่ลับเท่านั้น
    environment = [
      { name = "APP_ENV", value = var.environment }
    ]
  }])
}

# ---------- Load Balancer (ใน public subnet) ----------
resource "aws_lb" "main" {
  name               = "my-app-lb"   # ≤ 32 ตัวอักษร
  load_balancer_type = "application"
  subnets            = aws_subnet.public[*].id   # ALB อยู่ public, app server อยู่ private — ✅ pattern ถูก
  security_groups    = [aws_security_group.lb.id]
}

resource "aws_lb_target_group" "web" {
  name        = "my-app-tg"
  port        = 8080
  protocol    = "HTTP"
  target_type = "ip"
  vpc_id      = aws_vpc.main.id

  health_check {
    path                = "/health"
    matcher             = "200"
    healthy_threshold   = 2
    unhealthy_threshold = 3
  }
}

# Listener — HTTPS (ต้องมี ACM cert)
# 💡 ACM (AWS Certificate Manager) = บริการออกใบรับรอง HTTPS ฟรีของ AWS
#    ต้องขอ + validate โดเมนก่อน (ทำผ่าน Console/CLI แยกต่างหาก ไม่ได้อยู่ในตัวอย่างนี้)
#    ถึงจะได้ ARN มาใส่ตัวแปร acm_certificate_arn ด้านล่างนี้
resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.main.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = var.acm_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web.arn
  }
}

# Listener — HTTP (port 80) → redirect ไป HTTPS ทันที (อย่าลืม — ไม่งั้น traffic ยังวิ่ง HTTP เปล่าได้)
resource "aws_lb_listener" "http_redirect" {
  load_balancer_arn = aws_lb.main.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

→ รัน terraform apply → infra ทั้งระบบสร้างเสร็จใน 5-10 นาที


15. Terraform Best Practices

State Management — สำคัญที่สุด ต้องเข้าใจ

💡 Solo dev / side project — ข้ามไป "Plan + Review" ส่วนล่างได้

ส่วน "Remote State + Locking + DynamoDB" ด้านล่างเป็น production concern สำหรับทีม — ถ้าคุณทำ project คนเดียว, terraform state อยู่ local (terraform.tfstate ในเครื่อง) ใช้ได้ปกติ — แค่ commit state file ลง git ห้ามทำ (มี secret) และ backup ไว้ที่ปลอดภัย. Remote state จำเป็นเมื่อ:

  • มีทีม 2+ คนทำ infra ร่วมกัน (ต้อง lock กัน apply ชน)
  • มี CI/CD ที่ apply อัตโนมัติ
  • production-grade เริ่มจริง

State คืออะไร

terraform.tfstate = JSON file ที่ Terraform จำว่า:

  • "resource ที่ฉันเคยสร้าง มี ID อะไรใน AWS"
  • "resource นี้มี attribute อะไรบ้าง"
json
{
  "resources": [{
    "type": "aws_s3_bucket",
    "name": "uploads",
    "instances": [{
      "attributes": {
        "id": "my-app-uploads",
        "arn": "arn:aws:s3:::my-app-uploads",
        "region": "us-east-1"
      }
    }]
  }]
}

ทำไม state สำคัญ

Terraform เป็น declarative (บอกปลายทางที่อยากได้ ไม่บอกขั้นตอน) — เราบอกว่า "อยากได้แบบนี้" → Terraform ดู state → คำนวณเองว่าต้องทำอะไรบ้างถึงจะไปถึงปลายทางนั้น

text
Desired state (your .tf files):    Current state (terraform.tfstate):
  S3 bucket "uploads" with             S3 bucket "uploads" exists
  versioning = enabled                 versioning = disabled

→ Terraform diff: ต้องเปิด versioning

ถ้าไม่มี state → Terraform คิดว่าไม่เคยสร้างอะไร → พยายาม create ทุกครั้ง → error "already exists"

Remote State + Locking — ทำไมต้องมี

Local state (terraform.tfstate ในเครื่อง) มีปัญหา:

text
❌ ทำงานคนเดียวเท่านั้น (ไม่มีใคร share state ด้วย)
❌ ถ้าเครื่องพัง → state หาย → สร้าง infra ใหม่ต้องเริ่มจากศูนย์ (Terraform จะคิดว่าทุกอย่างยังไม่เคยถูกสร้าง)
❌ ถ้า 2 คน apply พร้อมกัน → เกิด race condition (สองคนเขียน state พร้อมกันแล้วชนกัน ข้อมูลเพี้ยน) → infra พัง
❌ มี secrets ใน state (DB password, API key) → ไม่ควรอยู่ใน local เครื่องส่วนตัว

Remote state (S3 / Azure Blob / GCS) แก้ทุกข้อ:

hcl
# Backend = remote state (team collaboration = ทำงานเป็นทีมได้)
terraform {
  backend "s3" {
    bucket       = "my-tf-state"
    key          = "prod/terraform.tfstate"
    region       = "us-east-1"
    encrypt      = true            # เข้ารหัสตอนเก็บ (at-rest encryption)
    use_lockfile = true            # ⭐ state locking แบบ native ของ S3 (Terraform 1.10+/OpenTofu 1.10+)
    # dynamodb_table = "tf-locks"  # วิธีเก่า — ใช้ DynamoDB lock; Terraform < 1.10 ต้องใช้ตัวนี้
  }
}

💡 2024+ ข่าวดี: S3 รองรับ Conditional Writes แล้ว — Terraform 1.10+ / OpenTofu 1.10+ ใช้ S3 lock ตรง ๆ ได้ ไม่ต้องตั้ง DynamoDB table แยกอีก (ลดความซับซ้อน + ลดค่าใช้จ่าย) — แต่ถ้าใช้เวอร์ชันเก่ากว่าก็ยังต้องใช้ DynamoDB

state locking ทำงานยังไง (S3 lockfile หรือ DynamoDB ก็แนวคิดเดียวกัน — สมมติ Alice กับ Bob เป็น dev 2 คนในทีมเดียวกัน):

text
1. Alice รัน terraform apply
2. Terraform จองล็อก (เขียน lockfile บน S3 หรือ row ใน DynamoDB): "Alice กำลังใช้ state นี้อยู่"
3. Bob รัน terraform apply พร้อมกัน
   → Terraform เจอ lock → ปฏิเสธ: "Error acquiring the state lock"
4. Alice เสร็จ → ลบ lock → Bob ทำต่อได้

Best Practices

  • ⚠️ อย่า commit terraform.tfstate — มี secrets (DB password, private keys)
  • ⚠️ อย่า edit terraform.tfstate ด้วยมือ — corruption → infra ไม่ตรง
  • ใช้ remote backend + locking ตั้งแต่วันแรก — S3 native locking (use_lockfile, Terraform/OpenTofu 1.10+) หรือ S3 + DynamoDB สำหรับเวอร์ชันเก่ากว่า (ทั้งคู่ฟรีในระดับ free tier)
  • Encrypt state (S3 server-side encryption + KMS)
  • Backup state (S3 versioning + cross-region replication)
  • Separate state per environment (dev/terraform.tfstate, prod/terraform.tfstate)

Workspaces vs Directory-per-environment (ตั้งค่าหลาย env)

bash
# Workspaces — เร็วแต่ใช้ state file เดียวที่ key ต่างกัน
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod

terraform workspace select prod
terraform apply

⚠️ คำแนะนำปี 2026: หลีกเลี่ยง workspaces สำหรับ multi-env บน prod — เพราะใช้ state, backend, provider, version เดียวกัน → เผลอ apply ผิด env ได้ง่าย, dev/prod ต้อง pin version ตรงกัน, ไม่มี isolation ที่แท้จริง. Workspaces เหมาะกับ "temporary scratch env" (เช่น feature branch ทดลอง) เท่านั้น

ทางที่ดีกว่า: directory-per-environment (หรือใช้ state file แยกกัน):

text
environments/
├── dev/
│   ├── main.tf            # อาจ import module จาก ../../modules
│   └── terraform.tfvars
├── staging/
└── prod/

→ แต่ละ env มี state, backend, provider version แยกเด็ดขาด → ผิดที่ dev ไม่กระทบ prod

Locking — ป้องกัน apply ชนกัน

ใช้ S3 native lockfile (Terraform 1.10+) หรือตาราง DynamoDB (วิธีเก่า) ป้องกัน 2 คนรัน terraform apply พร้อมกัน

Plan + Review

bash
terraform plan -out=tfplan
# review ดูว่าจะเปลี่ยนอะไรบ้าง
terraform apply tfplan

ใน Pull Request — แสดงผลของ terraform plan ใน comment เพื่อให้คนรีวิวเห็น diff ของ infra ก่อน merge


16. Terraform Patterns

เมื่อใช้ Terraform คล่องแล้ว จะเจอ pattern ที่ช่วยให้โค้ดยืดหยุ่นขึ้น — สร้าง resource แบบมีเงื่อนไข (count), วนสร้างหลายอันจาก list (for_each) และอ่านข้อมูล resource ที่มีอยู่แล้วโดยไม่สร้างใหม่ (data source) สาม pattern นี้ใช้บ่อยมากในงานจริง:

Conditional resource

hcl
resource "aws_instance" "monitoring" {
  count = var.environment == "prod" ? 1 : 0
  # ...
}

For each

hcl
variable "users" {
  default = ["alice", "bob", "carol"]
}

resource "aws_iam_user" "user" {
  for_each = toset(var.users)
  name     = each.key
}

Data source (อ่าน resource ที่มีอยู่แล้วโดยไม่สร้างใหม่)

hcl
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]   # เลข AWS account ID ของ Canonical (บริษัทเจ้าของ Ubuntu) — ใส่ไว้กรอง
                                    # ไม่ให้ดึง AMI ปลอมจาก account อื่นที่ตั้งชื่อคล้ายกัน

  filter {
    name   = "name"
    # ปี 2026 ใช้ Ubuntu 24.04 LTS (noble) — รองรับยาวถึง 2029
    # สำหรับ ARM Graviton ใช้ ssd-arm64 แทน amd64
    values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
  }
}

resource "aws_instance" "web" {
  ami = data.aws_ami.ubuntu.id
}

17. Alternatives to Terraform

Toolจุดเด่นเลือกเมื่อ
OpenTofuopen source แท้ (MPL), เป็น fork ของ Terraformปี 2026 = default ของ project ใหม่
Terraformนิยมสุด, ecosystem ใหญ่ที่สุดมี HashiCorp Cloud หรือ policy องค์กรกำหนด
Pulumiเขียนด้วย Python/TS/Go ได้จริงทีมเป็น dev ที่ไม่ชอบ HCL
AWS CDKใช้ได้บน AWS เท่านั้น, เขียนด้วยภาษาโปรแกรมจริงAll-in กับ AWS, อยากใช้ภาษาเดียวกับ app
CDK for Terraform (CDKTF)เขียน CDK style แต่ output เป็น Terraform — ใช้ provider Terraform ทั้งหมดได้ชอบ CDK แต่ไม่อยาก lock AWS
CloudFormationYAML/JSON ของ AWS เองenterprise ที่ไม่อยากใช้ 3rd party
Crossplaneจัดการ infra ผ่าน K8s CRDทีมใช้ K8s เป็น control plane
Pkl (Apple)typed config language ใหม่ของ Appleใช้ generate config หลายรูปแบบ
Ansibleconfiguration managementconfigure ของข้างใน VM (ไม่ใช่สร้างตัวเครื่อง)

มือใหม่ปี 2026: OpenTofu (หรือ Terraform — syntax เหมือนกัน)


18. Configuration Management

Terraform สร้าง "ตัวเครื่อง" (VM, DB) ให้ แต่ใครจะติดตั้งซอฟต์แวร์และตั้งค่า "ข้างใน" เครื่อง? นั่นคือหน้าที่ของ configuration management (Ansible/Chef/Puppet) — แม้ปี 2026 จะใช้น้อยลงเพราะ container + immutable infrastructure เข้ามาแทนในงาน cloud-native, แต่ Ansible ยังเป็นมาตรฐานสำหรับงาน bare-metal, edge, network device, OS hardening และ legacy server ที่ container ลงไม่ได้:

text
Terraform: provision infrastructure (VM, DB)
Ansible / Chef / Puppet: configure inside (install packages, config files)
yaml
# Ansible playbook
- hosts: webservers
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
    
    - name: Copy config
      copy:
        src: nginx.conf
        dest: /etc/nginx/nginx.conf
    
    - name: Start nginx
      service:
        name: nginx
        state: started

ปี 2026 — ในงาน cloud-native ใช้น้อยลงเพราะแทนด้วย container + immutable infrastructure (สร้างเครื่องใหม่ทุกครั้งแทนการแก้เครื่องเดิม) แต่ยังเป็นเครื่องมือหลักสำหรับ bare-metal, network device, และระบบ legacy


19. Cloud Architecture Patterns

มี "แบบแปลน" สถาปัตยกรรมมาตรฐานที่ใช้กันบ่อยบน cloud — 3-tier แบบคลาสสิก, serverless (ไม่มีเซิร์ฟเวอร์ให้ดูแล), microservices บน Kubernetes และ multi-region สำหรับความทนทานสูง รู้จักแต่ละแบบแล้วจะออกแบบระบบให้เหมาะกับความต้องการได้:

A. 3-Tier (Classic)

B. Serverless

✅ ไม่ต้องจัดการ server ✅ scale ลงถึง 0 ได้ (ไม่ใช้ก็ไม่จ่าย) ✅ จ่ายต่อ request

C. Microservices (K8s)

D. Multi-Region (HA = High Availability)


20. Cost Optimization

บิล cloud พุ่งโดยไม่รู้ตัวเป็นเรื่องที่เกิดบ่อยมาก — การคุมค่าใช้จ่ายจึงเป็นทักษะ DevOps สำคัญ หัวข้อนี้รวมทั้งวิธีประหยัด (right-size, reserved/spot, ลบของไม่ใช้), เครื่องมือดู cost และ "กับดักค่าใช้จ่าย" ที่คนลืมบ่อย (เช่น NAT Gateway ที่เปิดทิ้งไว้):

Tips ทั่วไป

  • Right-size — เลือกขนาดเครื่องให้พอดี ไม่ใช่จัด m5.xlarge ทั้งที่ traffic น้อย
  • Reserved Instance / Savings Plans — จ่ายล่วงหน้า 1-3 ปี ลดได้ 30-70% (เหมาะ workload คงที่)
  • Spot instances — ลดสูงสุด 70-90% แต่ AWS เรียกคืนได้ทุกเมื่อ (เหมาะ batch job ที่ทนถูกหยุดได้)
  • Auto-scale ลง เมื่อไม่ใช้ (เช่นกลางคืน, วันหยุด)
  • ลบของที่ไม่ใช้ — snapshot เก่า, ดิสก์ที่ไม่ผูกกับเครื่อง, AMI เก่า
  • CloudFront ช่วยลด traffic จาก EC2 (cache + ราคาต่อ GB ถูกกว่า)
  • S3 Lifecycle — ตั้งให้ย้ายไฟล์เก่าไปชั้น archive (Glacier) อัตโนมัติ
  • Billing alerts — ตั้งเตือนที่ $10, $100, $1000
  • ใช้ free tier สำหรับ dev / test
  • ARM Graviton — เปลี่ยน instance / Lambda มาเป็น ARM ลดได้ ~20-40%

เครื่องมือ

  • AWS Cost Explorer — dashboard ดู cost ในตัว
  • Cloud Custodian — เครื่องมือเปิด rule clean up resource อัตโนมัติ
  • Infracost — แสดงประมาณการ cost ใน Terraform PR ก่อน apply
  • CloudHealth / Spot.io — ระดับ enterprise

กับดักค่าใช้จ่ายที่เจอบ่อย

  • NAT Gateway เปิดทิ้งไว้ (~$32/เดือนต่อตัว + ค่า data transfer)
    • 💡 NAT Gateway = อุปกรณ์ที่ทำให้ VM ใน private subnet ออก internet ได้ (เช่น ดึง Docker image, OS update) — ปกติเปิดอย่างน้อย 1 ตัวต่อ environment, prod ใส่ตัวละ AZ; dev/staging ใช้ตัวเดียวพอ; ถ้าไม่ต้องการให้ออก internet เลย ปิดทิ้งได้
  • ❌ EBS snapshot ค้างเยอะ (เก็บไว้ปีกว่าโดยลืม)
  • ❌ Elastic IP ที่ไม่ได้ผูกกับเครื่อง (AWS เก็บ $3.6/เดือนต่ออันสำหรับ EIP ที่ idle)
  • ❌ Data transfer ข้าม region (แพง — ปกติ $0.02/GB)
  • ❌ CloudWatch logs เก็บตลอดชาติ (ตั้ง retention 7-30 วันสำหรับ log ทั่วไป)
  • ❌ ลืม resource ตอน test (ตั้ง tag ทุกอย่าง เช่น env=test, owner=alice แล้วตามล้างตาม tag ได้)

21. Security Basics

ความปลอดภัยบน cloud วางอยู่บนเสาหลักไม่กี่ต้น — identity (IAM: ใครทำอะไรได้), network (VPC/security group/firewall), encryption (เข้ารหัสทั้งตอนส่งและตอนเก็บ) และ compliance หัวข้อนี้สรุป best practice ของแต่ละด้านที่ควรทำตั้งแต่วันแรก:

Identity (IAM) — ใครทำอะไรได้

text
✅ ใช้ IAM role (ผูกกับ EC2/ECS/Lambda) แทน static access key
✅ Least privilege — ให้สิทธิ์เท่าที่จำเป็นเท่านั้น
✅ เปิด MFA (Multi-Factor Authentication = ยืนยันตัวตน 2 ชั้น)
✅ หมุน credential สม่ำเสมอ (rotate)
✅ เปิด audit log (CloudTrail) เพื่อย้อนดูใครทำอะไร
✅ ห้ามใช้ root account ทำงานประจำ — ใช้แค่ตอนตั้งบัญชีครั้งแรก
hcl
# IAM Role สำหรับ EC2 — เครื่องเอา role นี้ไปสวมเพื่อเข้า S3 โดยไม่ต้องมี access key
resource "aws_iam_role" "app" {
  name = "app-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action    = "sts:AssumeRole"
      Principal = { Service = "ec2.amazonaws.com" }
      Effect    = "Allow"
    }]
  })
}

resource "aws_iam_role_policy" "app_s3" {
  role = aws_iam_role.app.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action   = ["s3:GetObject", "s3:PutObject"]
      Effect   = "Allow"
      Resource = "${aws_s3_bucket.uploads.arn}/*"
      # ✅ บังคับให้เรียกผ่าน HTTPS เท่านั้น (best practice ปี 2026)
      Condition = {
        Bool = {
          "aws:SecureTransport" = "true"
        }
      }
    }]
  })
}

Network

  • VPC แบ่ง public + private subnet (ของสำคัญเช่น DB อยู่ private เท่านั้น)
  • Security Group = firewall แบบ stateful (จำ connection ที่ออกไป → packet ตอบกลับเข้าเองได้)
  • WAF (Web Application Firewall) = firewall ระดับ HTTP สำหรับ endpoint สาธารณะ — กัน SQL injection / XSS
  • VPN (Virtual Private Network) / PrivateLink สำหรับเชื่อม network ข้าม account หรือ on-prem โดยไม่ผ่าน internet

Encryption (เข้ารหัส)

  • TLS in transit (HTTPS) — เข้ารหัสตอนส่งข้าม network
  • ✅ Encryption at rest (เข้ารหัสตอนเก็บ):
    • S3 = เข้ารหัสโดย default ตั้งแต่มกราคม 2023 (server-side encryption)
    • EBS = ต้องไปกด "EBS encryption by default" ที่ระดับ region — ถ้าไม่เปิด, volume ใหม่จะไม่เข้ารหัสจนกว่าจะระบุเอง
    • RDS = ต้องเปิด storage_encrypted = true ตอนสร้างเท่านั้น — เปิดทีหลังไม่ได้ ต้อง restore จาก snapshot ที่เข้ารหัสไปสร้างใหม่
  • ✅ KMS (Key Management Service) เก็บ key + ตั้งให้หมุนอัตโนมัติ
  • ✅ Secrets Manager / Parameter Store / Vault — ไม่ฝัง secret ใน code หรือ env plain text
  • External Secrets Operator (ESO) — มาตรฐาน de-facto ปี 2026 สำหรับ sync secret จาก cloud (Secrets Manager / Vault) มาเป็น K8s Secret ให้ pod ใช้
  • SOPS (Mozilla) — เข้ารหัสไฟล์ YAML/JSON ของ secret ใน Git ได้

2026 Baselines (AWS) — เปิดทุกอันได้เลย

  • GuardDuty = ตรวจจับภัยอัตโนมัติจาก log (เปิดเป็น account-level)
  • Security Hub = dashboard รวม security finding จากทุก service
  • IAM Access Analyzer = สแกน policy หา resource ที่เปิดสิทธิ์เกิน
  • AWS Config = ตรวจ drift ของ config (เช่น S3 bucket เผลอเปิด public)
  • AWS Inspector = สแกน vulnerability ของ EC2/ECR/Lambda

Compliance

  • SOC 2, ISO 27001, HIPAA, GDPR (มาตรฐานที่ระบบ enterprise มักต้องผ่าน)
  • เช็คเอกสารของ cloud provider ว่ารองรับ compliance ไหนบ้างในแต่ละ region

22. Edge + CDN

ยิ่งเซิร์ฟเวอร์อยู่ไกล user ยิ่งช้า — CDN แก้ด้วยการ cache เนื้อหา static ไว้ที่ "edge" ใกล้ user ทั่วโลก ทำให้โหลดเร็วระดับ ~10ms และยังลดภาระเซิร์ฟเวอร์ต้นทาง ปัจจุบันยังรันโค้ดเล็ก ๆ ที่ edge ได้ด้วย (edge compute) สำหรับงานอย่าง auth หรือ A/B test:

CDN = cache เนื้อหา static ไว้ใกล้ผู้ใช้:

text
User (Bangkok) → CloudFront Bangkok edge → S3 (us-east-1)
                 (cache ไฟล์ HTML/JS/CSS/รูป ไว้แล้ว)

→ เว็บ static = latency ~10ms จากที่ไหนก็ได้ในโลก

Edge Compute

text
Cloudflare Workers, AWS Lambda@Edge, Vercel Edge:
- รันโค้ดที่ edge ของ CDN (ใกล้ผู้ใช้)
- ใช้สำหรับ: A/B test, ตรวจ auth, ดู geolocation, logic เบา ๆ
- cold start เร็ว — แต่ "เร็วแค่ไหน" ขึ้นกับ platform:
   • Cloudflare Workers, Vercel Edge = V8 isolate, cold start ~5ms
   • AWS Lambda@Edge = ใช้ Lambda จริง ๆ ใต้ฐาน, cold start 100-500ms (ไม่ใช่ edge ที่เร็วจริง)

23. Multi-Cloud + Hybrid

🚀 โซนขั้นสูง — ข้ามได้ Multi-cloud / hybrid เป็นเรื่องขององค์กรใหญ่ที่มีข้อจำกัดพิเศษ มือใหม่และโปรเจกต์ส่วนใหญ่ ควรใช้ cloud เจ้าเดียว ให้คล่องก่อน อ่านหัวข้อนี้แค่พอรู้ว่ามีอยู่และทำไมส่วนใหญ่ถึงไม่ทำก็พอ

ใช้ cloud หลายเจ้าพร้อมกัน (multi-cloud) หรือผสม on-premise กับ cloud (hybrid) ฟังดูดีแต่แลกมากับความซับซ้อนที่ทวีคูณ — หัวข้อนี้ชั่งน้ำหนักว่าเมื่อไหร่ควรทำจริง ๆ (ส่วนใหญ่คำตอบคือ "ใช้ cloud เจ้าเดียว + เตรียมแผนย้ายไว้" โดยใช้ Terraform เป็นชั้นกลางที่ช่วยให้ย้ายง่ายขึ้น):

text
ทำไมจะ multi-cloud:
- ไม่อยาก vendor lock-in (ผูกตัวกับเจ้าเดียว)
- เลือก service ที่เก่งที่สุดของแต่ละเจ้า (best-of-breed)
- ข้อบังคับเรื่อง compliance ในแต่ละประเทศ/region

ทำไมส่วนใหญ่ ไม่ ควรทำ:
- ความซับซ้อนเพิ่มเป็น N เท่า (ต้องเรียนรู้ทุกเจ้า)
- ค่าใช้จ่ายซ้ำซ้อน (ทำ network, monitoring, IAM 2 ระบบ)
- ทีมต้องเรียนแต่ละเจ้า

→ บริษัทส่วนใหญ่ = ใช้ cloud เจ้าเดียว + มีแผนย้าย (เขียน infra ผ่าน Terraform เพื่อให้ย้ายง่ายในวันที่จำเป็น)

Hybrid (on-prem + cloud)

text
ระบบเดิม on-prem → เชื่อมผ่าน AWS Direct Connect / VPN → cloud

เจอบ่อยในองค์กรใหญ่ที่กำลังทยอยย้ายขึ้น cloud (migration)


24. Common Pitfalls

รวมความผิดพลาดที่ทำให้ระบบ cloud ทั้งเปลือง ทั้งเสี่ยง และดูแลยาก — ส่วนใหญ่มาจากการทำมือใน console, ไม่ tag resource, hardcode secret หรือเผลอเปิด S3 เป็น public ตารางนี้จับคู่ปัญหากับวิธีแก้ที่ควรทำตั้งแต่ต้น:

ปัญหา (Pitfall)วิธีแก้
คลิกสร้างใน console (click-ops)ใช้ IaC (Terraform) แทน
แก้มือทำให้ infra เพี้ยน (drift)บังคับผ่าน CI/CD pipeline เท่านั้น
ไม่ติด tagtag ทุก resource (cost center, env, owner)
Hardcode secret ในโค้ดใช้ Secrets Manager / Vault
IAM user admin คนเดียวทำทุกอย่างแยก role ต่อ service ตามหลัก least privilege
S3 bucket เปิด publicprivate + ใช้ presigned URL ดึงไฟล์
ลืมลบ dev envตั้ง scheduled cleanup (ลบทุกคืน/วันหยุด)
ไม่ดู costตั้ง billing alert + เปิด Cost Explorer
ติด vendor lock-in ลึกเขียน infra ผ่าน Terraform เป็นชั้นกลาง

25. Cloud Cost — Real World

ตัวเลขจริงช่วยให้เห็นภาพดีกว่าทฤษฎี — หัวข้อนี้ยกตัวอย่างค่าใช้จ่ายต่อเดือนของระบบจริงสามขนาด: SaaS เล็ก (~$200), SaaS กลาง (~$1,400) และโปรเจกต์ที่อยู่บน free tier (~$1) ให้พอเดาได้ว่าระบบของคุณจะอยู่ราคาประมาณไหน:

SaaS เล็ก (~10k users)

text
EC2 (2x t3.medium):           $60     # เครื่องรันแอป
RDS (db.t3.medium):           $80     # database
S3 + CloudFront:              $20     # storage + CDN
ALB (Application LB):         $20     # load balancer
CloudWatch + logs:            $20     # monitoring
EBS (ดิสก์ผูก EC2):           $10     # มักลืมนับ
Data transfer ออก internet:   $10-30  # ขึ้นกับ traffic — มักโตเร็วสุด
รวม:                         ~$220-250/เดือน

⚠️ มือใหม่มักประมาณค่าใช้จ่ายต่ำกว่าจริง เพราะลืมนับ EBS, CloudWatch detailed metrics, data egress (ค่า traffic ออก internet ที่มักโตเร็วที่สุดและเก็บ $0.09/GB)

SaaS กลาง (~100k users)

text
EKS + 10 nodes:        $500    # Kubernetes cluster
RDS (Multi-AZ):        $300    # database สำรอง 2 ตัว
ElastiCache (Redis):   $100    # cache
S3 + CDN:              $200
อื่น ๆ:                $300    # monitoring, log, NAT, secret, etc.
รวม:                  ~$1,400/เดือน

โปรเจกต์ Free Tier

text
EC2 t3.micro (free 1 ปี):     $0
S3 5GB free:                  $0
Route 53 (DNS, ~$1):          $1
รวม:                          ~$1/เดือน

26. Choosing Cloud

สรุปสุดท้าย — เลือก cloud เจ้าไหนดี? คำตอบขึ้นกับบริบทของคุณ ตารางตัดสินใจแบบเร็วนี้แมตช์สถานการณ์ที่พบบ่อยกับตัวเลือกที่เหมาะ (เริ่มใหม่, สาย Microsoft, เน้น data/ML, อยากถูกและง่าย ฯลฯ):

text
เริ่มจากศูนย์ ไม่มี constraint?     → AWS (เอกสารเยอะที่สุด)
ทีมใช้เทคโนโลยี Microsoft เป็นหลัก?  → Azure
เน้น data / ML?                      → GCP (BigQuery, Vertex AI)
อยากถูก + เรียบง่าย?                  → Hetzner, DigitalOcean
มีแต่ frontend?                       → Vercel, Netlify, Cloudflare
หาตัวแทน Heroku?                      → Render, Railway, Fly.io

27. Checkpoint

ลงมือทำเองเพื่อให้ความรู้ติดตัว — แบบฝึกหัดต่อไปนี้ไล่จากตั้ง free tier + billing alert, สร้าง resource แรกด้วย Terraform, deploy full stack, audit ค่าใช้จ่าย ไปจนถึงทำ multi-environment ครบ 5 ข้อแล้วจะใช้ cloud + IaC ได้จริง:

🛠️ Checkpoint 6.1 — เปิด Free Tier

  • สร้าง AWS / GCP account
  • ตั้ง billing alert ที่ $10
  • Deploy hello-world บน EC2 / Compute Engine

🛠️ Checkpoint 6.2 — Terraform Resource แรก

  • ติดตั้ง Terraform (หรือ OpenTofu)
  • สร้าง S3 bucket ผ่าน Terraform
  • เพิ่ม versioning + encryption
  • รัน terraform plan แล้ว terraform apply

🛠️ Checkpoint 6.3 — Full Stack Deploy แอป Spring Boot + React:

  • VPC + subnets (public/private) ผ่าน Terraform
  • RDS PostgreSQL ใน private subnet + รหัสจาก Secrets Manager
  • ECS Fargate + execution role + task role
  • ALB ที่มี HTTPS listener
  • S3 + CloudFront สำหรับ static frontend

🛠️ Checkpoint 6.4 — Cost Audit

  • เปิด AWS Cost Explorer
  • หา 3 รายการที่กิน cost สูงสุด
  • ทำ 1 optimization (right-size / reserved / spot / Graviton)

🛠️ Checkpoint 6.5 — Multi-env

  • เขียน Terraform module ของแอป
  • ทำ environment dev / staging / prod (directory-per-env)
  • ตั้งขนาดต่างกันในแต่ละ env (เช่น dev = t4g.micro, prod = t4g.medium)

28. สรุปบท

ทบทวนสาระทั้งบท — ตั้งแต่ทำไมต้อง cloud, ผู้ให้บริการเจ้าหลัก, service model, การเลือก compute, Infrastructure as Code ด้วย Terraform ไปจนถึงเรื่อง cost และ security เช็กลิสต์นี้คือแก่นที่ควรเข้าใจก่อนนำไปใช้จริง:

✅ Cloud = ยืดหดได้ (elastic), มี managed service, จ่ายตามใช้จริง ✅ AWS (นิยมสุด), GCP (data/ML), Azure (enterprise), DigitalOcean (เรียบง่าย) ✅ Service models: IaaS → PaaS → SaaS → Function (ดูแลมาก → ดูแลน้อย) ✅ เลือก compute: Lambda → Cloud Run / ECS → EKS / GKE (ตามความซับซ้อน) ✅ Heroku/Render/Railway = ทางเลือกง่ายสุดสำหรับโปรเจกต์เล็ก ✅ IaC (Terraform/OpenTofu) = infrastructure เป็นโค้ด — มี version, reproducible ✅ Terraform: provider, resource, variable, output, module ✅ Remote state + lock (S3 native lockfile ตั้งแต่ Terraform 1.10+, หรือ DynamoDB ในเวอร์ชันเก่า) ✅ Workflow: plan → review → apply ✅ Cost optimization: right-size, Reserved/Savings, spot, Graviton, billing alert, tag ✅ Security: ใช้ IAM role (ไม่ใช้ static key), least privilege, encryption, Secrets Manager, MFA, เปิด GuardDuty/Security Hub ✅ เริ่มจาก cloud เจ้าเดียว — ใช้ Terraform เป็นชั้นกลาง เผื่อย้ายในอนาคต


← บทที่ 5 | บทที่ 7 → Monitoring + Observability